Files

18 KiB
Raw Permalink Blame History

Selective SRS Installer – Review Draft 0.9

Stand: 18.10.2026. Target: Debian 13, PostgreSQL/PostfixAdmin; reference implementation mx.warenform.de.

This directory is a review bundle, not a production-tested release. Copy its templates into the corresponding location of the shared mailsystem Git repository (files/srs/templates/) before the installer can be run in its normal script directory. The four Python programs and helpers/srs-common.sh in the bundle are unmodified reference snapshots from the user's repository/uploads.

Files

  • install-update-srs.sh — draft with read-only --check and an unapproved --install implementation.
  • files/srs/templates/delivery-main.cf.in — reference delivery main.cf with selected Postfix parameters templated.
  • files/srs/templates/delivery-master.cf — reference delivery master.cf, unchanged.
  • files/srs/templates/transport.in — reference transport file with SRS domain placeholder.
  • files/srs/templates/postsrsd.conf.in — reference PostSRSd configuration with SRS domain placeholder.
  • files/srs/templates/*.service — reference systemd units, unchanged.

Conventions

  • The product Postfix instance /etc/postfix/main.cf and /etc/postfix/master.cf is never modified by this draft. Separate activate-srs.sh/deactivate-srs.sh do that.
  • Initial PRE-SRS state is derived once; existing state is preserved.
  • PostSRSd CMake 2.4.1 options match the working reference.
  • The Debian unit postfix@srs-delivery.service decodes its %I instance token srs-delivery as srs/delivery, yielding /etc/postfix-srs/delivery. No special directory symlink is necessary.
  • Three reference Python programs have their single srs.warenform.de string replaced by the locally configured _SRS_DOMAIN when installed, without modifying the Git sources.
  • In this initial draft, active-service updates to another PostSRSd version are refused; coordinated restarts, full rollback of queue initialisation, semantic rendering parity tests and cross-host integration tests remain to be implemented.
  • No attempt is made to install Debian build dependencies. On a.mx.oopen.de, cmake was found missing during inventory.

Safe first check

Run only --check after placing the script and templates in the repository. This path does not run init_srs_runtime(), create a lock, install files, build anything or touch services.

Do not run --install on any production mail server yet. Syntax validation alone is insufficient; the installation stage and its rollback require offline/staging testing and explicit approval.

Findings after systemd template inspection (18 October 2026)

  • postfix@srs-delivery.service uses Environment=MAIL_CONFIG=/etc/postfix-%I. The unescaped %I for instance srs-delivery is srs/delivery; thus the intended configuration path is /etc/postfix-srs/delivery. There is NO /etc/postfix-srs-delivery symlink on the working reference server and none is needed.
  • The SRS private configuration directory is now created with root:root mode 0700; an already-existing directory must match these permissions.
  • Snapshotting existing files records a rollback entry only AFTER the backup is successful, and installation to a symlinked destination is rejected.
  • Remaining blockers: package provisioning (CMake missing on a.mx), semantic config parity validation, coordinated active-version upgrades, complete rollback of newly created directories/queue initialization and failure-injection testing. --install is NOT approved.

Changes in draft 0.3

  • The --check report correctly distinguishes an available Debian postfix@.service template from an installed, ready SRS delivery instance.
  • Rollback removes a freshly installed PostSRSd version prefix only after the previous stable link has been restored and only if it is not selected.
  • An initial installation aborts if SRS configuration files already exist without a stable PostSRSd symlink, rather than overwriting an ambiguous partial installation.

Still NOT production ready: CMake package provisioning, comprehensive rollback of new directories and Postfix queue creation, service upgrade orchestration, DNS checks, and integration tests are not yet implemented.

Changes in draft 0.4

  • Both --check and --install first ask interactively for the SRS domain, before inspecting prerequisites. For the target a.mx.oopen.de, enter srs.oopen.de. This value is not hardcoded into the shared Git source.

  • If a local conf/srs.conf contains a straightforward domain assignment, that domain is offered as the default. The hint is read as plain text, not sourced.

  • --check displays the selected domain and detects an evident conflict with a previously configured domain; it never writes conf/srs.conf.

  • First --install now stages and installs conf/srs.conf (root:root, 0644) after user confirmation. Existing configuration is validated using load_srs_config() and must match the selected domain; automatic domain migration is refused.

  • Add conf/srs.conf to the Git repository's .gitignore; only conf/srs.conf.sample belongs in Git.

  • Still a REVIEW DRAFT, NOT approved for production --install. Other known blockers from 0.3 remain.

  • After domain selection, --check prints informational DNS TXT/MX/A/AAAA lookups when dig is available. These outputs are not a completed SPF/MX validation.

Changes in review draft 0.5 (18 October 2026)

  • Adds helpers/srs-dns-check.py. Both modes ask for the domain first. --check uses it without any writes and reports readiness; --install stops before changes if the public-DNS preflight fails.
  • The DNS helper resolves delegation via public DNS resolvers, then directly queries every discovered authoritative nameserver. This bypasses the local /etc/hosts override where a.mx.oopen.de resolves to 127.0.1.1 via systemd-resolved on this machine.
  • The agreed strict single-host DNS profile is checked: precisely one MX pointing to Postfix myhostname, exactly one SPF record equal to v=spf1 mx -all, and public MX-target A/AAAA answers containing the explicit smtp_bind_address and smtp_bind_address6 values. For a.mx.oopen.de, that means MX a.mx.oopen.de, IPv4 95.217.204.247, IPv6 2a01:4f9:4a:47e5::247. No server domain or IP has been hardcoded into the installer or helper.
  • This is not a complete SPF evaluator, an SMTP connectivity test, or a guarantee of bounce routing through arbitrary topologies. DNS setups using other valid SPF expressions, shared SRS domains, multiple MX hosts or hosts without explicit IPv4/IPv6 bind addresses require a considered implementation extension, rather than being silently accepted.
  • Reorders --install so it performs root/command/source/DNS and installation-state preflight before asking the operator to approve preparation and before acquiring the lock or writing files. --check stays read-only. It checks for dig as a required installation dependency.
  • Add the new helper to the common Git repository at helpers/srs-dns-check.py alongside the updated install-update-srs.sh. Keep conf/srs.conf ignored in Git.
  • Tests run for this draft: Bash syntax check, Python syntax compilation, three isolated DNS-positive/negative cases, and an end-to-end mocked --check with two nameservers. No productive SRS installation, delivery, failure-injection or rollback testing has been performed.

Known blockers remain: CMake and CTest absent on a.mx.oopen.de; Postfix delivery config semantics and safe rollback/active upgrades need additional testing. Do not run --install in production yet.

Changes in review draft 0.6 (18 October 2026)

  • The operator's git status --short --untracked-files=all listed precisely the eight expected new files. bash -n of the installer and compile() of the DNS helper passed on a.mx.oopen.de. conf/srs.conf is already ignored by .gitignore (conf/*.conf). No Git commit has been performed.
  • Preflight now rejects symlinked/non-directory SRS destination paths and a nonprivate existing /etc/postsrsd-srs directory BEFORE the build and filesystem-deployment confirmation.
  • Newly created configuration directories are tracked separately and removed on failed installation only if empty (after tracked file rollback).
  • Newly created /var/spool/postfix-srs-delivery and /var/lib/postfix-srs-delivery roots are remembered before postfix -c ... check. Rollback tries only rmdir; it never recursively deletes Postfix runtime data. If Postfix created a nonempty hierarchy, that hierarchy remains for manual inspection. Thus rollback is not fully automatic for initialized Postfix queue/data.
  • Unexpected process EXIT after the file-deployment phase begins is routed through tracked-file rollback (normal success and explicit rollback disarm this trap). This does not guarantee recovery from SIGKILL, power loss, process crash without shell handling, or full operational restore.
  • No changes to the six reference templates, the four reference SRS Python scripts, helpers/srs-common.sh, or the existing activation/deactivation tools.

Release status: NOT approved for --install. Active upgrades with running SRS services are deliberately rejected and still need a separate safe restart/rollback design. CMake/CTest provisioning, live first-install, Postfix config semantic comparison, and injected-failure/queue behavior tests remain open. Do not commit this draft as a production-ready release.

Changes in review draft 0.7 (18 October 2026)

  • apt-get -s install cmake on a.mx.oopen.de proposed exactly four new Debian 13 packages: cmake, cmake-data, libjsoncpp26, librhash1; zero upgrades and removals. No backports packages were proposed.
  • --check still never changes packages or SRS state; it reports missing CMake/CTest and prints an apt-get -s --no-install-recommends simulation when CMake is missing.
  • --install first asks for the SRS domain, then performs read-only preflight and simulates the APT transaction. The simulated transaction must have exactly zero upgrades and zero removals. A general preparation approval and a separate, explicit yes for CMake package installation are required. APT is run only after the shared SRS lock has been acquired.
  • Re-simulates the APT transaction immediately before the actual install and refuses changed plans. Does not run apt-get update or request backports. Validates that cmake >= 3.24 and ctest are available after package installation. APT package changes are intentionally not reverted by SRS file rollback; an interrupted APT transaction requires manual inspection.
  • These checks are a safety guard, not an absolute guarantee against concurrent external changes in APT repositories, package indexes or package states.

Still not approved for production --install. No live package installation, PostSRSd build, first-install or failure-injection/rollback test has been performed for v0.7.

Changes in review draft 0.8 (18 October 2026)

  • Fixed actual delivery main.cf template rendering: template placeholders must be resolved by the exact case-sensitive Postfix parameter name on the left-hand side of the template assignment, not placeholder.lower(). smtp_tls_CAfile was erroneously queried as smtp_tls_cafile, causing a Postfix warning and an empty smtp_tls_CAfile in the generated delivery configuration.
  • The rendering step now refuses placeholders not standing alone in a Postfix assignment and refuses postconf errors/warnings instead of silently accepting an empty value. Existing valid empty settings remain possible. No reference template changed.
  • Still a review draft; no production --install approval.

Changes in review draft 0.9 (18 October 2026)

  • Same-version maintenance update: If /usr/local/postsrsd already resolves to the selected /usr/local/postsrsd-<version>, no Git/CMake/CTest build, no new installation prefix, and no symlink switch are performed. Instead, the installer renders and updates the four integration Python programs, PostSRSd config, separate Postfix delivery config/map and two systemd unit files with existing file snapshots and rollback.
  • Version-change update: When the selected version differs from the existing symlink target, the previous immutable version prefix is retained; the new version is built, staged and selected only after the prepared integration files have been copied. Failed deployment attempts restore the previous symlink and tracked files and remove the new prefix, provided it is not selected. This requires services to be inactive.
  • Strict inactive-only updates: For both maintenance updates and version changes, any SRS managed block in either productive Postfix main.cf or master.cf, or any running SRS systemd service, causes an immediate refusal. The operator must coordinate deactivation and downtime separately; live/zero-downtime updates remain unsupported. This draft never restarts or activates services.
  • Existing SRS secret and PRE-SRS state are never regenerated during an update. A missing secret or state on an existing installation is treated as an error before any writes.
  • CMake/CTest and Debian package provisioning are not required for same-version integration-only updates. They remain required for initial installation or PostSRSd version changes. The requested version defaults to 2.4.1; use --version X.Y.Z to specify another release.
  • Installation directory backups are created only after the final deployment confirmation; operator cancellation before deployment does not create an empty backup snapshot.
  • The change-tracking flags for new prefixes and symlink switches are set immediately before the respective filesystem operation to improve interruption handling (but SIGKILL, power loss and concurrent external changes remain outside the rollback guarantee).
  • A controlled offline mock test was run with all install paths remapped into a temporary directory, with fake systemctl, postfix, postmap, postconf, git, cmake, ctest and DNS checks. Cases that passed: same-version maintenance update, failed maintenance update with rollback of the helper and preservation of secret/symlink, version-change update (2.4.1 → simulated 2.4.2), failed version-change update (simulated 2.4.3) with symlink restoration and removal of new prefix. These were mock tests, not real PostSRSd builds, Postfix validation or service starts.
  • The six reference configuration templates, the four reference Python programs, helpers/srs-common.sh, helpers/srs-dns-check.py and activate-srs.sh/deactivate-srs.sh are unchanged. No Git commit has been made on a.mx.oopen.de by this development process.

NOT production-ready yet: First-install and rollback tests with actual Postfix and PostSRSd in a disposable Debian 13 environment, source-build verification and runtime end-to-end delivery checks remain necessary. Do not execute --install on a production mail server yet.

Changes in review draft 0.10 – display and offline test status (18 October 2026)

  • Shortens the APT dry-run output in both --check and --install preflight: report the transaction summary and the packages in Inst lines. The actual apt-get -s output remains the source of truth; the --install safety gate still requires zero upgrades and removals and still compares the full plan before installing packages. If the simulation cannot be summarized, the full text is printed for diagnosis and the --install plan is rejected.
  • No changes to the six Postfix/PostSRSd templates, to the four SRS Python integration programs, or to the SRS common and DNS helper scripts.
  • A simulated end-to-end --check in a temporary directory, using fake postconf, apt-get, systemctl and DNS helper responses, passed. It detected CMake/CTest as missing, summarized four proposed packages and left the test project files unchanged. Bash syntax passed.
  • This environment is Debian 13, and CMake/CTest are available, but actual PostSRSd 2.4.1 source retrieval failed because outbound DNS/network access to GitHub was unavailable; no genuine PostSRSd build, ctest of the real source or real Postfix check was performed. Postfix binaries are unavailable here. The production target a.mx.oopen.de was not modified.
  • As before, do not run --install on production without a genuinely isolated Debian-13 test exercising real PostSRSd and Postfix, including failure injection and rollback.

Changes in review draft 0.11 – directory mode and reproducible offline tests (18 October 2026)

  • A newly created /etc/postsrsd-srs directory must be exactly root:root mode 0700. On directories under a setgid parent, install -d -m 0700 may leave an inherited SGID bit and produce mode 2700. This caused the subsequent maintenance update to fail its strict permission preflight in the isolated test.
  • After creating and registering the new directory for rollback, the installer now applies a five-digit octal chmod (00700), which removes inherited setgid/sticky flags, then confirms owner/group and exact mode. This applies only to newly created paths using a requested explicit mode; existing directory permissions are not silently changed.
  • The new test runner tests/test_installer_mock.py relocates all managed paths into a temporary fixture tree (which deliberately inherits SGID), mocks Git/CMake/CTest, DNS, Postfix and systemd, and supplies a pseudo-terminal to exercise the complete installer flow.
  • Successfully tested scenarios: simulated first install, same-version maintenance update, failure of maintenance update with file rollback, version upgrade, failed version upgrade with symlink/prefix rollback, update refusal when SRS managed block exists, failed initial Postfix check retaining runtime queue directories, and failed postmap with tracked-file rollback.
  • Reproduce the mocked scenarios on an isolated development machine by extracting this archive and executing python3 tests/test_installer_mock.py. This is not a real PostSRSd source build or a Postfix integration test. The fake programs do not validate Postfix syntax, actual LMTP routing, service listeners or mail delivery.
  • Production use remains forbidden pending real integration testing in a disposable Debian 13 VM/container. No changes were made to the productive mailserver a.mx.oopen.de.