5.6 KiB
Installation
Requirements
- Linux x86_64 (the
.debneeds 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.1only by default.
Debian package
./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
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:
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:
# /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. Losing the database never loses mail - devices resynchronise.
Building from source without a package
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