142 lines
7.7 KiB
Markdown
142 lines
7.7 KiB
Markdown
# PostfixAdmin-RS
|
||
|
||
Panel administracyjny serwera poczty Postfix/Dovecot napisany w Rust — zamiennik
|
||
PHP-owego [PostfixAdmin](https://github.com/postfixadmin/postfixadmin), działający
|
||
na **tej samej bazie danych** (MySQL/MariaDB, PostgreSQL, SQLite). Postfix, Dovecot,
|
||
`vacation.pl` i `fetchmail.pl` korzystają z tabel dokładnie tak jak przy PHP-owym
|
||
PostfixAdminie, więc panel można podmienić bez migracji danych.
|
||
|
||
Wersja: **0.1.0** · referencja logiki: PostfixAdmin 4.0.5 + gałąź `master` (schemat bazy 1857).
|
||
|
||
Jeden statyczny plik binarny z wbudowanym interfejsem (EN/PL, jasny/ciemny motyw,
|
||
działa na telefonie), bez PHP, bez serwera aplikacji, bez zależności w runtime.
|
||
|
||
## Funkcje
|
||
|
||
| Obszar | Zachowanie |
|
||
|---|---|
|
||
| Domeny | limity aliasów/skrzynek (`-1` = wyłączone, `0` = bez limitu), quota domeny i maks. quota skrzynki, transport, backup MX, wygasanie haseł, status DNS, domyślne aliasy przy tworzeniu, kasowanie domeny z wszystkimi danymi |
|
||
| Lista wirtualna | widok domeny jak `list-virtual.php`: domeny aliasowe, aliasy, skrzynki, wyszukiwanie, stronicowanie, filtr aktywne/nieaktywne, przełączanie aktywności jednym kliknięciem, „usuń nieaktywne”, statusy (niedostarczalny, zewnętrzny, autoresponder, wyłączona, hasło wygasło, POP/IMAP) |
|
||
| Skrzynki | reguły quota identyczne z `MailboxHandler::check_quota()`/`allowed_quota()` (podpowiedź „maks. N MB” w formularzu), generowanie hasła, potwierdzenie hasła, SMTP on/off, e-mail do odzyskiwania, wiadomość powitalna (w tle), maildir zgodny z `domain_path`/`domain_in_mailbox`, hooki po utworzeniu/edycji/usunięciu/zmianie hasła |
|
||
| Przekierowania | alias skrzynki („przekaż i zachowaj”), z uprawnieniami `alias_control` / `alias_control_admin` / `edit_alias` jak w PostfixAdminie |
|
||
| Aliasy | catch-all (`*` → `@domena`), przekierowanie całej domeny, konto lokalne (`root`), blokada aliasu wskazującego na siebie, `emailcheck_localaliasonly`, chronione aliasy domyślne (`special_alias_control`), zapamiętany domyślny cel |
|
||
| Domeny aliasowe | z ochroną przed łańcuchami i pętlami |
|
||
| Administratorzy | globalni i domenowi, przypisanie domen, aktywacja, reset hasła |
|
||
| Autoresponder | tabela `vacation` + alias transportu `user#domena@vacation_domain`, data i godzina od/do, `vacation_choice_of_reply`, czyszczenie `vacation_notification` |
|
||
| Panel użytkownika | podgląd skrzynki i quota, przekierowania, autoresponder, zmiana hasła, zmiana nazwy (`edit_mailbox_name`), 2FA, hasła aplikacji, filtry Sieve |
|
||
| Bezpieczeństwo | TOTP + wyjątki IP, hasła aplikacji, odzyskiwanie hasła e-mailem, limit prób logowania per IP/konto, CSRF, ciasteczka `HttpOnly`/`SameSite=Strict`/`Secure`, nagłówki CSP/HSTS, wylogowanie innych sesji po zmianie hasła, rewalidacja sesji (wyłączone konto lub odebrane uprawnienia działają natychmiast) |
|
||
| Inne | fetchmail (hasło base64 jak w PostfixAdmin), dziennik zmian z filtrem domen i stronicowaniem, wysyłanie poczty / wiadomość do wszystkich, kopia zapasowa bazy, DKIM (tabele PostfixAdmin/OpenDKIM oraz Rspamd), ManageSieve |
|
||
| Hasła | wszystkie formaty PostfixAdmin (ARGON2ID/I, BLF-CRYPT, SHA512-CRYPT, MD5-CRYPT, `php_crypt:*`, `md5crypt`, SSHA, Courier, Authlib, `dovecot:*` …) — format zapisany w rekordzie ma pierwszeństwo, więc stare i nowe hashe mogą współistnieć |
|
||
|
||
Szczegółowe porównanie z PHP: [PORT-PARITY.md](PORT-PARITY.md).
|
||
|
||
## Instalacja produkcyjna
|
||
|
||
### 1. Budowanie
|
||
|
||
```bash
|
||
cargo build --release --locked # wynik: target/release/postfixadmin-rs
|
||
# albo pakiet Debiana (w Dockerze):
|
||
./scripts/build-deb.sh # wynik: packages/postfixadmin-rs_*.deb
|
||
```
|
||
|
||
### 2. Konfiguracja
|
||
|
||
```bash
|
||
install -d -m 0750 -g postfixadmin /etc/postfixadmin-rs
|
||
install -m 0640 -g postfixadmin config.example.toml /etc/postfixadmin-rs/config.toml
|
||
$EDITOR /etc/postfixadmin-rs/config.toml
|
||
```
|
||
|
||
Najważniejsze ustawienia:
|
||
|
||
- `[database]` – dane bazy używanej przez Postfix/Dovecot. Hasło można podać w
|
||
`/etc/default/postfixadmin-rs` jako `POSTFIXADMIN_RS__DATABASE__PASSWORD=...`.
|
||
- `[password] scheme` – **musi** odpowiadać temu, co obsługuje Dovecot
|
||
(`default_pass_scheme`). Dla nowych instalacji: `ARGON2ID` lub `SHA512-CRYPT`.
|
||
- `[defaults] vacation_domain` – domena transportu autorespondera z `master.cf`.
|
||
- `[security]` – za nginx ustaw `trusted_proxies = ["127.0.0.1", "::1"]`,
|
||
`cookie_secure = true`, `hsts = true`.
|
||
|
||
### 3. Baza danych
|
||
|
||
```bash
|
||
export POSTFIXADMIN_RS_CONFIG=/etc/postfixadmin-rs/config.toml
|
||
postfixadmin-rs --init-schema --dry-run # co zostałoby zmienione
|
||
postfixadmin-rs --init-schema # tworzy brakujące tabele/kolumny/indeksy
|
||
postfixadmin-rs --create-superadmin admin@example.com # hasło ze stdin lub POSTFIXADMIN_RS_ADMIN_PASSWORD
|
||
postfixadmin-rs --check-config
|
||
```
|
||
|
||
`--init-schema` zastępuje `setup.php`/`upgrade.php`: na pustej bazie tworzy pełny
|
||
schemat PostfixAdmin (wersja 1857), na istniejącej tylko dodaje brakujące elementy —
|
||
nigdy niczego nie usuwa. Jest idempotentne.
|
||
|
||
### 4. Usługa i reverse proxy
|
||
|
||
```bash
|
||
install -m 0644 packaging/postfixadmin-rs.service /etc/systemd/system/
|
||
systemctl daemon-reload && systemctl enable --now postfixadmin-rs
|
||
```
|
||
|
||
Przykład nginx z TLS, HSTS i limitem logowań: [packaging/nginx.conf.example](packaging/nginx.conf.example).
|
||
Aplikacja nasłuchuje tylko na `127.0.0.1:8080`; publicznie wystawiony jest wyłącznie nginx.
|
||
|
||
### 5. Zadania okresowe (opcjonalnie)
|
||
|
||
```cron
|
||
# odświeżanie statusu DNS domen (odpowiednik scripts/domain-dns-check.php)
|
||
17 3 * * * postfixadmin POSTFIXADMIN_RS_CONFIG=/etc/postfixadmin-rs/config.toml /usr/bin/postfixadmin-rs --refresh-dns
|
||
```
|
||
|
||
## Migracja z PHP PostfixAdmin
|
||
|
||
1. Kopia zapasowa bazy oraz konfiguracji Postfix/Dovecot/PostfixAdmin.
|
||
2. Przenieś ustawienia z `config.local.php` do `config.toml`
|
||
(`$CONF['encrypt']` → `password.scheme`, `$CONF['vacation_domain']`, `default_aliases`, limity, `quota_multiplier` …).
|
||
Przykład odwzorowania: [config.from-user.toml](config.from-user.toml).
|
||
3. `postfixadmin-rs --init-schema --dry-run`, a potem bez `--dry-run`
|
||
(dodaje tylko brakujące kolumny nowszych wersji PostfixAdmin).
|
||
4. Uruchom panel równolegle (inny vhost), sprawdź logowanie, listy i jedną domenę testową.
|
||
5. Przełącz reverse proxy, a PHP/FPM wyłącz na końcu.
|
||
|
||
Konta administratorów i skrzynek oraz ich hasła działają bez zmian.
|
||
|
||
## Polecenia
|
||
|
||
```
|
||
postfixadmin-rs uruchamia serwer
|
||
postfixadmin-rs --check-config sprawdza konfigurację, połączenie i schemat
|
||
postfixadmin-rs --init-schema tworzy/aktualizuje schemat (--dry-run: tylko raport)
|
||
postfixadmin-rs --integrity-check osierocone rekordy (tylko odczyt)
|
||
postfixadmin-rs --create-superadmin EMAIL
|
||
postfixadmin-rs --refresh-dns odświeża status DNS wszystkich domen
|
||
postfixadmin-rs --version | --help
|
||
```
|
||
|
||
## Rozwój
|
||
|
||
```bash
|
||
bash dev.sh # izolowana baza SQLite z danymi testowymi
|
||
POSTFIXADMIN_RS_DEV_RESET=1 bash dev.sh
|
||
```
|
||
|
||
Konta testowe: `admin@example.test / admin123` (globalny), `domain-admin@example.test / domain123`
|
||
(admin `example.test`), `user@example.test / user123` (skrzynka). Tryb SSH do prawdziwej bazy
|
||
(domyślnie tylko do odczytu) opisuje `.env.example`.
|
||
|
||
Testy:
|
||
|
||
```bash
|
||
cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test
|
||
python3 scripts/api-smoke.py http://127.0.0.1:8080 admin@example.test admin123 # test API na działającej instancji
|
||
python3 scripts/i18n/build.py # przebudowa katalogu PL + kontrola brakujących tłumaczeń
|
||
```
|
||
|
||
Interfejs jest w `src/web` (zwykły JS/CSS, wbudowywany przez `build.rs`); teksty źródłowe
|
||
są po angielsku, tłumaczenia polskie w `scripts/i18n/pl_messages.py`.
|
||
|
||
## Licencja
|
||
|
||
GPL-2.0-or-later, jak PostfixAdmin. Zob. [LICENSE](LICENSE) i [NOTICE.md](NOTICE.md).
|