58 lines
3.6 KiB
Markdown
58 lines
3.6 KiB
Markdown
# Example Linux service
|
|
|
|
`rustproxy.service` is an operator-reviewed deployment example, not an installed or
|
|
tested service. It runs the compiled executable as a dedicated `rustproxy` account,
|
|
uses the public administration profile shown below and grants only the capability needed
|
|
for low-port binding. It does not run the proxy as root or grant Docker socket access.
|
|
|
|
Before installation, run the real Rust acceptance suite, build a release executable,
|
|
create the unprivileged account/group through your normal system administration
|
|
process and install the executable at `/opt/rustproxy/rust-proxy`. The service
|
|
manager creates `/var/lib/rustproxy` as private writable state; the actual private
|
|
data directory is `/var/lib/rustproxy`. `LogsDirectory=rustproxy` provisions
|
|
`/var/log/rustproxy` for the JSONL access-log sink while the rest of the filesystem
|
|
remains protected by `ProtectSystem=strict`. The service enables 80/443 startup
|
|
defaults, does not start a demo backend and uses a self-signed fallback certificate
|
|
until trusted certificates are imported. Firewall, DNS and trust configuration are
|
|
separate operator responsibilities.
|
|
|
|
Existing SQLite listener overrides take precedence over these startup defaults.
|
|
Review Settings before moving an old database into this service. Public addresses
|
|
are deliberately explicit in the example. Customize the unit for other paths,
|
|
addresses, limits or a service-account convention. Never point it at a user-owned
|
|
source directory containing writable executables or real public web content.
|
|
|
|
After starting through your service manager, run account/certificate CLI operations
|
|
as the same service account with `--data-dir /var/lib/rustproxy`. The example
|
|
uses `ProtectHome=true`, so certificate files intended for runtime use must be in
|
|
the data directory, not in a home directory. Use an SSH tunnel to access the local
|
|
admin port remotely. This reference unit keeps administration on `127.0.0.1:9090`; public HTTP/HTTPS
|
|
listeners remain explicit. For direct remote administration, enable Administration HTTPS and persist
|
|
a non-loopback bind from the panel rather than exposing the plain-HTTP bootstrap listener. For a
|
|
systemd drop-in, reset `ExecStart` before replacing it. Example preserving the loopback-safe admin:
|
|
|
|
```ini
|
|
[Service]
|
|
ExecStart=
|
|
ExecStart=/opt/rustproxy/current/rust-proxy --data-dir /var/lib/rustproxy --admin-listen 127.0.0.1:9090 serve --proxy-listen 0.0.0.0:80 --tls-listen 0.0.0.0:443
|
|
ReadWritePaths=/var/log/rustproxy
|
|
ReadOnlyPaths=-/etc/letsencrypt -/etc/ssl
|
|
```
|
|
|
|
Saving HTTP/TLS or TCP/UDP stream listener changes in the UI does not restart this service. Restart explicitly
|
|
only after checking permission, free ports and certificate readiness. A bad saved
|
|
bind can prevent startup; preserve a pre-change database backup and consult
|
|
`docs/MIGRATION.md` for recovery. Verify the unit on the target system with
|
|
`systemd-analyze verify` and exercise actual non-root binding before accepting a
|
|
production deployment. This packaging environment did not run systemd or bind
|
|
privileged ports through this unit.
|
|
|
|
External certificate files under `/etc/letsencrypt` or `/etc/ssl` remain read-only under the systemd sandbox. `ReadOnlyPaths=` does not grant Unix permissions; use narrow POSIX ACLs for the `rustproxy` user. For traversal of a protected root, for example:
|
|
|
|
```bash
|
|
setfacl -m u:rustproxy:--x /etc/ssl/
|
|
```
|
|
|
|
Grant `r--` only on the certificate/key files RustProxy actually needs; never grant write access to the service identity.
|
|
If Certbot or another renewer recreates a key as `0600`, reapply the named file ACL to the newly resolved target in the renewal hook before calling the RustProxy reload API.
|