Files
ActivePush/docs/INSTALL.md
T
2026-11-05 12:52:32 +01:00

5.6 KiB

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

./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