forked from username/flaskpaste
docs: update for systemd and rate limit headers
This commit is contained in:
@@ -81,7 +81,6 @@ A self-hosted pastebin API that:
|
||||
- Syntax highlighting
|
||||
- Paste forking / versioning
|
||||
- Public paste listing / discovery
|
||||
- Rate limiting per IP (delegated to reverse proxy)
|
||||
- Multi-node clustering / distributed storage
|
||||
- Alternative storage backends (S3, PostgreSQL)
|
||||
|
||||
@@ -135,7 +134,7 @@ A self-hosted pastebin API that:
|
||||
│ Content-hash deduplication │ Complete
|
||||
│ Proof-of-work │ Complete
|
||||
│ Anti-flood (dynamic PoW) │ Complete
|
||||
│ IP-based rate limiting │ Complete
|
||||
│ IP-based rate limiting │ Complete (with X-RateLimit-* headers)
|
||||
│ URL prefix support │ Complete
|
||||
│ /client endpoint │ Complete
|
||||
│ E2E encryption (CLI) │ Complete
|
||||
@@ -151,6 +150,7 @@ A self-hosted pastebin API that:
|
||||
│ CLI paste listing/search │ Complete
|
||||
│ Public certificate registration │ Complete
|
||||
│ CLI register command │ Complete
|
||||
│ Test suite │ 216 tests passing
|
||||
│ systemd deployment │ Complete (security-hardened)
|
||||
│ Test suite │ 284 tests passing
|
||||
└─────────────────────────────────┴────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
14
ROADMAP.md
14
ROADMAP.md
@@ -12,7 +12,7 @@ FlaskPaste v1.5.0 is deployed with comprehensive security hardening and abuse pr
|
||||
- Content-hash deduplication (abuse prevention)
|
||||
- Proof-of-work spam prevention
|
||||
- Anti-flood system (dynamic PoW difficulty under load)
|
||||
- IP-based rate limiting (configurable per-IP limits)
|
||||
- IP-based rate limiting with X-RateLimit-* headers
|
||||
- Entropy enforcement (require encrypted uploads)
|
||||
- E2E encryption in CLI (AES-256-GCM, key in URL fragment)
|
||||
- URL prefix support for reverse proxy deployments
|
||||
@@ -23,12 +23,13 @@ FlaskPaste v1.5.0 is deployed with comprehensive security hardening and abuse pr
|
||||
- Scheduled cleanup (pastes, hashes, rate limits)
|
||||
- Security headers and request tracing
|
||||
- Container deployment support
|
||||
- systemd service unit with security hardening
|
||||
- Security tooling (ruff, bandit, mypy, pip-audit)
|
||||
- CI/CD pipeline with lint, security, and test jobs
|
||||
- CLI with list, search, update, export commands
|
||||
- Public certificate registration (PoW-protected)
|
||||
- CLI register command for certificate enrollment
|
||||
- Comprehensive test suite (283 tests)
|
||||
- Comprehensive test suite (284 tests)
|
||||
- PKI audit logging (certificate lifecycle events)
|
||||
- Request duration metrics (Prometheus histogram)
|
||||
- Memory leak detection in CI pipeline
|
||||
@@ -119,9 +120,10 @@ Focus: Integration with external systems.
|
||||
├───┼─────────────────────────────────┼────────────────────────────────────┤
|
||||
│ 1 │ CLI client (fpaste) │ Done (with E2E + PKI)
|
||||
│ 2 │ /client endpoint │ Done (downloadable CLI)
|
||||
│ 3 │ Ansible deployment role │ Planned
|
||||
│ 4 │ Kubernetes manifests │ Planned
|
||||
│ 5 │ Shell aliases/functions │ Planned
|
||||
│ 3 │ systemd service unit │ Done (with security hardening)
|
||||
│ 4 │ Ansible deployment role │ Planned
|
||||
│ 5 │ Kubernetes manifests │ Planned
|
||||
│ 6 │ Shell aliases/functions │ Planned
|
||||
└───┴─────────────────────────────────┴────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -184,6 +186,8 @@ These features will not be implemented:
|
||||
| 2024-12 | PKI audit logging | Full certificate lifecycle traceability
|
||||
| 2024-12 | Request duration metrics | Prometheus histogram for observability
|
||||
| 2024-12 | Memory leak CI job | tracemalloc-based leak detection in CI
|
||||
| 2024-12 | systemd service unit | Security-hardened deployment example
|
||||
| 2024-12 | Rate limit headers | X-RateLimit-* on 201/429 responses
|
||||
|
||||
## Review Schedule
|
||||
|
||||
|
||||
5
TODO.md
5
TODO.md
@@ -6,7 +6,6 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r
|
||||
|
||||
## Ideas
|
||||
|
||||
- Rate limit headers in responses (X-RateLimit-*)
|
||||
- Paste compression for large text content
|
||||
- ETag support for conditional requests
|
||||
- Neovim/Vim plugin for editor integration
|
||||
@@ -27,6 +26,8 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r
|
||||
- PKI audit events now logged: CERT_ISSUED, CERT_REVOKED, AUTH_FAILURE
|
||||
- Request duration metrics recorded via Prometheus histogram
|
||||
- Memory leak tests use tracemalloc to detect leaks (CI job)
|
||||
- Rate limit headers (X-RateLimit-*) on both 201 and 429 responses
|
||||
- systemd service unit with security hardening in examples/
|
||||
|
||||
## Questions
|
||||
|
||||
@@ -40,7 +41,7 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r
|
||||
## Debt
|
||||
|
||||
- Mypy has pre-existing type errors (runs with --ignore-missing-imports)
|
||||
- Could add more deployment examples (Kubernetes, systemd)
|
||||
- Could add more deployment examples (Kubernetes, Ansible role)
|
||||
|
||||
## External Dependencies
|
||||
|
||||
|
||||
@@ -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-*`)
|
||||
|
||||
Reference in New Issue
Block a user