docs: update for systemd and rate limit headers

This commit is contained in:
Username
2025-12-24 20:05:30 +01:00
parent cf458347ef
commit 4577a1d7e4
4 changed files with 57 additions and 39 deletions

View File

@@ -58,38 +58,37 @@ gunicorn \
### Systemd Service
Create `/etc/systemd/system/flaskpaste.service`:
```ini
[Unit]
Description=FlaskPaste Pastebin Service
After=network.target
[Service]
Type=notify
User=flaskpaste
Group=flaskpaste
RuntimeDirectory=flaskpaste
WorkingDirectory=/opt/flaskpaste
Environment="FLASK_ENV=production"
Environment="FLASKPASTE_DB=/var/lib/flaskpaste/pastes.db"
ExecStart=/opt/flaskpaste/venv/bin/gunicorn \
--workers 4 \
--bind unix:/run/flaskpaste/gunicorn.sock \
wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
Use the provided examples in `examples/`:
```bash
# Create service user
sudo useradd -r -s /sbin/nologin flaskpaste
# Copy application
sudo mkdir -p /opt/flaskpaste/data
sudo cp -r . /opt/flaskpaste/
sudo chown -R flaskpaste:flaskpaste /opt/flaskpaste
# Copy service unit (with security hardening)
sudo cp examples/flaskpaste.service /etc/systemd/system/
# Copy and secure environment file
sudo mkdir -p /etc/flaskpaste
sudo cp examples/flaskpaste.env /etc/flaskpaste/env
sudo chmod 600 /etc/flaskpaste/env
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now flaskpaste
```
The provided service unit includes security hardening:
- `NoNewPrivileges`, `PrivateTmp`, `ProtectSystem=strict`
- `MemoryDenyWriteExecute`, `RestrictNamespaces`
- Resource limits and restart policies
See `examples/flaskpaste.service` for the full configuration.
---
## Production: Container Deployment
@@ -277,6 +276,8 @@ podman run --rm \
## Environment Variables
See `examples/flaskpaste.env` for a complete template.
| Variable | Default | Description |
|----------|---------|-------------|
| `FLASK_ENV` | `development` | Set to `production` in production |
@@ -284,15 +285,23 @@ podman run --rm \
| `FLASKPASTE_ID_LENGTH` | `12` | Paste ID length (hex chars) |
| `FLASKPASTE_MAX_ANON` | `3145728` | Max anonymous paste (bytes) |
| `FLASKPASTE_MAX_AUTH` | `52428800` | Max authenticated paste (bytes) |
| `FLASKPASTE_EXPIRY` | `432000` | Paste expiry (seconds) |
| `FLASKPASTE_PROXY_SECRET` | (empty) | Shared secret for proxy trust validation |
| `FLASKPASTE_EXPIRY_ANON` | `86400` | Anonymous paste expiry (1 day) |
| `FLASKPASTE_EXPIRY_UNTRUSTED` | `604800` | Untrusted cert expiry (7 days) |
| `FLASKPASTE_EXPIRY_TRUSTED` | `2592000` | PKI-registered expiry (30 days) |
| `FLASKPASTE_PROXY_SECRET` | (empty) | Shared secret for proxy trust |
| `FLASKPASTE_POW_DIFFICULTY` | `20` | PoW difficulty (0=disabled) |
| `FLASKPASTE_RATE_LIMIT` | `1` | Enable IP-based rate limiting |
| `FLASKPASTE_RATE_MAX` | `10` | Max requests per window (anon) |
| `FLASKPASTE_RATE_AUTH_MULT` | `5` | Multiplier for authenticated users |
| `FLASKPASTE_ANTIFLOOD` | `1` | Enable dynamic PoW under attack |
| `FLASKPASTE_PKI_ENABLED` | `0` | Enable built-in PKI |
---
## Security Checklist
- [ ] Run behind reverse proxy with TLS
- [ ] Use non-root user in containers
- [ ] Use non-root user (or systemd security hardening)
- [ ] Set appropriate file permissions on database
- [ ] Configure firewall (only expose reverse proxy)
- [ ] Set `FLASK_ENV=production`
@@ -300,6 +309,10 @@ podman run --rm \
- [ ] Set `FLASKPASTE_PROXY_SECRET` for defense-in-depth
- [ ] Configure proxy to send `X-Proxy-Secret` header
- [ ] Configure proxy to pass/generate `X-Request-ID`
- [ ] Enable rate limiting (`FLASKPASTE_RATE_LIMIT=1`)
- [ ] Enable anti-flood (`FLASKPASTE_ANTIFLOOD=1`)
- [ ] Enable PoW (`FLASKPASTE_POW_DIFFICULTY=20`)
- [ ] Set up log rotation
- [ ] Enable automatic backups
- [ ] Monitor disk usage (paste storage)
- [ ] Monitor rate limit headers (`X-RateLimit-*`)