.. This file is part of PEPSI. Copyright (C) 2026 GNUnet e.V. PEPSI is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. =========== pepsi-setup =========== *Provision the database, signing keys and DNS for a deployment.* Role ==== ``pepsi-setup`` is the administrative bootstrap tool. In one invocation it validates the configuration, installs the schema, generates signing keys and prints the DNS records to publish; a separate ``check`` verifies live DNS. References: :manpage:`pepsi-setup(1)` / :manpage:`pepsi.conf(5)`. Features ======== * **Configuration validation.** Parses ``[pepsi]``, ``[pepsi-ingress]`` and the ``[stage-*]`` pipeline; checks that ``[stage-init]`` exists, that every ``NEXT_STAGE``/``BOUNCE_STAGE`` resolves, that each stage's program configuration (including smarthost routing) parses, and that domains and ``PUBLIC_IP`` values are well-formed. On any error it changes **nothing** and exits non-zero. * **TLS certificate provisioning.** For every TLS-terminating listener/cert section that has no ``TLS_CERT``/``TLS_KEY``, it fills in the standard **certbot** path layout (rewriting the config file in place, comments preserved) and then runs ``certbot certonly --standalone`` to obtain any certificate not yet on disk (or to widen one that no longer covers every name). Pass ``--no-certbot`` to skip the certbot call and manage certificates yourself. A certificate that is missing and cannot be obtained is *deferred*, not fatal: the rest of the run proceeds and the end-of-run summary says what is left to do. * **TLS access provisioning.** The servers run as unprivileged users, while certbot keeps ``/etc/letsencrypt`` root-only. Under systemd, ``pepsi-setup`` writes a ``LoadCredential=`` drop-in per unit so systemd reads each certificate and key as root at unit start and hands the service a private copy — the file permissions then do not matter at all. It also grants POSIX ACLs and installs a certbot deploy hook (which re-grants *and* restarts the servers, so a renewed certificate is actually served), and finally verifies — by becoming the service user and opening the file — that anything left over really is readable. * **Schema installation.** The sole installer of the single ``pepsi`` schema: applies the numbered patch series and the re-creatable procedures from ``SQL_DIR``; idempotent and re-runnable. It records what it applied, by content hash, so every program can refuse a schema from another release, and it refuses to install over a newer schema itself (see :ref:`upgrading`). ``run --reset`` drops and recreates the schema (destroying queued mail; on-disk keys are kept). * **Key generation.** For every domain Pepsi is authoritative for — the union of ``ACCEPTED_DOMAINS``, each stage's ``SERVER_NAME``/``POSTMASTER`` domain, any explicit ``SIGNING_DOMAIN``, ``SRS_DOMAIN`` or fixed ``RESPONSE_FROM``, and ``ARC_DOMAIN`` — creates an **RSA-2048** and an **Ed25519** (RFC 8463) DKIM key under ``KEY_DIR`` (mode 0600 in 0700 dirs) if absent; existing keys are never overwritten. * **DNS record output.** Prints, in BIND zone format, the DKIM public keys (``._domainkey`` and ``-ed25519._domainkey``), an **SPF** policy built from the ``PUBLIC_IP`` of every relay stage (unioned), a **DMARC** suggestion where none is published, an **MTA-STS** ``_mta-sts`` TXT record (RFC 8461), a **TLSRPT** record when ``[pepsi-tlsrpt] RUA`` is set, and **DANE/TLSA** records for the TLS listeners. Records already published with the right value are left out. The policy file itself is served by :doc:`pepsi-httpd`, not printed. Long RSA records are split into multiple character-strings. The same SPF record is suggested for every served domain; the output notes that special multi-host setups may prefer a tighter, still-correct per-domain grouping, which pepsi-setup does not compute automatically. * **Live DNS verification** (``check``): queries DNS and reports, per domain, whether the published DKIM ``p=`` matches the local key, the SPF record lists every ``PUBLIC_IP``, the DMARC record is valid, and the ``_mta-sts`` TXT is present and parseable; it also compares the MTA-STS policy with the live ``MX`` records and with what is actually served, and checks that the SRS domain can receive its bounces. Purely informational: its findings never set the exit status. * **Setup wizard** (``--wizard``): a short interactive interview that writes a complete, already-validated configuration file (to the ``--config`` path, or ``/etc/pepsi/pepsi.conf`` by default) and then offers to run the full setup. It imports a previous run's answers from the file's ``[pepsi-wizard]`` section; ``--force`` overwrites a file that has no such section without prompting. Use :doc:`pepsi-config` to inspect the effective configuration. Command-line options ==================== Run with no subcommand performs the full setup (the same as ``run``). Full detail is in :manpage:`pepsi-setup(1)`; the options are: Subcommands: * ``run`` — validate, provision TLS, install schema, generate keys, print DNS (the default action). ``-r``/``--reset`` first drops and recreates the schema (**destroys all queued mail**; on-disk keys are kept). * ``schema`` — install or upgrade the schema and the role grants, and nothing else; needs only ``[pepsi-postgres]``, so it also works with a telemetry collector's configuration file. Refuses a newer schema (exit status 78). ``--backup-dir`` *DIR* first saves the schema with ``pg_dump`` when there is something to upgrade; ``--if-installed`` does nothing on a database with no schema yet. This is what a package upgrade runs; see :ref:`upgrading`. * ``check`` — query live DNS and report mismatches; makes no changes, and its findings never set the exit status. * ``visualize`` — print the ``[stage-*]`` pipeline as a Graphviz ``dot`` graph on standard output (a solid edge per ``NEXT_STAGE``, a dashed red one per ``BOUNCE_STAGE``); pipe it into ``dot -Tpng``. * ``questions`` — print the setup interview as JSON: the steps, each question's shape, default, help text and when it is asked. It is the model both the terminal wizard and the browser setup are described by, and the schema an ``--answers`` file is written against. * ``apply`` — perform the privileged setup work the browser interface has asked for, reading intent rows from ``pepsi.setup_task``. Normally started on demand by systemd. ``--once`` drains what is pending and exits; ``--idle`` *SECS* sets how long it waits with nothing to do before exiting; ``--clear`` deletes every queued row **without executing any of them** (mutually exclusive with the other two). * ``bootstrap`` — mint and print the one-time bearer token that creates the first administrator account (``--valid-for`` *SECS*, ``--admin-url`` *URL*). * ``import`` [*MTA*] — report what would be migrated from an existing MTA (``postfix``, ``exim``, ``sendmail``, ``qmail``, ``stalwart``) without writing anything; ``--root`` reads from under another directory, ``--out`` writes the report and converted map files, ``--alias-style`` chooses how bare alias names are qualified. Options, which all come **before** the subcommand: * ``--no-certbot`` — do not invoke ``certbot`` for missing TLS certificates; they are deferred instead (see **TLS certificate provisioning** above). * ``--no-reverse-proxy`` — do not auto-integrate with an existing front HTTP server; let :doc:`pepsi-httpd` bind 443 directly. * ``-y``/``--yes-to-all``, ``-n``/``--no-to-all`` — answer every interactive offer the same way, so setup never blocks on input. * ``--wizard`` — run the interactive configuration wizard (does not require an existing configuration file); ``--force`` overwrites an un-importable file without prompting. With it: ``--expert`` *SPEC* also asks the deeper options (``--expert=help`` lists them), ``--import`` *MTA* / ``--no-import`` / ``--import-root`` *DIR* control the migration of an existing MTA's settings, and ``--answers`` *FILE* answers every question from JSON instead of asking. * ``-c``/``--config`` *FILE*, ``-L``/``--log`` *LEVEL*, ``-v``/``--verbose``, ``-h``/``--help``, ``-V``/``--version`` — the options shared by all Pepsi tools. Configuration ============= Reads the shared ``[pepsi]`` (``KEY_DIR``, ``DKIM_SELECTOR``, ``DKIM_ALGORITHMS``, ``ARC_DOMAIN``, ``ARC_ALGORITHM``, ``ORIGINATE_SUCCESS_DSN``, ``MTA_STS_MODE``, ``MTA_STS_MAX_AGE``), ``[pepsi-postgres]`` (``CONFIG``, ``SQL_DIR``), ``[pepsi-ingress]`` (``HOSTNAME``, ``ACCEPTED_DOMAINS``), and the ``[stage-*]`` sections — including each relay stage's ``PUBLIC_IP`` (collected by ``PROGRAM``). Full reference: :manpage:`pepsi.conf(5)`. See also ======== :doc:`../installation`, :doc:`../configuration`, :manpage:`pepsi-setup(1)`, :manpage:`pepsi.conf(5)`.