feat: systemd user service file for headless deployment
Hardened unit with ProtectSystem/ProtectHome, auto-restart on failure, and ExecReload for SIGHUP hot config reload. Docs updated with setup, management, and enable-linger instructions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,13 +35,12 @@
|
|||||||
- [x] Client-side TLS (accept TLS from clients)
|
- [x] Client-side TLS (accept TLS from clients)
|
||||||
- [x] Channel key support (JOIN #channel key)
|
- [x] Channel key support (JOIN #channel key)
|
||||||
- [x] Hot config reload (SIGHUP)
|
- [x] Hot config reload (SIGHUP)
|
||||||
- [ ] Systemd service file
|
- [x] Systemd service file
|
||||||
|
|
||||||
## v0.4.0
|
## v0.4.0
|
||||||
|
|
||||||
- [ ] Per-client backlog tracking (multi-user)
|
- [ ] Per-client backlog tracking (multi-user)
|
||||||
- [ ] Web status page
|
- [ ] Web status page
|
||||||
- [ ] DCC passthrough
|
|
||||||
- [ ] Containerfile for podman deployment
|
- [ ] Containerfile for podman deployment
|
||||||
|
|
||||||
## v1.0.0
|
## v1.0.0
|
||||||
|
|||||||
2
TASKS.md
2
TASKS.md
@@ -28,5 +28,5 @@
|
|||||||
- [x] P2: Client-side TLS support
|
- [x] P2: Client-side TLS support
|
||||||
- [x] P2: Channel key support
|
- [x] P2: Channel key support
|
||||||
- [x] P2: Hot config reload (SIGHUP + REHASH refactor)
|
- [x] P2: Hot config reload (SIGHUP + REHASH refactor)
|
||||||
- [ ] P3: Systemd service file
|
- [x] P3: Systemd service file
|
||||||
- [ ] P3: Containerfile for podman deployment
|
- [ ] P3: Containerfile for podman deployment
|
||||||
|
|||||||
2
TODO.md
2
TODO.md
@@ -3,14 +3,12 @@
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [ ] Web status dashboard
|
- [ ] Web status dashboard
|
||||||
- [ ] DCC passthrough
|
|
||||||
- [ ] Per-client backlog tracking (multi-user)
|
- [ ] Per-client backlog tracking (multi-user)
|
||||||
- [ ] Farm: configurable ephemeral deadline
|
- [ ] Farm: configurable ephemeral deadline
|
||||||
- [ ] Farm: per-network enable/disable override
|
- [ ] Farm: per-network enable/disable override
|
||||||
|
|
||||||
## Infrastructure
|
## Infrastructure
|
||||||
|
|
||||||
- [ ] Systemd unit file
|
|
||||||
- [ ] Containerfile for podman deployment
|
- [ ] Containerfile for podman deployment
|
||||||
- [ ] PyPI packaging
|
- [ ] PyPI packaging
|
||||||
|
|
||||||
|
|||||||
36
config/bouncer.service
Normal file
36
config/bouncer.service
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=IRC bouncer with stealth connect and multi-network multiplexing
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=user
|
||||||
|
Group=user
|
||||||
|
|
||||||
|
ExecStart=%h/git/bouncer/.venv/bin/bouncer -c %h/git/bouncer/config/bouncer.toml
|
||||||
|
ExecReload=kill -HUP $MAINPID
|
||||||
|
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Logging (stdout/stderr -> journal)
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=bouncer
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=tmpfs
|
||||||
|
BindPaths=%h/git/bouncer
|
||||||
|
PrivateTmp=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
RestrictRealtime=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -9,6 +9,18 @@ bouncer --version # version
|
|||||||
bouncer --help # help
|
bouncer --help # help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Systemd
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user enable bouncer # enable at boot
|
||||||
|
systemctl --user start bouncer # start
|
||||||
|
systemctl --user stop bouncer # stop
|
||||||
|
systemctl --user restart bouncer # restart
|
||||||
|
systemctl --user reload bouncer # hot reload (SIGHUP)
|
||||||
|
systemctl --user status bouncer # status
|
||||||
|
journalctl --user -u bouncer -f # follow logs
|
||||||
|
```
|
||||||
|
|
||||||
## Podman
|
## Podman
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -219,6 +231,7 @@ password # optional, IRC server PASS
|
|||||||
|------|---------|
|
|------|---------|
|
||||||
| `config/bouncer.toml` | Active config (gitignored) |
|
| `config/bouncer.toml` | Active config (gitignored) |
|
||||||
| `config/bouncer.example.toml` | Example template |
|
| `config/bouncer.example.toml` | Example template |
|
||||||
|
| `config/bouncer.service` | Systemd user service unit |
|
||||||
| `config/bouncer.db` | SQLite backlog (auto-created) |
|
| `config/bouncer.db` | SQLite backlog (auto-created) |
|
||||||
| `{data_dir}/bouncer.pem` | Listener TLS cert (auto-created) |
|
| `{data_dir}/bouncer.pem` | Listener TLS cert (auto-created) |
|
||||||
| `{data_dir}/certs/{net}/{nick}.pem` | Client certificates (auto-created) |
|
| `{data_dir}/certs/{net}/{nick}.pem` | Client certificates (auto-created) |
|
||||||
|
|||||||
@@ -68,6 +68,45 @@ Verify:
|
|||||||
which bouncer
|
which bouncer
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Systemd (User Service)
|
||||||
|
|
||||||
|
Install and enable the bouncer as a user service (no root required):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.config/systemd/user
|
||||||
|
cp config/bouncer.service ~/.config/systemd/user/bouncer.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `ExecStart=` paths if your install differs from the defaults:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$EDITOR ~/.config/systemd/user/bouncer.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable and start:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable bouncer
|
||||||
|
systemctl --user start bouncer
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable lingering so the service runs without an active login session:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo loginctl enable-linger $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
### Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user status bouncer # check status
|
||||||
|
systemctl --user restart bouncer # restart
|
||||||
|
systemctl --user stop bouncer # stop
|
||||||
|
journalctl --user -u bouncer -f # follow logs
|
||||||
|
systemctl --user reload bouncer # hot reload config (SIGHUP)
|
||||||
|
```
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
Installed automatically by `make dev`:
|
Installed automatically by `make dev`:
|
||||||
|
|||||||
@@ -684,6 +684,20 @@ Results are sent back as NOTICE messages.
|
|||||||
| farm_enabled, farm_interval, etc. | Farm started/stopped |
|
| farm_enabled, farm_interval, etc. | Farm started/stopped |
|
||||||
| bind, port, password, client_tls | Warning logged (restart required) |
|
| bind, port, password, client_tls | Warning logged (restart required) |
|
||||||
|
|
||||||
|
## Systemd
|
||||||
|
|
||||||
|
The bouncer ships with a systemd user service file. See [INSTALL.md](INSTALL.md)
|
||||||
|
for setup. Key operations:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user start bouncer # start
|
||||||
|
systemctl --user stop bouncer # stop
|
||||||
|
systemctl --user reload bouncer # hot reload (SIGHUP)
|
||||||
|
journalctl --user -u bouncer -f # follow logs
|
||||||
|
```
|
||||||
|
|
||||||
|
The service restarts automatically on failure (`RestartSec=10`).
|
||||||
|
|
||||||
## Stopping
|
## Stopping
|
||||||
|
|
||||||
Press `Ctrl+C` or send `SIGTERM`. The bouncer shuts down gracefully, closing
|
Press `Ctrl+C` or send `SIGTERM`. The bouncer shuts down gracefully, closing
|
||||||
|
|||||||
Reference in New Issue
Block a user