Files
PostfixAdminRS/README.md
T
2026-11-03 16:52:28 +01:00

11 KiB

PostfixAdmin-RS

Rustowy panel administracyjny dla Postfix/Dovecot, rozwijany jako zamiennik runtime PHP PostfixAdmin i zgodny z jego istniejaca baza danych.

Aktualna linia developerska: 0.0.1-dev. Projekt jest przypiety do Rust 1.99.1, edition 2024. Frontend jest osadzony w pojedynczym binarnym pliku; bundlowanie assetow, sprite SVG i workflow developerski sa wzorowane na przekazanym RustBox. Stary wyglad PostfixAdmin nie jest kopiowany.

Development bez produkcyjnej bazy

Domyslny dev.sh nie potrzebuje MySQL/PostgreSQL. Uzywa izolowanego SQLite w .dev/postfixadmin-rs.sqlite i przy pierwszym starcie tworzy mock schematu PostfixAdmin z danymi testowymi:

bash dev.sh

Konta testowe:

admin@example.test         / admin123   # global-admin
domain-admin@example.test  / domain123  # admin example.test
user@example.test          / user123    # mailbox user

Reset mock DB oraz developerskiego mocka Rspamd DKIM:

POSTFIXADMIN_RS_DEV_RESET=1 bash dev.sh

database.dev_mock=true jest dozwolone tylko z environment="development" i backendem SQLite. Produkcyjna baza nie jest potrzebna do pracy nad UI/API.

Jesli chcesz testowac bezposrednio na produkcyjnej bazie przez SSH, dev.sh moze zestawic lokalny tunnel. Domyslnie taka sesja jest read-only. Najprosciej skopiowac gotowy przyklad dla host.linuxiarz.pl:

cp .env.example .env
$EDITOR .env
bash dev.sh

W .env uzupelnij co najmniej POSTFIXADMIN_RS_DEV_DB_PASSWORD. Przyklad jest dopasowany do testowego hosta: root@host.linuxiarz.pl:11922, MySQL/MariaDB, baza postfix, uzytkownik DB postfix i lokalny port tunelu 13306.

Domyslny forward dla MySQL to 127.0.0.1:13306 -> 127.0.0.1:3306, a dla PostgreSQL 127.0.0.1:15432 -> 127.0.0.1:5432. Mozesz zmienic host/port po stronie serwera przez POSTFIXADMIN_RS_DEV_DB_HOST i POSTFIXADMIN_RS_DEV_DB_PORT. Weryfikacja host key SSH pozostaje wlaczona. Tunel uzywa BatchMode=yes, wiec przygotuj klucz/ssh-agent; opcjonalnie ustaw POSTFIXADMIN_RS_SSH_IDENTITY lub POSTFIXADMIN_RS_SSH_KNOWN_HOSTS.

Zapisy na produkcyjnej bazie wymagaja dodatkowego, jawnego opt-in:

POSTFIXADMIN_RS_DEV_DB_MODE=ssh POSTFIXADMIN_RS_DEV_DB_WRITES=1 bash dev.sh

W tym trybie aplikacja moze modyfikowac realne skrzynki/aliasy. Do zwyklych testow UI i odczytu schematu nie ustawiaj POSTFIXADMIN_RS_DEV_DB_WRITES=1.

Co jest gotowe

  • logowanie admin/mailbox, sesje HttpOnly/SameSite, CSRF i rate limit,
  • global-admin, domain-admin i mailbox user,
  • domeny, skrzynki, aliasy, alias-domains i masowe usuwanie nieaktywnych forwardow,
  • limity domen, quota/domain quota, transport, backup MX i self-alias,
  • fetchmail, vacation/autoreply zgodny z tabela vacation, log, sendmail/broadcast i backup DB,
  • panel mailbox-user: wlasna quota/usage z DB, dane skrzynki, self-alias, bez odczytu IMAP,
  • opcjonalny ManageSieve dla mailbox-user: lista/edycja/walidacja/aktywacja skryptow filtrow, prosty wizualny builder reguly + edytor raw, bez IMAP,
  • admin preferences (m.in. domyslny cel aliasu),
  • DKIM keys/signing, TOTP, TOTP exceptions, application passwords,
  • Rspamd DKIM: generowanie kluczy, selector/path maps, configtest, podpinanie istniejacych kluczy i opcjonalny reload,
  • smtp_active, password expiration i DNS status, gdy schema je udostepnia,
  • bezpieczny natywny maildir_template zamiast PHP maildir_name_hook,
  • automatyczne subfoldery przez doveadm mailbox create, jesli lista jest skonfigurowana,
  • MySQL/MariaDB, PostgreSQL i SQLite przez SQLx Any,
  • hooki wykonywane jako program + argumenty, bez sh -c,
  • UI EN/PL z English jako domyslnym jezykiem; wybor z interfejsu jest zapamietywany w przegladarce, API pozostaje po angielsku.

Pelna macierz: COMPATIBILITY.md. Audyt 1:1 wobec dostarczonego PHP 4.0.1: PORT-PARITY.md.

Mailbox user, Vacation i ManageSieve

Panel zwyklego uzytkownika nie pokazuje administracyjnej listy modulow ani cudzych skrzynek. Overview pobiera tylko rekord zalogowanej skrzynki i jej self-alias. Quota/usage pochodzi z tabel PostfixAdmin/Dovecot (mailbox, opcjonalnie quota/quota2); aplikacja nie loguje sie do IMAP, zeby zbudowac ten widok.

Vacation pozostaje zgodny z PostfixAdmin: korzysta z tabeli vacation i ustawien features.vacation / features.vacation_control. Samo wlaczenie UI nie konfiguruje transportu/autorespondera po stronie Postfix/Dovecot, dlatego na istniejacym serwerze wlacz te flagi tylko wtedy, gdy mechanizm Vacation jest faktycznie skonfigurowany.

ManageSieve jest dodatkiem niezaleznym od mechanizmu Vacation PA. Konfiguracja:

[sieve]
enabled = true
host = "127.0.0.1"
port = 4190
tls_mode = "starttls" # starttls | implicit | none
allow_insecure_auth = false
timeout_secs = 10
read_only = false

Haslo mailbox-user jest przechowywane tylko w pamieci jego sesji, i tylko gdy Sieve jest wlaczone; nie trafia do JSON API ani logow. Po zmianie hasla credential sesji jest aktualizowany. Dla developerskiego testu przez SSH mozna wlaczyc drugi forward tym samym dev.sh:

POSTFIXADMIN_RS_DEV_SIEVE_ENABLED=true bash dev.sh

Domyslnie zewnetrzny ManageSieve przez dev tunnel jest read-only. Zapis wymaga osobnego POSTFIXADMIN_RS_DEV_SIEVE_WRITES=1; jest to niezalezne od POSTFIXADMIN_RS_DEV_DB_WRITES.

Hasla zgodne z PostfixAdmin

Weryfikacja najpierw rozpoznaje format juz zapisany w rekordzie. Dzieki temu jedna baza moze zawierac stare i nowe hashe podczas migracji, bez masowego przepisywania kont.

Obslugiwane sa m.in.:

  • ARGON2ID, ARGON2ID.B64, ARGON2I, ARGON2I.B64,
  • BLF-CRYPT, BLF-CRYPT.B64, CRYPT,
  • SHA512-CRYPT, SHA512-CRYPT.B64, legacy SHA512.B64, SHA512,
  • SHA256-CRYPT, SHA256-CRYPT.B64, SHA256,
  • SHA1-CRYPT, SHA1, SHA1.B64, SHA, SSHA,
  • MD5-CRYPT, legacy md5crypt, PLAIN-MD5, MD5, MD5RAW,
  • AUTHLIB (md5raw, md5, SHA, crypt),
  • courier:md5, courier:md5raw, courier:sha1, courier:ssha, courier:sha256,
  • php_crypt:DES|MD5|BLOWFISH|SHA256|SHA512 z kompatybilnym difficulty/prefix,
  • dovecot:METHOD jako kontrolowany fallback do doveadm pw, bez shella i bez hasla w argv,
  • PLAIN, CLEAR, cleartext tylko dla zgodnosci/testow.

Testy zawieraja referencyjne wektory z dostarczonego tests/PacryptTest.php. Slabe formaty pozostaja tylko dla kompatybilnosci; nowych kont nie nalezy na nie migrowac bez potrzeby.

Dla przekazanego configu produkcyjnego pozostaje php_crypt:MD5, dopoki konfiguracja Dovecot/Postfix SASL nie zostanie zmieniona razem z panelem.

Konfiguracja przekazanego serwera

config.from-user.toml odwzorowuje przekazany config PostfixAdmin, ale nie zawiera hasla bazy. Sekret podaj przez ENV:

export POSTFIXADMIN_RS_CONFIG="$PWD/config.from-user.toml"
export POSTFIXADMIN_RS__DATABASE__PASSWORD='...'

Jezyki interfejsu

Frontend ma katalogi src/web/i18n/en.json i src/web/i18n/pl.json. default_language = "en" ustawia English jako pierwszy jezyk, a przelacznik w loginie i gornej belce zapisuje wybor w localStorage. Lokalizacja dotyczy tylko UI; endpointy, JSON i kody bledow API pozostaja angielskie.

Build / release gate

./scripts/build-release.sh

Gate wykonuje walidacje statyczna, cargo fmt --check, testy, Clippy z -D warnings i release build z Cargo.lock.

Migracja z PHP

  1. Zrob backup bazy i konfiguracji Postfix/Dovecot/PostfixAdmin.
  2. Najpierw testuj na kopii DB lub na mocku developerskim.
  3. Na realnej DB uruchom --check-config, sprawdz logowanie i CRUD na domenie testowej.
  4. Nie zmieniaj password.scheme, dopoki Dovecot/Postfix SASL nie obsluguje tego samego formatu.
  5. Reverse proxy przelacz dopiero po testach regresyjnych; PHP/FPM usun na koncu.

Status 0.0.1-dev

To nadal wersja developerska, nie deklaruje jeszcze 100% parity PostfixAdmin 4.x. Pozostale luki to przede wszystkim webowy setup/upgrade schematu, XML-RPC, SMS provider, update checker oraz generic IMAP/Courier do tworzenia folderow. Dynamiczne hooki PHP (*_struct_hook, language_hook) nie beda uruchamiane jako PHP — wymagaja natywnego mechanizmu rozszerzen.

W tym srodowisku nie ma cargo/rustc; proba pobrania toolchaina 1.99.1 jest dodatkowo blokowana przez brak DNS/network, wiec realny cargo check/test/clippy nie mogl zostac wykonany tutaj. Statyczny gate jest uruchamiany przed spakowaniem, ale developerski build trzeba ostatecznie zweryfikowac przez bash dev.sh na maszynie z Rust 1.99.1. Checklista testowa: TESTING.md.

Rspamd DKIM

Integracja Rspamd nie rozbudowuje recznie domain { ... }. Uzywa map selector_map i path_map, generuje klucze przez rspamadm, wykonuje rspamadm configtest przed zaakceptowaniem zmian i moze wykonac jawnie skonfigurowany argv-only reload. Instrukcja: docs/RSPAMD_DKIM.md.

DKIM backends

The UI exposes PostfixAdmin database DKIM and Rspamd DKIM as separate backends. They can be enabled independently:

[features]
dkim = true

[dkim]
default_backend = "postfixadmin" # postfixadmin | rspamd

[rspamd_dkim]
enabled = true

When both are enabled, dkim.default_backend selects the tab opened first. Disabling one backend removes that tab from the UI.

Mailbox users can optionally see DKIM as a read-only DNS view for their own domain ([dkim].user_read_only = true). The view merges only public records from the PostfixAdmin DKIM tables and Rspamd. default_backend is only a UI preference for administrators; there is no shared/global DKIM key in this project. Every key/selector remains associated with a concrete domain.

When development uses the SSH database mode, dev.sh also forwards ManageSieve (14190 -> 4190) and, by default, builds a public-only Rspamd DKIM cache over SSH. The helper reads mapping/config metadata and derives the public key on the mail host; it never downloads private-key bytes. Disable this with POSTFIXADMIN_RS_DEV_RSPAMD_PUBLIC_SYNC=false.

Domain-focused UI

Domains is the main entry point for domain administration. Clicking a domain opens a workspace with mailbox and alias usage, quota progress, mailboxes, aliases and alias-domain relationships. The standalone Mailboxes and Aliases pages show one domain at a time instead of rendering all domains at once.

Local Debian package

For Debian-like systems, build a development .deb inside Docker:

./scripts/build-deb.sh

The builder uses Debian 12 as the compatibility baseline, installs the Rust toolchain pinned by rust-toolchain.toml, runs static validation, cargo fmt --check, tests and clippy, then writes the package and SHA256 file to ./packages/. The resulting package installs the binary, a systemd service, /etc/postfixadmin-rs/config.toml and /etc/default/postfixadmin-rs. During installation it creates the unprivileged system user/group postfixadmin, runs the service as that identity, keeps /etc/postfixadmin-rs root-owned with group-read access for postfixadmin, and creates /var/lib/postfixadmin-rs for runtime state. It does not start the service automatically because database/Rspamd permissions must be configured first. Rspamd DKIM integration must be granted narrowly scoped write access to the configured key/map/config paths; do not run the whole service as root.