first commit

This commit is contained in:
Mateusz Gruszczyński committed 2026-11-05 12:52:32 +01:00
commit 19dfc51360
85 files changed
+25504

No files matched your search

+132
View File
@@ -0,0 +1,132 @@
# Installation
## Requirements
- Linux x86_64 (the `.deb` needs glibc >= 2.30: Debian 11+, Ubuntu 20.04+). No OpenSSL or PHP - TLS is
rustls and SQLite is built in.
- IMAP server (Dovecot recommended: `UIDPLUS`, `MOVE`, `SPECIAL-USE`, `CONDSTORE`, `UNSELECT`).
- SMTP submission (Postfix on 587 with SASL) or a local `sendmail`.
- Optional CalDAV/CardDAV.
- A TLS reverse proxy (nginx, RustProxy, Apache). ActivePush listens on `127.0.0.1` only by default.
## Debian package
```bash
./dev.sh deb # on the build machine (Rust stable; cargo-zigbuild makes it portable)
sudo apt install ./dist/active-push_*_amd64.deb
```
| Path | Content |
|---|---|
| `/usr/bin/active-push` | binary (server + CLI) |
| `/lib/systemd/system/active-push.service` | service with systemd sandboxing |
| `/etc/active-push/environment` | listen addresses, panel TLS, log level (conffile) |
| `/var/lib/active-push/active-push.db` | SQLite: settings, devices, states, statistics, audit (0600) |
| `/usr/share/doc/active-push/` | documentation and nginx examples |
| `/usr/share/active-push/zpush-import.py` | Z-Push configuration importer |
`postinst` creates the `active-push` system user and enables and starts the service. Upgrading the package
restarts the service (push connections are released and devices reconnect). `apt purge` also removes data.
### Portable builds
`scripts/build-deb.sh` uses `cargo zigbuild` with a glibc 2.31 baseline when it is installed
(`pip install ziglang && cargo install cargo-zigbuild`), otherwise a normal `cargo build`. The `libc6`
dependency is computed from the binary's symbols. `GLIBC_TARGET=0` forces a native build.
### First administrator
```bash
sudo -u active-push active-push admin setup-token # one-time token, valid 60 minutes
ssh -L 9091:127.0.0.1:9091 admin@server # from your workstation
# browser: http://127.0.0.1:9091 -> paste the token, choose login and password (min. 12 characters)
```
Without a browser: `sudo -u active-push active-push admin init --username admin`.
Lost password: `sudo -u active-push active-push admin reset-password` (revokes all sessions).
Always run CLI commands as `active-push`; the binary refuses to touch a data directory owned by another user.
## nginx
Replace the Z-Push fastcgi locations with the snippet from `deploy/nginx-active-push.conf`:
```nginx
location = /Microsoft-Server-ActiveSync {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3660s; # Ping holds the request for up to ~59 minutes
proxy_send_timeout 3660s;
proxy_buffering off;
client_max_body_size 64m;
}
location = /AutoDiscover/AutoDiscover.xml { include snippets/active-push-autodiscover.conf; }
location = /Autodiscover/Autodiscover.xml { include snippets/active-push-autodiscover.conf; }
location = /autodiscover/autodiscover.xml { include snippets/active-push-autodiscover.conf; }
# health check for monitoring / load balancers (no authentication, no data)
location = /activesync-healthz {
proxy_pass http://127.0.0.1:8081/healthz;
access_log off;
}
```
`snippets/active-push-autodiscover.conf` is `deploy/active-push-autodiscover.conf`.
**Important:** `X-Forwarded-For $remote_addr` (overwrite, not append) together with the default trusted proxy
`127.0.0.1/32` gives the real client IP for lockouts and logs.
Port 8081 answers `/` with a short text, `/healthz` with `ok` (also checks the database) and anything else
with a plain 404.
## RustProxy
Create a vhost for the mail domain that routes `/Microsoft-Server-ActiveSync` and the three autodiscover paths
to `http://127.0.0.1:8081` with a response timeout of at least 3660 s and response buffering disabled; point a
health check at `/healthz`. RustProxy sets `X-Forwarded-For`, so its address must be in **Security -> Trusted
proxies** (loopback by default).
## Postfix (submission)
Recommended: SMTP on 587 authenticated with the device user's credentials (`auth: user_credentials`). With
`smtpd_sender_login_maps` + `reject_sender_login_mismatch` the mail server enforces the sender as well.
The `sendmail` method needs `NoNewPrivileges=false` and `ReadWritePaths=/var/spool/postfix/maildrop` in the unit
(setgid `postdrop`), which is why it is not recommended.
## Panel outside localhost
The panel refuses to start on a non-loopback address unless allowed:
```ini
# /etc/active-push/environment
ACTIVE_PUSH_ALLOW_REMOTE_ADMIN=true
ACTIVE_PUSH_ADMIN_LISTEN=0.0.0.0:9091
ACTIVE_PUSH_ADMIN_TLS_CERT=/etc/active-push/tls/fullchain.pem
ACTIVE_PUSH_ADMIN_TLS_KEY=/etc/active-push/tls/privkey.pem
```
and set **Security -> Networks allowed to use the panel**. Certificates must be readable by the
`active-push` group (e.g. copied by a certbot deploy hook).
## Upgrades
Install the new package; the schema is migrated automatically on start. Settings, devices and states are kept.
## Backups
See [LOGS.md](LOGS.md#backups). Losing the database never loses mail - devices resynchronise.
## Building from source without a package
```bash
cargo build --release
sudo install -m 0755 target/release/active-push /usr/bin/active-push
sudo adduser --system --group --home /var/lib/active-push active-push
sudo install -d -o active-push -g active-push -m 0700 /var/lib/active-push
sudo install -m 0644 deploy/active-push.service /etc/systemd/system/
sudo install -d -m 0750 -g active-push /etc/active-push
sudo install -m 0640 -g active-push deploy/environment.example /etc/active-push/environment
sudo systemctl daemon-reload && sudo systemctl enable --now active-push
```