3. Installation

Pepsi kann auf zwei Arten installiert werden. Das Bauen aus dem Quellcode aus dem Cargo-Workspace liefert Ihnen die Binärprogramme und überlässt es Ihnen, die Dienstkonten anzulegen, die Privilegien-Bits zu setzen und die Laufzeitverzeichnisse einzurichten. Das vorgefertigte Debian-Paket erledigt all das für Sie — sein postinst legt die Konten, Gruppen, Verzeichnisse, Overrides für privilegierte Binärprogramme und die Datenbank an — sodass nur noch der standortspezifische Bootstrap (die Konfiguration bearbeiten und pepsi-setup ausführen) zu tun bleibt.

Wählen Sie den Tab für die von Ihnen verwendete Methode. Alles danach — Einrichtung von Schema/Schlüsseln/DNS, Betrieb der Dienste, das Privilegienmodell und der Schema-Lebenszyklus — ist für beide gleich.

3.1. Voraussetzungen

  • PostgreSQL — eine Datenbank, in die Pepsi das einzige pepsi-Schema installiert. Alle Komponenten verbinden sich mit derselben Datenbank. (Das Debian-Paket hat postgresql als Depends und zieht es für Sie mit herein.)

  • PostgreSQLs postgresql-contrib – optional und nur für Mailinglisten. Es bringt die Erweiterung pg_trgm mit, die das Mailinglisten-Archiv für die Teilzeichenfolgen- und Fuzzy-Suche benutzt: einen Hostnamen, einen Konfigurationsschlüssel, eine Zeile aus einem Traceback oder einen Namen zu finden, den der Suchende falsch geschrieben hat. Ein Stammform-Wörterbuch wirft genau dieses Material weg, die Volltextsuche kann diese Anfragen daher überhaupt nicht beantworten.

    Ein Server ohne es installiert und läuft normal. Die Erweiterung wird in einem abgesicherten Block erzeugt, ihr Fehlen ist daher eine Warnung und keine gescheiterte Installation; das Archiv hat dann nur Volltextsuche, und pepsi-list check sagt, in welchem Modus der Server ist. Es später zu installieren und pepsi-setup run erneut auszuführen schaltet es ein, danach braucht das bestehende Archiv ein pepsi-archive reindex, um die Spalte zu füllen, die der Index liest.

    Das Debian-Paket führt es unter Recommends, ein voreingestelltes apt install zieht es also mit, und ein Server, der keine Listen betreibt, kann es entfernen.

  • Für echten Mail-Verkehr: öffentliches DNS, das Sie für jede bediente Domain kontrollieren (um DKIM-, SPF- und MTA-STS-Einträge zu veröffentlichen), und die Fähigkeit, den privilegierten SMTP-Port 25 (und 465/587 für Submission) zu binden. Ein Entwicklungs-Build kann vollständig auf unprivilegierten Ports und einer Wegwerf-Datenbank laufen.

3.2. Pepsi installieren

Bauen Sie den Workspace, platzieren Sie die Binärprogramme und das SQL mit make install und legen Sie die Systemkonten und Privilegien selbst an (dieselben, die das Paket anlegen würde — siehe Benutzer, Gruppen und Privilegien unten).

Zusätzliche Voraussetzungen

  • Eine Rust-Toolchain mit rustc 1.93 oder neuer (die Untergrenze legt das mitgelieferte taler-common fest; ./configure warnt bei einer älteren), dazu die nativen Build-Abhängigkeiten der Krypto- und Kerberos-Crates: pkg-config, cmake, libclang, nettle, GMP und die Kerberos-Entwicklungsheader (unter Debian: libclang-dev, nettle-dev, libgmp-dev, libkrb5-dev).

  • Das mitgelieferte GNU-Taler-Rust-Submodul, das vor dem ersten Build geholt wird:

    git submodule update --init --recursive
    

Bauen

Pepsi ist ein Cargo-Workspace, dessen Root-Paket (pepsi) jedes Binärprogramm unter src/bin/ besitzt; die pepsi-*-Member-Crates sind Bibliotheken, die die dünnen Binärprogramme aufrufen. Ein Entwicklungs-Build erzeugt eine ausführbare Datei pro Programm:

cargo build --workspace

Ein Release-Build hingegen verlinkt die meisten Programme zu einem einzigen Multi-Call-Binärprogramm pepsi, das das auszuführende Programm anhand des Namens auswählt, unter dem es aufgerufen wird (argv[0]). Dies wird durch das Cargo-Feature unibin ausgewählt (das das make build-Ziel für Sie aktiviert); das Standard-Feature multibin behält die programmweisen Binärprogramme bei, die für Entwicklung und Testsuite verwendet werden:

make build   # == cargo build --release --locked \
             #      --no-default-features --features unibin,crypto-nettle

So oder so führen Sie die programmweisen Namen aus; das Release-Layout installiert sie als Symlinks auf das eine Binärprogramm (siehe Installieren). Einige Programme werden nicht eingefaltet und bleiben eigenständig; die maßgebliche Liste ist STANDALONE_BINARIES im Makefile. Zwei Gründe bringen ein Programm dorthin:

  • es trägt sein eigenes setuid- oder setgid-Bit, was ein gemeinsames Binärprogramm nicht je Programm kann — die Helper für lokale Zustellung, ~/.forward und Wallet und ihre aufrufenden Stages, das Smarthost-Relay, pepsi-quota, pepsi-whitelist sowie pepsi-stage-encrypt und pepsi-stage-decrypt (beide setuid pepsi-crypto, damit sie das private Schlüsselmaterial erreichen können) — oder eine Site kann ihm eines geben (pepsi-keys);

  • es wird separat ausgerollt oder aufgerufen — pepsi-setup, pepsi-config, pepsi-stage-detect-language (dessen Sprachmodelle groß sind; dieses Binärprogramm ist selbst multi-call, und ein zweiter $PATH-Symlink, pepsi-detect-language, führt das Offline-Diagnosewerkzeug daraus aus), pepsi-telemetry (das in einem eigenen Paket ausgeliefert wird und auf einem separaten Host läuft) und pepsi-helper-mailbox-scan (das pepsi-whitelist über seinen Namen ausführt).

Die Programme, auf die sich dieses Kapitel bezieht, sind unten aufgeführt. Dies ist eine Auswahl, kein Inventar: Die maßgeblichen Listen sind FOLDED_BINARIES und STANDALONE_BINARIES im Makefile (BINARIES wird aus diesen beiden abgeleitet und ist selbst nicht bearbeitbar).

  • pepsi-ingress — eingehender SMTP-Server

  • pepsi-dispatch — Stage-Dispatcher

  • pepsi-stage-arc, pepsi-stage-srs, pepsi-stage-encrypt, pepsi-stage-decrypt, pepsi-stage-dkim-sign, pepsi-stage-bounce, pepsi-stage-relay-to-internet, pepsi-stage-relay-to-smarthost, pepsi-stage-discard — die Stages

  • pepsi-setup — Einrichtung/Bootstrap

  • pepsi-queue — Inspektion/Reparatur der Warteschlange

  • pepsi-status — Gesundheitszusammenfassung der Pipeline

  • pepsi-sendmail — lokale Submission (vom Debian-Paket als /usr/sbin/sendmail installiert)

Die Qualitätsschranken, die das Projekt grün hält, sind:

RUSTFLAGS="-D warnings" cargo build --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all -- --check
cargo test --workspace
cargo deny check
make docs

cargo test --workspace benötigt ein erreichbares PostgreSQL, weil die Crate für den Dispatcher-Lebenszyklus den echten Dispatcher gegen eine Datenbank startet. make check ist der Einstiegspunkt, der das absichert – er überspringt diese Suite, statt fehlzuschlagen, wenn keine Datenbank nutzbar ist – und führt außerdem cargo deny check aus; siehe Weitere make-Ziele unten.

Installieren

Ein bloßer Build erzeugt nur Binärprogramme; Pepsi liefert außerdem SQL-Migrationen und eine Beispielkonfiguration, die auf der Platte abgelegt werden müssen. Das Makefile umschließt beides — führen Sie es als root aus, damit es auch die Privilegien-Bits der Binärprogramme setzen kann (andernfalls gibt es die genauen, von Hand auszuführenden chown/chmod aus):

make install PREFIX=/usr/local SYSCONFDIR=/etc DESTDIR=

Besser noch: Führen Sie zuerst ./configure aus und lassen Sie es die Verzeichnisvariablen in config.mk auflösen (das das Makefile vor seinen eigenen Standardwerten liest, sodass gilt, was configure entschieden hat). Jedes Verzeichnis leitet sich von --prefix ab, sodass die Angabe eines Präfixes und sonst nichts die gesamte Installation — Binärprogramme, SQL, config.d-Standardwerte und Nachrichtenvorlagen — darunter verschiebt:

./configure --prefix=/opt/pepsi     # templates at /opt/pepsi/share/pepsi/templates
make && make install

--sysconfdir ist die eine Ausnahme, denn eine Konfigurationsdatei muss dort liegen, wo das System sie sucht: Es ist /etc, wenn kein --prefix angegeben wurde (und auch, wenn --prefix=/usr angegeben wurde, da /usr/etc auf keinem System existiert), und sonst $(PREFIX)/etc. Geben Sie --sysconfdir ausdrücklich an, um es in beide Richtungen zu überschreiben.

./configure --help listet alles auf, was es akzeptiert. Neben den GNU-Verzeichnisvariablen (--prefix, --exec-prefix, --bindir, --sbindir, --libexecdir, --sysconfdir, --datarootdir, --datadir, --mandir, --infodir, --docdir) nimmt es entgegen:

--with-templatedir=DIR

Wohin die Nachrichtenvorlagen kommen; muss mit [pepsi] TEMPLATE_DIR übereinstimmen. Standardwert ist $(DATADIR)/templates.

--with-systemdunitdir=DIR / --with-tmpfilesdir=DIR / --with-sendmail-libdir=DIR

Die Unit-Dateien, das tmpfiles.d-Schnipsel und der Ort, an den der überkommene Link /usr/lib/sendmail kommt.

--with-maildir-group=NAME, --with-forward-group=NAME, --with-wallet-group=NAME, --with-token-group=NAME, --with-dispatch-group=NAME, --with-crypto-user=NAME, --with-whitelist-user=NAME

Die lokalen Namen der Konten und Gruppen, die die privilegierten Binärprogramme absichern (siehe Privilegierte Binärprogramme unten). Standardwerte sind pepsi-maildir, pepsi-forward, pepsi-wallets, pepsi-token, pepsi, pepsi-crypto und pepsi-whitelist.

--enable-docs / --disable-docs

Ob die Man-Pages und das Info-Handbuch aus den Quellen gerendert oder vorgebaut übernommen werden (was ein Release-Tarball mitliefert). Standardwert ist auto: an, wenn sphinx-build, makeinfo und Python mit docutils allesamt vorhanden sind.

--enable-mta-links / --disable-mta-links

Ob make install /usr/sbin/sendmail und den Rest der Debian-Schnittstelle für Mail-Transport-Agents beansprucht. Standardmäßig aus, sodass eine Quellinstallation den vorhandenen MTA des Systems nicht stillschweigend verdrängen kann; das Debian-Paket übergibt INSTALL_MTA_LINKS=yes, weil sein Conflicts: mail-transport-agent die Ausschließlichkeit bereits garantiert.

--with-crypto-backend=FEATURE

Das Cargo-Feature für das Sequoia-Krypto-Backend (Standardwert crypto-nettle).

CARGO=, INSTALL=, SPHINXBUILD=, MAKEINFO=, INSTALL_INFO=, RST2MAN= und PYTHON= werden als VAR=VALUE-Argumente oder aus der Umgebung akzeptiert. Optionen, für die dieser Build keine Verwendung hat (--libdir, --localstatedir, --build, --host, …), werden akzeptiert und ignoriert, sodass ein generischer Paketierungstreiber das Skript unverändert aufrufen kann; nur ein fehlendes cargo ist ein harter Fehler.

make install führt die folgenden Schritte aus:

install-bin

Baut das (vereinheitlichte) Release-Binärprogramm und installiert es nach $(DESTDIR)$(PREFIX)/libexec/pepsi/pepsi, erstellt dann einen $(DESTDIR)$(PREFIX)/bin-Symlink pro eingefaltetem Programmnamen, der darauf zeigt (z. B. pepsi-ingress -> ../libexec/pepsi/pepsi). Die siebzehn eigenständigen Programme, die in STANDALONE_BINARIES im Makefile genannt sind, werden als eigene ausführbare Dateien in $(DESTDIR)$(PREFIX)/bin installiert. Weil jeder Symlink weiterhin in $(PREFIX)/bin (auf $PATH) liegt, ist die Laufzeit-Herleitung von DATADIR unten davon unberührt.

install-data

Kopiert die SQL-Dateien von pepsi-setup/db/ nach $(DESTDIR)$(DATADIR)/sql (wobei DATADIR = $(PREFIX)/share/pepsi). pepsi-setup liest diese beim Installieren des Schemas; der Standardwert von SQL_DIR ist ${DATADIR}/sql. Installiert außerdem contrib/hosters.txt als $(DATADIR)/hosters.txt, die Liste öffentlicher Hoster, für die pepsi-whitelist import --auto-wildcard nie einen Platzhalter vorschlägt.

install-templates

Kopiert die Nachrichtenvorlagen (<name>.<lang>.body — die Zahlungsaufforderung des Anti-Spam, die Bounce-Nachrichtentexte, die Mailinglisten-Hinweise und die übrigen automatischen Antworten) nach $(DESTDIR)$(TEMPLATEDIR), das standardmäßig $(DATADIR)/templates ist. Der Standardwert [pepsi] TEMPLATE_DIR der Binärprogramme ist ${DATADIR}/templates und wird über dieselbe Laufzeitableitung aufgelöst, sodass beide Enden unter jedem Präfix übereinstimmen, ohne dass die Konfiguration einen Pfad nennt.

install-config

Installiert die Referenzdatei pepsi.conf.sample unter $(DESTDIR)$(SYSCONFDIR)/pepsi/. Sie legt nie eine pepsi.conf an: Die Vorlage bindet optionale Stages ein, die weitere Einrichtung brauchen, und ist keine funktionierende Konfiguration; die produktive Datei kommt daher von pepsi-setup --wizard (eine vorhandene wird nie angefasst).

install-config-d

Kopiert contrib/config.d/*.conf nach $(DESTDIR)$(DATADIR)/config.d. Dies sind paketierte Standardwerte, keine conffiles, und sie werden vor pepsi.conf geparst — siehe Konfiguration. Zwei werden mit Pepsi ausgeliefert: die Texte der Abwesenheitsnotiz je Sprache und die Einstellung des S/MIME-Containers (CRYPTO_ALLOW_DOWNGRADE).

install-man / install-info

Installiert die gerenderten roff-Handbuchseiten unter $(DESTDIR)$(MANDIR)/manN und pepsi.info unter $(DESTDIR)$(INFODIR) (mit install-info registriert). Mit BUILD_DOCS=no — was ./configure --disable-docs setzt und was ein Release-Tarball verwendet — werden vorgefertigte Seiten installiert, statt sie zu rendern, und jeder Schritt wird mit einer Meldung übersprungen, wenn keine vorhanden sind.

install-doc

Installiert README.md, NEWS, SECURITY.md, AUTHORS, COPYING und die Lizenztexte aus LICENSES/ unter $(DESTDIR)$(DOCDIR), standardmäßig $(DATAROOTDIR)/doc/pepsi.

install-systemd

Installiert die systemd-Units aus debian/systemd/ in $(DESTDIR)$(SYSTEMDUNITDIR) (wobei /usr/bin und /etc/pepsi auf die konfigurierten BINDIR/SYSCONFDIR umgeschrieben werden) sowie das tmpfiles.d-Bruchstück, das /run/pepsi seinen Eigentümer und seine ACL gibt – woher die Rechte dieses Verzeichnisses vollständig stammen, denn keine Unit darf es als RuntimeDirectory deklarieren (siehe Keine Unit darf es als RuntimeDirectory beanspruchen). Alles wird deaktiviert ausgeliefert. make install INSTALL_ADMIN_UNITS=no lässt die beiden pepsi-setup-apply-Units weg, was dem Nichtinstallieren des Pakets pepsi-httpd-admin bei einer Quellinstallation entspricht.

Zusätzlich hängt install von den Zielen für die Privilegien-Bits ab (install-helper, install-maildir-stage, install-forward-*, install-auto-pay-*, install-smarthost-stage, install-whitelist-suid, install-crypto-suid, install-quota-tool), die unten unter Privilegierte Binärprogramme beschrieben sind; jedes gibt das von Hand auszuführende chown/ chmod aus, wenn es nicht als Root läuft oder wenn die Gruppe, die es braucht, nicht existiert.

Überschreiben Sie PREFIX, SYSCONFDIR und DESTDIR passend zum Zielsystem. make uninstall entfernt alles, was make install abgelegt hat (immer einschließlich beider pepsi-setup-apply-Units, unabhängig von INSTALL_ADMIN_UNITS), lässt aber die aktive pepsi.conf an Ort und Stelle.

Weitere make-Ziele

make check

Der Test-Einstiegspunkt, der keine entfernten Konten benötigt: die Datei-Gegenprüfungen der systemd-Units und des Telemetrie-Socket-Pfads, die Workspace-Tests (ohne die Crate für den Dispatcher-Lebenszyklus, die PostgreSQL benötigt), dann – nach bestem Bemühen, übersprungen statt fehlgeschlagen, wenn die Voraussetzung fehlt – die Lebenszyklus-Suite gegen eine lokale pepsicheck-Datenbank, die Vertragstests der setuid-Helfer, das Skript zur Authentifizierungs-Interoperabilität, cargo deny check und die Querverweisprüfung des Handbuchs.

make integrationtests / make benchmarks

Die Live-Pipeline-Skripte unter tests/, die passwortloses SSH zu den in ACCOUNTS genannten Hosts benötigen (Standardwert tests/test-accounts.ini, angelegt aus tests/test-accounts.ini.sample); integrationtests führt zuerst die Thunderbird-Interoperabilitätsschranke aus. Die Benchmarks sind ein eigenes Ziel, weil sie den MTA absichtlich belasten.

make docs

Das Handbuch für die Quellsprache — ein Alias für make docs-en, das dessen HTML und dessen PDF baut, dazu die Man-Pages und das Info-Handbuch (beide nur in der Quellsprache). make docs-<lang> baut eine andere Sprache und make docs-all baut jede Sprache in DOC_LANGUAGES (en de fr); make html baut allein das HTML jeder Sprache.

make dist / make distcheck

Bauen den Release-Tarball pepsi-$(VERSION).tar.gz (jede versionierte Datei einschließlich des mitgelieferten Submoduls, dazu configure und vorgebaute Dokumentation) und prüfen ihn, indem sie ihn in einen sauberen Baum entpacken und configure, make, make check, make install und make uninstall gegen ein Wegwerf-Präfix ausführen. Der Tarball wird aus dem Arbeitsbaum kopiert; deshalb verweigert make dist die Arbeit, solange eine versionierte Datei von HEAD abweicht oder das Submodul nicht auf dem in HEAD verzeichneten Commit steht (unversionierte Dateien zählen nicht); make dist DIST_ALLOW_DIRTY=yes baut trotzdem einen Entwicklungs-Tarball.

make clean / make distclean

clean führt cargo clean aus und entfernt die gerenderte Dokumentation; distclean entfernt zusätzlich config.mk, config.status und alles, was make dist erzeugt hat.

Bemerkung

DATADIR muss mit dem übereinstimmen, was die Binärprogramme zur Laufzeit berechnen: taler-common leitet ${DATADIR} als <install-prefix>/share/pepsi aus dem Speicherort des Binärprogramms selbst ab. Wenn Sie aus einem Quellcode-Checkout (nicht installiert) ausführen, setzen Sie [pepsi-postgres] SQL_DIR explizit, damit pepsi-setup die Migrationen findet.

Das System vorbereiten

Das postinst des Debian-Pakets führt die folgenden Schritte automatisch aus; bei einer Quellcode-Installation führen Sie sie selbst aus und verwenden dabei das gleiche Konto-, Gruppen-, Modus- und Verzeichnis-Layout, das unten unter Benutzer, Gruppen und Privilegien und Verzeichnisse und Geheimnisse dokumentiert ist. Legen Sie die Konten und Gruppen vor make install an (damit es die Privilegien-Bits setzen kann) und die Datenbankrollen vor pepsi-setup (das das Schema installiert):

  1. Legen Sie die Systemkonten an, jedes --system mit /usr/sbin/nologin und Home /var/pepsi und einer privaten Gruppe gleichen Namens, dazu die absichernden Gruppen. debian/pepsi.postinst ist die maßgebliche Liste; diese Schleife ist genau sie, übersetzt:

    for u in pepsi pepsi-ingress pepsi-httpd pepsi-owner \
             pepsi-helper-token-refresh pepsi-whitelist pepsi-crypto \
             pepsi-keydisc pepsi-config; do
        addgroup --system "$u"
        adduser --system --home /var/pepsi --no-create-home \
                --ingroup "$u" --shell /usr/sbin/nologin \
                --disabled-password "$u"
    done
    for g in pepsi-maildir pepsi-forward pepsi-token pepsi-admin \
             pepsi-telemetry; do
        addgroup --system "$g"
    done
    # The shared-wallet account owns its wallet databases, so unlike the
    # service accounts it gets a real home.
    addgroup --system pepsi-wallets
    adduser --system --home /var/lib/pepsi-wallets --ingroup pepsi-wallets \
            --shell /usr/sbin/nologin --disabled-password pepsi-wallets
    install -d -o pepsi-wallets -g pepsi-wallets -m 0700 /var/lib/pepsi-wallets
    # Memberships: telemetry producers, and the SRS secret fragment.
    adduser pepsi pepsi-telemetry
    adduser pepsi-ingress pepsi-telemetry
    adduser pepsi pepsi-ingress
    

    Jedes der letzten vier Konten existiert, weil etwas ohne es nicht arbeiten will: pepsi-whitelist ist das Konto, auf das das CLI für weiße Listen setuid ist, pepsi-crypto ist die einzige Datenbankrolle, der crypto_identity.private_wrapped gewährt ist, und der Eigentümer des Fragments mit dem Schlüsselverschlüsselungsschlüssel, pepsi-keydisc ist die engste Rolle der Installation (sie parst Schlüsselmaterial, das aus dem offenen Internet geholt wurde), und pepsi-config ist die einzige Rolle, die die Konfigurationsüberlagerung schreiben darf. Lassen Sie pepsi-crypto aus, und install-crypto-suid warnt lediglich — womit die beiden Krypto-Stages unprivilegiert bleiben und keinen einzigen privaten Schlüssel öffnen können.

  2. Legen Sie die neun PostgreSQL-Login-Rollen und die Datenbank an (Peer-Authentifizierung, als postgres-Superuser) — dieselbe Menge, die debian/pepsi.postinst anlegt, nämlich jedes Konto, das sich über den Peer-Auth-Socket als es selbst authentifiziert. pepsi-telemetry gehört auch auf einem Knoten dazu, der keine Telemetrie bedient: pepsi-setup run vergibt ihm auf jedem Host Rechte und erledigt seine Datenbankarbeit als pepsi-owner, das eine fehlende Rolle nicht anlegen kann:

    for r in pepsi-owner pepsi pepsi-ingress pepsi-httpd \
             pepsi-whitelist pepsi-config pepsi-crypto pepsi-keydisc \
             pepsi-telemetry; do
        createuser "$r"          # createuser takes one role name at a time
    done
    createdb -O pepsi-owner pepsi
    
  3. Führen Sie make install als root aus (siehe oben), damit die setuid/setgid-Bits gesetzt werden; andernfalls setzen Sie sie von Hand gemäß Privilegierte Binärprogramme unten. Jedes install-*-Ziel warnt nur, wenn die Gruppe fehlt, die es braucht — ein oben ausgelassenes Konto oder eine ausgelassene Gruppe lässt das entsprechende Programm also stillschweigend unprivilegiert.

  4. Legen Sie die Laufzeitverzeichnisse mit den unter Verzeichnisse und Geheimnisse aufgeführten Eigentümern und Modi an. pepsi-setup legt /var/pepsi/keys für Sie an; legen Sie die Smarthost-Geheimnis-Verzeichnisse nur an, wenn Sie einen Smarthost konfigurieren, der sie nutzt.

Das Paket ist der einfachere Weg: Es liefert die Binärprogramme (installiert nach /usr/bin), das SQL-Schema, die Nachrichtenvorlagen, die Handbuchseiten, das GNU-Info-Handbuch und socket-aktivierte systemd-Units, und sein postinst richtet das gesamte System für Sie ein.

Das Paket installieren

Installieren Sie das .deb mit apt, damit seine Abhängigkeiten (einschließlich postgresql) mit hereingezogen werden:

apt install ./pepsi_*.deb

Bei configure führt das postinst automatisch:

  • legt die zehn Dienstkonten und die sechs absichernden Gruppen — pepsi-maildir, pepsi-forward, pepsi-token, pepsi-admin, pepsi-telemetry und pepsi-wallets — samt den Mitgliedschaften zwischen ihnen an (dieselben Identitäten, die die Quellcode-Installation von Hand erstellt);

  • legt die /var/pepsi-Laufzeitverzeichnisse — keys, tokens, token-refresh, tls, krb5 — sowie /etc/pepsi/secrets und /etc/pepsi/secrets.d mit den unter Verzeichnisse und Geheimnisse unten dokumentierten Eigentümern und Modi an;

  • setzt die Privilegien-Bits der Binärprogramme über dpkg-statoverride (die drei setuid-root-Helfer, die setgid-Programme, die sie ausführen dürfen — die beiden Zustell-Stages, die Wallet-Stage und pepsi-quota —, das setgid-Smarthost-Relay, das setuid pepsi-whitelist und die beiden setuid-pepsi-crypto-Stages — siehe Privilegierte Binärprogramme unten); und

  • legt nach bestem Bemühen die neun PostgreSQL-Login-Rollen (pepsi-owner, pepsi, pepsi-ingress, pepsi-httpd, pepsi-whitelist, pepsi-config, pepsi-crypto, pepsi-keydisc, pepsi-telemetry) und die pepsi-Datenbank (im Besitz von pepsi-owner) an, wenn ein lokaler Cluster erreichbar ist — und gibt andernfalls die von Hand anzulegenden Rollen aus.

Der Dienst wird deaktiviert ausgeliefert: Das Paket installiert Pepsi, startet es aber nicht, und überlässt Ihnen den standortspezifischen Bootstrap.

Bemerkung

pepsi ist eines von vier Binärpaketen, die aus dieser Quelle gebaut werden: Die Spracherkennungs-Stage und der Telemetrie-Collector sind aus Größen- und Installationsgründen abgetrennt, und pepsi-httpd-admin — das pepsi Recommends, sodass apt es standardmäßig installiert — trägt den einzigen Mechanismus, mit dem die Browser-Konsole auf diesem Host eine privilegierte Änderung bewirken kann. Dieses eine Paket zu entfernen ist ein unterstützter Härtungsschritt für eine Installation, die vom Terminal aus verwaltet wird. Debian-Pakete beschreibt jedes Paket und diesen Hebel vollständig.

Nachdem das Paket installiert ist

Bei der Erstinstallation kopiert das Paket eine Platzhalter-Konfiguration nach /etc/pepsi/pepsi.conf; spätere Upgrades rühren diese Datei nie an (sie ist keine dpkg-Conffile, sodass ein Upgrade nie anhält, um danach zu fragen). Bearbeiten Sie sie und führen Sie dann den Bootstrap genau wie in den gemeinsamen Schritten unten aus — zum Beispiel:

# 1. edit /etc/pepsi/pepsi.conf (HOSTNAME, ACCEPTED_DOMAINS, domains, TLS)
# 2. install the schema + DKIM keys and print the DNS records:
pepsi-setup --no-certbot run        # or:  pepsi-setup --wizard
# 3. publish the printed DNS records, then start the pipeline:
systemctl enable --now pepsi.target

Da die Units socket-aktiviert sind, fährt pepsi.target pepsi-ingress, pepsi-httpd und pepsi-dispatch gemeinsam hoch; Sie rufen die serve-Unterbefehle nicht von Hand auf.

3.3. Migration von einem vorhandenen Mailserver

Wenn auf diesem Host bereits Postfix, Exim, Sendmail, qmail oder Stalwart läuft, müssen Sie dessen Konfiguration nicht von Hand neu herleiten. Ist keine pepsi.conf vorhanden, erkennt pepsi-setup --wizard, was installiert ist, und bietet an, es zu importieren: Hostname, akzeptierte Domains, Smarthost (mit den aus der Passwortdatei jenes Servers gelesenen Relay-Zugangsdaten), Zustellmethode für lokale Mail, Submission-SASL-Socket, vertrauenswürdige Netze, Nachrichtengrößenbeschränkung, Warteschlangen-Lebensdauer und TLS-Zertifikatspfade kommen alle als vorbelegte Antworten des Interviews an, die Sie dann eine nach der anderen bestätigen oder korrigieren.

Um zu sehen, was eine Migration ergäbe, bevor Sie den Assistenten starten — es wird nichts geschrieben:

pepsi-setup import

Routing-Tabellen werden ebenfalls konvertiert. /etc/aliases, /etc/postfix/virtual, Sendmails virtusertable, qmails .qmail-*-Dateien und ihre Entsprechungen werden zu einer Pepsi-Alias-Map neben der Konfiguration (siehe pepsi-stage-aliases), wobei bloße Alias-Namen in dem von Ihnen gewählten Stil qualifiziert werden. Da Pepsi-Alias-Schlüssel eine Domain tragen müssen, wird postmaster: root standardmäßig für jede akzeptierte Domain zu postmaster@example.org  root@example.org.

Alles, was nicht übernommen wird, wird neben der Konfiguration in import-report.txt geschrieben, aufgeteilt danach, was sich nicht parsen ließ, wofür Pepsi keine Entsprechung hat (header_checks, ein Alias, der an einen Befehl zustellt), was angenähert wurde (mbox-Zustellung, die zu Maildir wird) und was der Importer nicht erkannt hat. Ein Import bricht das Setup nie ab — eine nicht lesbare Datei oder eine unbekannte Direktive erzeugt einen Berichtseintrag, keinen Fehler.

Zwei Dinge werden bewusst nicht migriert: eingereihte Mail (lassen Sie die Warteschlange des alten Servers leerlaufen, bevor Sie den MX umstellen) und DKIM-Schlüssel (pepsi-setup run erzeugt frische und gibt die zu veröffentlichenden Einträge aus). Wenn der alte MTA beim Lauf des Assistenten noch Port 25 hält, sagt der Bericht das — halten Sie ihn an und deaktivieren Sie ihn, bevor Sie pepsi-ingress starten.

Siehe pepsi-setup für die Details pro Server, die --alias-style-Auswahlmöglichkeiten und die --expert-Optionen, die die Einstellungen zugänglich machen, nach denen das Interview sonst nicht fragt.

3.3.1. Mailfilter, die bereits auf dem Host laufen

Unabhängig von jeder Migration durchsucht der Assistent den Host nach Milter-Daemons — clamav-milter, rspamd, spamass-milter, milter-greylist, milter-regex, mimedefang, amavisd-milter — und bietet jeden gefundenen als Stage an. Einen zu finden bedeutet der Reihe nach dreierlei: Das Paket ist installiert, ein Socket lässt sich aus seiner eigenen Konfiguration lesen (oder aus seiner Unit oder den Pfaden, die seine Distribution mitliefert), und eine echte Milter-Optionsaushandlung mit diesem Socket kommt zustande. Nichts wird allein aufgrund eines installierten Pakets angeboten, und die Aushandlung ist auch der Grund, weshalb das erzeugte ALLOW_ACTIONS genau das gewährt, was dieser Filter verlangt, statt einer Vermutung.

Angenommene Filter werden nach ihrer Aufgabe platziert — Richtlinie und Greylisting, dann Viren, dann Spam, dann Allzweck-Frameworks — nach der Entschlüsselung und vor den Schranken für weiße Liste und Bezahlung. Da Pepsi nach der Annahme einer Nachricht filtert, wird das REJECT eines Filters zu einer erzeugten Discard-Stage geroutet statt gebounct, sodass gefälschte Absender keinen Backscatter erhalten; siehe pepsi-stage-milter. Filter, deren Aufgabe Pepsi bereits erledigt (opendkim, openarc, opendmarc, SPF-Daemons, postsrsd), werden benannt und übersprungen statt angeboten.

3.4. Datenbank, Schlüssel und DNS einrichten

Wenn eine Konfigurationsdatei vorhanden ist (siehe Konfiguration), führen Sie das Bootstrap-Werkzeug einmal aus:

pepsi-setup -c /etc/pepsi/pepsi.conf run > pepsi-dns.zone

Dies validiert die gesamte Konfiguration, installiert das pepsi-Schema, erzeugt domainspezifische RSA-2048- und Ed25519-DKIM-Schlüssel unter KEY_DIR (nur falls nicht vorhanden) und gibt die zu veröffentlichenden DNS-Einträge aus (öffentliche DKIM-Schlüssel, eine SPF-Richtlinie aus den konfigurierten PUBLIC_IP-Adressen und einen MTA-STS-Eintrag). Die Operation ist idempotent und kann jederzeit erneut ausgeführt werden; das Upgrade des Schemas auf ein neues Release erledigt pepsi-setup schema (siehe Upgrade). run --reset verwirft das Schema und erstellt es neu (zerstört alle eingereihten Nachrichten; Schlüssel auf der Festplatte bleiben erhalten).

Veröffentlichen Sie die ausgegebenen DNS-Einträge und verifizieren Sie dann das Veröffentlichte gegen das, was Pepsi erwartet:

pepsi-setup -c /etc/pepsi/pepsi.conf check

Siehe pepsi-setup für den vollständigen Einrichtungsablauf.

3.5. Im Browser einrichten

Alles Obige lässt sich auch von einem Browser aus erledigen, gegen denselben Code. Der Terminalweg ist der kürzeste Weg auf einer Maschine, auf der Sie eine Shell haben; der Browserweg ist für die, auf denen Sie keine haben, und für Operatoren, die die DNS-Einträge lieber als rot/grüne Checkliste sehen als als Zonendatei.

3.5.1. Die Trennung, und warum

Das Setup ist privilegiert: Es schreibt /etc/pepsi/pepsi.conf, übergibt jedes secrets.d-Fragment dem einzigen Konto, das es liest, führt certbot aus, legt Datenbankrollen an und erzeugt Schlüsselmaterial — alles als root. pepsi-httpd, das die Oberfläche bedient, gibt seine Privilegien ab, bevor es eine Verbindung annimmt, und darf sie nie zurückerlangen.

Es handelt also nicht. Es schreibt einen Absichts-Datensatz, der sagt, was wahr sein soll, und ein separates root-Programm — pepsi-setup apply, auf Anforderung gestartet und wieder fort, wenn es nichts zu tun hat — entscheidet wie, tut es und hält fest, was geschehen ist. Root ist nie im Netz. Lesen Sie „Das Vertrauensmodell des Appliers“ in :doc:`programs/pepsi-setup`, bevor Sie das aktivieren: Dort steht genau, was der Applier tun und nicht tun wird, einschließlich der Dinge, die er bewusst nicht kann (es gibt keine Neustart- oder Abschaltaufgabe, und install-schema lehnt reset ab).

3.5.2. Es aktivieren

Die Debian-Pakete liefern eine minimale, aber vollständige Konfiguration, einen administrativen Listener auf einem UNIX-Socket und — in pepsi-httpd-admin, das pepsi Recommends und apt daher standardmäßig installiert — die Socket-Unit des Appliers (siehe Debian-Pakete). Drei Schritte:

# systemctl enable --now pepsi-httpd.socket pepsi-setup-apply.socket
# pepsi-setup -c /etc/pepsi/pepsi.conf bootstrap

Der zweite gibt ein Einmal-Token und den curl-Befehl aus, der daraus das erste Administratorkonto macht. Auf der Maschine selbst können Sie ihn ganz überspringen: Ein Mitglied der Gruppe pepsi-admin (und root) wird über SO_PEERCRED auf /run/pepsi/admin.sock identifiziert und braucht überhaupt kein Credential.

Eine weitere Einstellung ist nötig, bevor überhaupt etwas Privilegiertes angefordert werden kann: [pepsi-admin] CONFIG_DB muss eine Verbindung benennen, die sich als Datenbankrolle pepsi-config authentifiziert. Das ist die Grenze: Nur diese Rolle darf Setup-Arbeit in die Warteschlange stellen, und das eigene Konto von pepsi-httpd ist es nicht, sodass eine Kompromittierung der Web-Schicht keine Kompromittierung der Pipeline-Definition ist. Solange sie nicht gesetzt ist, antworten die Setup-Endpunkte mit 503 und sagen es.

3.5.3. Es bedienen

Das Interview ist Daten. GET /api/v1/setup/questions liefert die geordneten Schritte und, für jede Frage, ihre Form, ihren Standardwert, ihren Hilfetext und die Bedingung, unter der sie gestellt wird — dasselbe Modell, das pepsi-setup questions ausgibt, und dasselbe, durch das der Terminal-Assistent beschrieben ist, von der Testsuite als gleich zugesichert. Antworten werden mit PUT /api/v1/setup/answers in Entwurfsdatensätze vorbereitet, die kein laufender Prozess sehen kann, sodass eine unterbrochene Sitzung nichts halb konfigurieren kann.

POST /api/v1/setup/tasks fordert dann die privilegierte Hälfte an — die Konfiguration schreiben, Zertifikate beschaffen, das Schema installieren, Schlüssel erzeugen — und GET /api/v1/setup/tasks/{id}?since=<seq> streamt Zeile für Zeile, was der Applier tut.

3.5.4. Was immer einen Texteditor brauchen wird

Manche Einstellungen werden ausschließlich aus der Konfigurationsdatei gelesen, und daran wird keine Oberfläche etwas ändern: [pepsi], [pepsi-postgres], [paths] sowie die Listener-Abschnitte für HTTP(S) und Ingress. Sie müssen funktionieren, bevor eine Datenbankverbindung existiert, oder sie sind eine Sicherheitsgrenze — eine Datenbank, die einen lauschenden Socket verschieben oder die Kryptorichtlinie lockern könnte, machte eine Datenbankkompromittierung zu einer Kompromittierung des eigenen TLS und der Ports des MTA.

Also: Einen Submission-Port hinzuzufügen oder einen Listener zu verschieben ist eine Texteditor-und-Neustart-Operation. Ebenso jede Änderung, die die Konsole als restart statt als hot kennzeichnet: Es gibt keinen Neustartknopf, denn ein Knopf, der einen Dienst auf Anforderung neu startet, gäbe die Privilegien der Web-Schicht an jeden weiter, der sie erreicht.

3.5.5. Es skripten

Dasselbe Antwortmodell treibt eine unbeaufsichtigte Installation:

pepsi-setup --wizard --answers answers.json -c /etc/pepsi/pepsi.conf

pepsi-setup questions gibt das Schema aus, gegen das diese Datei geschrieben wird. Das ist keine dritte Implementierung des Interviews: Es führt das interaktive aus, mit jeder Frage aus der Datei beantwortet, sodass die Verzweigungen und die Validierung je Feld dieselben sind, die ein Mensch sieht.

3.6. Die Dienste betreiben

Zwei langlebige Prozesse müssen dauerhaft laufen:

  • pepsi-ingress serve — nimmt Mail an (typischerweise unter einem Dienstmanager, optional mit systemd-Socket-Aktivierung für die privilegierten Ports).

  • pepsi-dispatch serve — läuft mit genau einer Instanz pro System; es ist der einzige Prozess, der Stage-Programme startet.

Die Stage-Programme selbst werden vom Dispatcher als persistente PROGRAM worker-Prozesse gestartet, die Nachrichten-IDs von der Standardeingabe lesen; im Produktivbetrieb führen Sie sie nicht von Hand aus (zum Debuggen können Sie eine ID an worker weiterleiten, z. B. echo 42 | pepsi-stage-srs -c /etc/pepsi/pepsi.conf worker).

3.7. Upgrade

Ab dem ersten Release, 0.0.0, aktualisiert jedes Release die Datenbank jedes früheren Releases an Ort und Stelle: Die Warteschlange, der Schlüsselspeicher, die Einstellungen und alles andere darin bleiben erhalten, und in der Warteschlange wartende Mail wird vom neuen Release zugestellt. Downgrades werden nicht unterstützt (siehe unten).

Das Vorgehen:

  1. Lesen Sie NEWS zu dem Release. Es führt geänderte Konfigurationsoptionen auf und alles andere, was von Hand zu erledigen ist.

  2. Legen Sie eine Sicherung an (Sicherung und Wiederherstellung), oder aktivieren Sie zumindest den unten beschriebenen automatischen Dump.

  3. Installieren Sie das neue Release. Die Debian-Pakete erledigen den Rest: Sie aktualisieren das Schema und starten die Dienste neu, die liefen. Aus den Quellen: make install, dann pepsi-setup -c /etc/pepsi/pepsi.conf schema und systemctl try-restart pepsi.target.

  4. Prüfen Sie mit pepsi-status, dass sich die Warteschlange leert, und sehen Sie im Journal nach Warnungen (Logs).

Der Rest dieses Abschnitts erklärt, was in Schritt 3 geschieht.

Jedes Pepsi-Programm prüft beim Verbinden mit der Datenbank, dass das Schema aus genau den SQL-Dateien gebaut wurde, mit denen das Programm selbst gebaut wurde. Der Installer hält SHA-256 und Release jeder angewendeten Datei in pepsi.schema_file fest, und ein Programm, das etwas anderes vorfindet – ein älteres Schema, ein neueres oder eines aus anderen Dateien –, hält sofort mit Exit-Status 78 und einer Meldung an, die die Abhilfe nennt, statt mitten in einer Nachricht an der ersten fehlenden Spalte zu scheitern. Der Dispatcher behandelt einen Stage-Worker, der auf diese Weise anhält, als „kann noch nicht laufen“, nicht als Absturz: Die Nachricht, die ihm übergeben wurde, kommt zurück in die Warteschlange und wird nie auf failed gesetzt.

Das Upgrade des Schemas ist ein eigener Schritt:

pepsi-setup -c /etc/pepsi/pepsi.conf schema

Er installiert die Patches, die dieses Release hinzufügt, ersetzt die gespeicherten Funktionen, wendet die Rollenrechte erneut an und tut sonst nichts – keine Zertifikate, Schlüssel oder DNS –, braucht also nur den Abschnitt [pepsi-postgres]. Auf einem Telemetrie-Collector übergeben Sie ihm die Datei des Collectors, /etc/pepsi-telemetry/pepsi-telemetry.conf.

Debian-Pakete führen ihn bei ihrer Aktualisierung automatisch aus, bevor die Dienste neu gestartet werden; eine Neuinstallation bleibt pepsi-setup run überlassen. Schlägt er fehl (etwa weil die Datenbank nicht läuft), wird das Paket trotzdem installiert, ein Hinweis meldet dies, und die Dienste verweigern den Start und werden von systemd erneut versucht – mit zunehmendem Abstand bis zu einmal pro Minute, ohne Startlimit –, bis das Schema passt. Ist die Ursache behoben, genügt es, den obigen Befehl auszuführen; die Dienste kommen von selbst wieder.

Aus den Quellen, nach make install:

pepsi-setup -c /etc/pepsi/pepsi.conf schema
systemctl try-restart pepsi.target

Was die Zurückweisungen bedeuten:

Die Meldung sagt

Was zu tun ist

kein pepsi-Schema

Eine Neuinstallation: pepsi-setup run (oder pepsi-setup schema auf einem Collector-Host).

älter als dieses Programm

pepsi-setup -c FILE schema.

neuer als dieses Programm

Ein Downgrade, der nicht unterstützt wird. Installieren Sie das neuere Release wieder, oder stellen Sie die vor dem Upgrade angelegte Datenbanksicherung wieder her (siehe unten).

aus einer anderen Fassung eines Patches gebaut

Ein veröffentlichter Patch ändert sich nie, dies ist also ein Fehler; bitte melden Sie ihn. Die einzige Ausnahme ist eine Datenbank, die aus einem Entwicklungsstand gebaut wurde (einem Git-Checkout zwischen Releases), bei dem der neueste Patch noch bearbeitet wird: Leeren Sie sie und erstellen Sie sie mit pepsi-setup run --reset neu.

gespeicherte Funktionen aus einem anderen Build

Nur bei Entwicklungs-Builds: pepsi-setup -c FILE schema.

3.7.1. Downgrades

Nicht unterstützt. pepsi-setup weigert sich, das SQL eines älteren Releases über ein neueres Schema zu installieren (Exit-Status 78, nichts geändert), und die Programme des älteren Releases verweigern darauf den Betrieb. Zurück zu einem älteren Release geht es nur, indem Sie eine vor dem Upgrade angelegte Datenbanksicherung wiederherstellen und danach die älteren Pakete installieren.

3.7.2. Sicherung vor einem Schema-Upgrade

Eine Sicherung wird nur angelegt, wenn Sie sie aktivieren. Ist sie aktiviert, wird sie nur angelegt, wenn ein Upgrade das Schema tatsächlich ändert: pg_dump sichert das pepsi-Schema (mit den Erweiterungen, die es verwendet) als pepsi-<previous version>-<UTC time>.dump, nur für root lesbar. Schlägt der Dump fehl, wird das Schema nicht aktualisiert. Sicherungen werden nie automatisch gelöscht.

Bei den Debian-Paketen ist es eine debconf-Einstellung, die nur mit Priorität low abgefragt wird:

dpkg-reconfigure -plow pepsi

Antworten Sie mit yes und bestätigen oder ändern Sie das Verzeichnis (Vorgabe /var/backups/pepsi). Unbeaufsichtigt oder vor dem ersten Upgrade:

echo "pepsi pepsi/schema-backup boolean true" | debconf-set-selections
echo "pepsi pepsi/schema-backup-dir string /var/backups/pepsi" | debconf-set-selections

Auf einem Telemetrie-Collector-Host gehören die Fragen zu pepsi-telemetry (pepsi-telemetry/schema-backup, pepsi-telemetry/schema-backup-dir). Sind beide Pakete installiert und verwenden dieselbe Datenbank, legt dasjenige die Sicherung an, das sie zuerst aktualisiert.

Aus den Quellen übergeben Sie das Verzeichnis dem Upgrade-Schritt:

pepsi-setup -c /etc/pepsi/pepsi.conf schema --backup-dir /var/backups/pepsi

Um eine Sicherung wiederherzustellen, stoppen Sie die Dienste, legen die Datenbank leer und im Besitz des Schemaeigentümers neu an und stellen die Sicherung als dieser Eigentümer darin wieder her:

systemctl stop pepsi.target
sudo -u postgres dropdb pepsi
sudo -u postgres createdb -O pepsi-owner pepsi
sudo -u pepsi-owner pg_restore -d pepsi /var/backups/pepsi/pepsi-0.0.0-20261001T000000Z.dump

Installieren Sie danach das Release, aus dem die Sicherung stammt, und starten Sie die Dienste wieder. Alles, was die Datenbank nach der Sicherung erfahren hat – seitdem angenommene Mail, seitdem geänderte Einstellungen –, geht verloren. Die gespeicherten privaten Schlüssel im Dump sind unter dem Schlüsselverschlüsselungsschlüssel in secrets.d verschlüsselt, der nicht in der Datenbank liegt: Bewahren Sie diese Datei auf und sichern Sie sie separat (siehe Sicherung und Wiederherstellung).

3.8. Benutzer, Gruppen und Privilegien

Pepsi läuft niemals als root. Die langlebigen Daemons dürfen als Root gestartet werden, damit sie privilegierte Ports binden und nur für Root lesbare TLS-Schlüssel lesen können, aber jeder gibt seine Privilegien an sein eigenes unprivilegiertes Dienstkonto ab, bevor er auch nur eine Verbindung bedient; kann die Abgabe nicht abgeschlossen werden, verweigert der Prozess den Start, statt zu riskieren, als Root zu laufen (siehe pepsi-common::privdrop). Die lokale Zustellung — die in die Postfächer beliebiger Benutzer schreiben muss — ist die eine Operation, die mehr braucht, als das Dienstkonto geben kann, und sie ist auf einen einzigen, eng begrenzten setuid-Helper beschränkt, statt der Pipeline als Ganzes überlassen zu werden.

Unter den mitgelieferten systemd-Units laufen die Daemons überhaupt nie als root: systemd bindet die privilegierten Sockets (Socket-Aktivierung) und startet jeden Prozess direkt unter seinem Dienstkonto. Bleiben die TLS-Schlüssel, die certbot nur für root lesbar hält — also lässt pepsi-setup auch diese von systemd lesen und schreibt pro Unit ein LoadCredential=-Drop-in: systemd öffnet jedes Zertifikat und jeden Schlüssel als root, wenn es die Unit startet, und übergibt dem Dienst eine private Kopie unter $CREDENTIALS_DIRECTORY, wo der Server zuerst nachsieht. Führen Sie pepsi-setup run erneut aus, wann immer Sie ein Zertifikat hinzufügen, verschieben oder entfernen, damit das Drop-in neu erzeugt wird. Siehe pepsi-httpd.

Die oben beschriebene Browser-Einrichtung ist der eine Weg, auf dem etwas anderes als ein Operator an einem Terminal einen root-Prozess laufen lassen kann: pepsi-httpd betätigt einen Türklingel-Socket, und systemd startet ein kurzlebiges root-pepsi-setup apply. Dieser Weg ist das am leichtesten zu entziehende Privileg in Pepsi. Seine beiden systemd-Units sind ein eigenes Debian-Paket, pepsi-httpd-admin, dessen Entsprechung bei einer Quellinstallation make install INSTALL_ADMIN_UNITS=no ist; ohne sie leert nichts pepsi.setup_task, und keine HTTP-Anfrage kann etwas unterhalb von /etc/pepsi ändern, während pepsi-setup auf einem Terminal unverändert weiterarbeitet. Das Paket wieder einzuspielen wirkt nicht rückwirkend auf das, was in seiner Abwesenheit angefordert wurde: Seine Installation leert diese Warteschlange, bevor seine Units scharfgestellt werden. Siehe Die Aufteilung als Härtungshebel.

Die folgenden Konten und Gruppen werden automatisch durch das postinst des Debian-Pakets angelegt; bei einem make install legen Sie sie selbst an (dieselben Namen). Der PostgreSQL-Zugriff erfolgt per Peer-Authentifizierung über den lokalen Socket: Jedes Dienstkonto meldet sich als gleichnamige Datenbankrolle an, sodass nirgends Passwörter gespeichert werden. Eine entfernte Datenbank behält dasselbe Modell bei: eine Login-Rolle je Konto, jede authentifiziert durch ein eigenes Client-Zertifikat oder eine eigene Passwortdatei, die nur dieses Konto lesen kann und die je Rolle mit dem Platzhalter {role} in [pepsi-postgres] CONFIG benannt wird (siehe CONFIG in pepsi.conf(5)). Die Konfigurationsdatei enthält nie ein Passwort.

3.8.1. Dienstkonten

Dies sind Systemkonten (--system, /usr/sbin/nologin, Home /var/pepsi), jedes mit einer privaten primären Gruppe gleichen Namens. Die ersten drei sind langlebige Daemons, die nach dem Binden auf ihr Konto wechseln; die übrigen sind keine Daemons in der Pipeline.

Konto

Läuft als

Zweck / Zugriff

pepsi-ingress

pepsi-ingress

Eingehender SMTP-Server. Unter systemd socket-aktiviert (nie root; das TLS-Material kommt als Dienst-Credential); von Hand gestartet bindet er 25/465/587 und liest die TLS-Schlüssel als root und gibt die Rechte dann ab. DB-Rolle pepsi-ingress.

pepsi-httpd

pepsi-httpd

HTTP/HTTPS-Server (MTA-STS-Policy + /metrics). Unter systemd socket-aktiviert, genau wie pepsi-ingress; von Hand gestartet bindet er 80/443 als root und gibt die Rechte dann ab. DB-Rolle pepsi-httpd.

pepsi

pepsi-dispatch und jeder Stage-Worker, den er startet

Die Arbeitsidentität der Pipeline. Liest die DKIM-Schlüssel (über die Gruppe pepsi) zum Signieren. DB-Rolle pepsi (besitzt die Warteschlangen-Datensätze). Dies ist das Konto, das die beiden unten genannten Zustell-Gruppenidentitäten vorübergehend erlangt.

pepsi-owner

pepsi-setup (vorübergehend)

Kein Laufzeitdienst. Besitzt die pepsi-Datenbank, das Schema, die Tabellen und Funktionen. Wenn pepsi-setup als Root läuft, nimmt es vorübergehend diese Identität an (seteuid), damit die von ihm erstellten Objekte der peer-authentifizierten pepsi-owner-Rolle gehören, und kehrt dann für die Dateisystemarbeit (Schlüsselerzeugung, Eigentümer-Korrekturen) zu Root zurück.

pepsi-helper-token-refresh

pepsi-helper-token-refresh-Dienst

Nur vorhanden, wenn ein Smarthost AUTH = oauth verwendet. Erneuert OAuth-Zugriffstoken und schreibt die Token-Dateien, die das Smarthost-Relay liest. Hat keine Datenbankrolle.

pepsi-crypto

pepsi-keys (vorübergehend) und die Ende-zu-Ende-Krypto-Stages

Verwahrer des privaten Ende-zu-Ende-Schlüsselmaterials. Besitzt secrets.d/pepsi-crypto.secret, den Schlüsselverschlüsselungsschlüssel, der pepsi.crypto_identity.private_wrapped öffnet, und ist die einzige Datenbankrolle, der diese Spalte gewährt ist — jede andere Rolle, pepsi eingeschlossen, bekommt eine spaltenweise Berechtigung, die sie auslässt. pepsi-keys nimmt diese Identität für die Dauer eines Datenbankaufrufs an und gibt sie sofort wieder ab. Siehe Schlüsselverwaltung.

pepsi-whitelist

pepsi-whitelist (vorübergehend)

Konto, das das setuid-CLI für weiße Listen annimmt, damit gewöhnliche Benutzer ihre eigenen weißen Absenderlisten pflegen können. Seiner Datenbankrolle sind SELECT/INSERT/DELETE auf pepsi.whitelist gewährt und sonst nichts.

pepsi-keydisc

pepsi-keydisc@<method>-Dienste

Schlüsselentdeckung (WKD, DANE, VKS, LDAP). Parst Schlüsselmaterial, das aus dem offenen Internet geholt wird, daher ist seine Datenbankrolle die engste in der Installation. Siehe Schlüsselverwaltung.

pepsi-config

pepsi-config (von einem Operator ausgeführt)

Die einzige Datenbankrolle, die das Overlay pepsi.config_override schreiben darf: Eine Komponente, die Mail verarbeitet, darf die Pipeline, in der sie läuft, nicht umschreiben können.

Die neun PostgreSQL-Login-Rollen — pepsi-owner, pepsi, pepsi-ingress, pepsi-httpd, pepsi-telemetry sowie die eng gefassten Rollen pepsi-whitelist, pepsi-config, pepsi-crypto und pepsi-keydisc — werden vom postinst des Pakets (oder, bei einer manuellen Installation, von Ihnen) angelegt, bevor pepsi-setup das Schema installiert; pepsi-setup gewährt dann jeder, was sie braucht.

3.8.2. Gruppen, die gemeinsame Ressourcen absichern

Vier Gruppen existieren ausschließlich, um den Zugriff auf privilegierte Binärprogramme und geheime Dateien zu kontrollieren. Der pepsi-Benutzer ist bewusst kein dauerhaftes Mitglied einer von ihnen: Das setgid-Bit auf dem betreffenden Stage-Binärprogramm gewährt dem Worker die Gruppenidentität nur für die Lebensdauer dieses Prozesses.

pepsi-maildir

Kontrolliert den Helper für die lokale Zustellung. pepsi-helper-maildir-writer ist setuid root und hat Modus 4750 (root:pepsi-maildir), sodass nur diese Gruppe ihn ausführen darf. pepsi-stage-relay-to-maildir ist setgid auf diese Gruppe (Modus 2550, pepsi:pepsi-maildir — nur der Eigentümer darf ausführen, sodass kein anderer lokaler Benutzer an das setgid-Bit kommt); wenn der pepsi-Worker die Stage ausführt, erlangt er egid=pepsi-maildir, genau das Recht, den Helper zu starten — der dann per setuid zum Empfänger wechselt und ~/Maildir/new/ schreibt. Der Helper ist der einzige Code, der jemals das Postfach eines Dritten berührt.

pepsi-forward

Kontrolliert den ~/.forward-Helper, in genau der Form des Maildir-Paares oben: pepsi-helper-dot-forward ist setuid root und hat Modus 4750 (root:pepsi-forward), und pepsi-stage-dot-forward ist setgid auf diese Gruppe (Modus 2550, pepsi:pepsi-forward). Nur nötig, wenn Sie die ~/.forward-Stage betreiben; ohne die Gruppe geben die Ziele install-forward-helper / install-forward-stage von make install nur eine Warnung aus und lassen die Binärprogramme unprivilegiert.

pepsi-wallets

Kontrolliert den Wallet-Helper auf dieselbe Weise: pepsi-helper-auto-pay ist 4750 root:pepsi-wallets und pepsi-stage-auto-pay ist setgid auf diese Gruppe (Modus 2550, pepsi:pepsi-wallets). Ein Systemkonto gleichen Namens besitzt die gemeinsamen Wallet-Datenbanken unter /var/lib/pepsi-wallets, wenn WALLET_MODE = shared gilt. Nur nötig, wenn Sie die Auto-Pay-Stage betreiben; andernfalls fallen install-auto-pay-helper / install-auto-pay-stage auf eine Warnung zurück.

pepsi-token

Kontrolliert das geheime Material, das das Smarthost-Relay liest: OAuth-Token-Dateien, das Mutual-TLS-Client-Zertifikat/-Schlüssel und den Kerberos-Credential-Cache. pepsi-stage-relay-to-smarthost ist setgid auf diese Gruppe (Modus 2550, pepsi:pepsi-token); die Verzeichnisse, die diese Geheimnisse enthalten, sind setgid pepsi-token, sodass dort abgelegte Dateien die Gruppe erben und das Relay sie lesen kann, ohne dass der pepsi-Benutzer Mitglied ist.

3.8.3. Privilegierte Binärprogramme

Diese Bits werden von make install gesetzt, wenn es als Root läuft (andernfalls gibt es die genauen, von Hand auszuführenden chown/chmod aus), sowie vom Debian-Paket über dpkg-statoverride, das die maßgebliche Liste ist (debian/pepsi.postinst):

Binärprogramm

Modus / Eigentümer

Warum

pepsi-helper-maildir-writer

4750 root:pepsi-maildir

Setuid root, damit es in das Postfach jedes lokalen Benutzers schreiben kann; gruppengesperrt, sodass nur pepsi-maildir es ausführen darf.

pepsi-stage-relay-to-maildir

2550 pepsi:pepsi-maildir

Setgid, damit der pepsi-Worker den obigen Helper ausführen darf. Ausführbar für den Eigentümer und nicht für alle: Das setgid-Bit ist die ganze Schranke, also darf kein anderer lokaler Benutzer an es herankommen. pepsi kann das Ausführungsrecht nicht über die Gruppe bekommen (es ist bewusst kein Mitglied), also bekommt es das Recht dadurch, dass ihm die Datei gehört. pepsi-quota, pepsi-stage-dot-forward und pepsi-stage-auto-pay tragen dieselbe Form für ihre eigenen Gruppen.

pepsi-quota

2550 pepsi:pepsi-maildir

Dieselbe Gruppe und derselbe Grund: measure/reconcile führen den obigen Helper aus, und das Bit ist es, was einem unbeaufsichtigten Durchlauf das ohne Root erlaubt.

pepsi-helper-dot-forward

4750 root:pepsi-forward

Setuid root, damit es die ~/.forward eines Benutzers als dieser Benutzer ausführen kann; auf seine Stage gruppengesperrt.

pepsi-stage-dot-forward

2550 pepsi:pepsi-forward

Setgid, damit der pepsi-Worker den obigen Helper ausführen darf.

pepsi-helper-auto-pay

4750 root:pepsi-wallets

Setuid root, damit es auf das Konto, dem das Wallet gehört (oder auf die eigene uid des Empfängers), herabgehen kann, um taler-wallet-cli auszuführen.

pepsi-stage-auto-pay

2550 pepsi:pepsi-wallets

Setgid, damit der pepsi-Worker den obigen Helper ausführen darf.

pepsi-stage-relay-to-smarthost

2550 pepsi:pepsi-token

Setgid, damit der pepsi-Worker die pepsi-token-Geheimnisse lesen darf; nicht für alle ausführbar, da die Stage -c akzeptiert und diese Geheimnisse sonst an jeden Server senden würde, den ein lokaler Benutzer nennt.

pepsi-whitelist

4755 pepsi-whitelist:pepsi-whitelist

Setuid und absichtlich für alle ausführbar: Jeder lokale Benutzer darf seinen eigenen <login>/…-Namensraum verwalten, und die Regel, die ihn vom Namensraum anderer fernhält, steckt im Programm, nicht im Dateimodus.

pepsi-stage-encrypt, pepsi-stage-decrypt

4750 pepsi-crypto:pepsi

Setuid, nicht setgid: Die Peer-Authentifizierung von PostgreSQL richtet sich nach der effektiven uid, und pepsi-crypto ist die einzige Rolle, der crypto_identity.private_wrapped gewährt ist. Modus 4750 mit Gruppe pepsi, weil dies keine Benutzerbefehle sind — nur das Konto des Dispatchers und root dürfen sie ausführen.

Jedes andere Binärprogramm wird unprivilegiert installiert, einschließlich pepsi-keys, das aus denselben Gründen eigenständig ist, aber mit 0755 ausgeliefert wird: Ein Binärprogramm, das jeden privaten Schlüssel einer Installation öffnen kann, ist eine weit größere Beute als die eine Tabelle von pepsi-whitelist, sodass es setuid pepsi-crypto zu machen eine Entscheidung je Standort ist statt der Standardwert.

3.8.4. Verzeichnisse und Geheimnisse

pepsi-setup und das Paket legen Folgendes unter /var/pepsi (dem Dienst-Home) und /etc/pepsi an. Die setgid-Verzeichnisse (2750) bewirken, dass neue Dateien die Gruppe des Verzeichnisses erben, sodass Token-/TLS-/Kerberos-Material vom Relay gruppenlesbar ist, ohne dass pro Datei ein chgrp nötig wäre.

Pfad

Eigentümer / Modus

Inhalt

/var/pepsi

pepsi-owner:pepsi

Dienst-Home.

/var/pepsi/keys

pepsi-owner:pepsi 2750

Domainspezifische private DKIM-Schlüssel: von pepsi-setup geschrieben, vom pepsi-Dispatcher (Gruppe pepsi) zum Signieren gelesen.

/var/pepsi/tokens

pepsi-helper-token-refresh:pepsi-token 2750

OAuth-Zugriffstoken-Dateien: vom Refresher geschrieben, vom Smarthost-Relay über die Gruppe pepsi-token gelesen.

/var/pepsi/token-refresh

pepsi-helper-token-refresh 0700

Private, rotierte Refresh-Token; niemals gruppenlesbar.

/etc/pepsi/secrets

root:pepsi-helper-token-refresh 0750

Die @inline-secret@-Token-Refresh-Zugangsdaten; nur der Refresher darf sie lesen.

/etc/pepsi/secrets.d

root:root 0751

Die Fragmente, die pepsi-setup erzeugt: den SRS-Schlüssel, Smarthost-/LMTP-Passwörter, Händler- und Resume-Token, den Herkunftsnachweis-Schlüssel und den Schlüsselverschlüsselungsschlüssel für pepsi-crypto. Für alle durchsuchbar (nicht lesbar), damit jeder Dienst das eine Fragment erreicht, das er öffnen darf; die Fragmente selbst sind 0640 und gehören ihrem einzigen lesenden Konto. pepsi-setup legt das Verzeichnis an, falls es fehlt.

/var/pepsi/tls

root:pepsi-token 2750

Mutual-TLS-Client-Zertifikat + -Schlüssel für das Smarthost-Relay (TLS_CLIENT_CERT / TLS_CLIENT_KEY).

/var/pepsi/krb5

root:pepsi-token 2750

Kerberos-Credential-Cache für AUTH = gssapi-Smarthosts (richten Sie KRB5CCNAME hier auf einen FILE:-Cache; ein externer Keytab-Refresher befüllt ihn).

/run/pepsi

root:root 0775 + ACL

Die Sockets für lokale Einlieferung, Administration, HTTP und den Setup-Applier. Angelegt vom tmpfiles.d-Snippet, dessen ACL pepsi-ingress und pepsi-httpd namentlich Schreibzugriff gewährt.

/var/lib/pepsi-wallets

pepsi-wallets:pepsi-wallets 0700

Home des Kontos pepsi-wallets und die Wallet-Datenbanken, die pepsi-helper-auto-pay darunter anlegt (wallets/<key>.sqlite3, Modus 0700). Nur mit pepsi-stage-auto-pay in WALLET_MODE = shared.

Die Verzeichnisse /var/pepsi/tokens, /var/pepsi/tls und /var/pepsi/krb5 (und das pepsi-helper-token-refresh-Konto) sind nur relevant, wenn Sie einen Smarthost mit dem entsprechenden AUTH-Mechanismus konfigurieren; eine standardmäßige Direkt-zu-MX- oder lokale-Zustellungs-Installation verwendet keines davon.

3.9. Von GNU Mailman migrieren

Eine bestehende GNU-Mailman-Installation – 2.1 oder 3 – zieht mit pepsi-list import und pepsi-archive import auf Pepsi um. Lesen Sie die Tabelle unten, bevor Sie anfangen, nicht danach.

Die Verhaltensunterschiede sind eine andere Tabelle, und sie wird hier nicht wiederholt: Erklärte Unterschiede zu GNU Mailman 3 in Mailinglisten sammelt jede Stelle, an der Pepsi absichtlich etwas anderes tut als upstream – die Ein-Klick-Abmeldung, das immer empfängerweise Fan-out, die verschleierten Absenderadressen im Archiv, den Löschgrabstein, die umbenannten X-Mailman-*-Header und das, was einfach fehlt (kein NNTP-Gateway, keine einsteckbaren Archivierer, keine Plugin-API). Zwei Kopien dieser Tabelle würden auseinanderlaufen, und die Kopie, die ein migrierender Betreiber zufällig liest, wäre die veraltete. Dieser Abschnitt handelt nur davon, was der Importer zurücklässt.

3.9.1. Was nicht mitkommt und warum

Warum

Passwörter

Weder die sha512_crypt-Hashes von Mailman-Core noch die pbkdf2_sha256-Hashes von Django aus mailman-web werden importiert. Der eigene Importer von upstream hat den Code, und er ist auskommentiert. Deshalb muss der Importer die Django-Datenbank überhaupt nie lesen, und deshalb gibt es nirgends in Pepsi einen Prüfer für Altlast-Hashes. Bestätigte Adressen bleiben bestätigt, niemand belegt also eine Adresse erneut – es wird nur ein Passwort gewählt, und dafür ist pepsi-list invite da.

Bounce-Punktestände

Upstream importiert sie ebenfalls nicht: das bounce_info aus config.pck und die Bounce-Ereignisse von Mailman 3 werden beide verworfen, ein migriertes Mitglied beginnt also auf beiden Systemen bei Punktestand null.

Token in Bearbeitung

Ein anstehendes Bestätigungs- oder Moderationstoken ist ein Versprechen über einen Ablauf, den es nach der Umstellung nicht mehr geben wird. Wer mitten in einem Abonnement steckt, fragt erneut.

Topics (2.1)

Kein Gegenstück in Mailman 3.

Vorlagen-URIs, die wir nicht abrufen

Eine file:-Überschreibung würde die eigene Platte des Servers lesen und wird daher nicht importiert. Der Importer meldet jede solche URI zur Importzeit, statt die erste Benachrichtigung, die sie braucht, Monate später scheitern zu lassen, und die Liste fällt auf die eingebaute Vorlage zurück.

Alles Weitere, was der Importer nicht verstanden hat, steht in seinem Bericht. Er endet mit einem Fehlerstatus, wenn etwas verloren ging, und das ist der Sinn: eine Migration, die halb funktionierte und mit Null endete, ist eine Migration, die niemand prüft. Nichts wird zurückgerollt, und einen Import erneut auszuführen ist gefahrlos – jeder Schreibvorgang hängt an der Listen-ID, der Adresse oder der Message-ID, ein zweiter Lauf ist also eine Leeroperation.

3.9.3. Wenn unser Pickle-Leser strenger ist als ihrer

pepsi-list import mailman21 liest config.pck mit einem eigenen Parser, der nichts konstruiert: kein Modul wird nachgeschlagen und kein Aufrufbares aufgerufen, denn eine config.pck kommt vom Server eines anderen, und Pythons pickle.load auf nicht vertrauenswürdiger Eingabe ist das Ausführen beliebigen Codes.

Der Preis dafür ist Strenge. Weigert sich der Leser bei einer Datei – ein Opcode, den er nicht implementiert, ein Protokoll neuer als das, was Python 2 schreiben konnte, eine Ganzzahl zu breit für 64 Bit –, dann sagt er das und nennt die Notluke:

python2 contrib/mm21-export.py /var/lib/mailman/lists/announce/config.pck \
    > /root/announce.json
pepsi-list import mailman21 --json /root/announce.json --list announce

Dieses Skript läuft auf dem alten Server, mit dem Python, dem dieser Server ohnehin vertraute, und schreibt dasselbe Wörterbuch als JSON aus. Beide Wege gehen danach durch dieselbe Zuordnung, sie können sich also nicht darüber uneinig sein, was die Datei bedeutet. Eine Migration darf nie daran scheitern, dass unser Parser strenger ist als der, der die Datei geschrieben hat.

3.9.4. Header-Umbenennungen, die ein Benutzer bemerkt

Pepsi gibt X-Pepsi-List-* aus, wo Mailman X-Mailman-* ausgab; die Zuordnungstabelle steht in Mailinglisten. Das sind die echten Kosten eines migrierenden Benutzers, denn procmail- und Sieve-Regeln sind gegen diese Namen geschrieben, und es lohnt sich, es ihnen vor dem Wechsel zu sagen und nicht danach.