forked from claw/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
|
- Syntax highlighting
|
||||||
- Paste forking / versioning
|
- Paste forking / versioning
|
||||||
- Public paste listing / discovery
|
- Public paste listing / discovery
|
||||||
- Rate limiting per IP (delegated to reverse proxy)
|
|
||||||
- Multi-node clustering / distributed storage
|
- Multi-node clustering / distributed storage
|
||||||
- Alternative storage backends (S3, PostgreSQL)
|
- Alternative storage backends (S3, PostgreSQL)
|
||||||
|
|
||||||
@@ -135,7 +134,7 @@ A self-hosted pastebin API that:
|
|||||||
│ Content-hash deduplication │ Complete
|
│ Content-hash deduplication │ Complete
|
||||||
│ Proof-of-work │ Complete
|
│ Proof-of-work │ Complete
|
||||||
│ Anti-flood (dynamic PoW) │ Complete
|
│ Anti-flood (dynamic PoW) │ Complete
|
||||||
│ IP-based rate limiting │ Complete
|
│ IP-based rate limiting │ Complete (with X-RateLimit-* headers)
|
||||||
│ URL prefix support │ Complete
|
│ URL prefix support │ Complete
|
||||||
│ /client endpoint │ Complete
|
│ /client endpoint │ Complete
|
||||||
│ E2E encryption (CLI) │ Complete
|
│ E2E encryption (CLI) │ Complete
|
||||||
@@ -151,6 +150,7 @@ A self-hosted pastebin API that:
|
|||||||
│ CLI paste listing/search │ Complete
|
│ CLI paste listing/search │ Complete
|
||||||
│ Public certificate registration │ Complete
|
│ Public certificate registration │ Complete
|
||||||
│ CLI register command │ 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)
|
- Content-hash deduplication (abuse prevention)
|
||||||
- Proof-of-work spam prevention
|
- Proof-of-work spam prevention
|
||||||
- Anti-flood system (dynamic PoW difficulty under load)
|
- 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)
|
- Entropy enforcement (require encrypted uploads)
|
||||||
- E2E encryption in CLI (AES-256-GCM, key in URL fragment)
|
- E2E encryption in CLI (AES-256-GCM, key in URL fragment)
|
||||||
- URL prefix support for reverse proxy deployments
|
- 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)
|
- Scheduled cleanup (pastes, hashes, rate limits)
|
||||||
- Security headers and request tracing
|
- Security headers and request tracing
|
||||||
- Container deployment support
|
- Container deployment support
|
||||||
|
- systemd service unit with security hardening
|
||||||
- Security tooling (ruff, bandit, mypy, pip-audit)
|
- Security tooling (ruff, bandit, mypy, pip-audit)
|
||||||
- CI/CD pipeline with lint, security, and test jobs
|
- CI/CD pipeline with lint, security, and test jobs
|
||||||
- CLI with list, search, update, export commands
|
- CLI with list, search, update, export commands
|
||||||
- Public certificate registration (PoW-protected)
|
- Public certificate registration (PoW-protected)
|
||||||
- CLI register command for certificate enrollment
|
- CLI register command for certificate enrollment
|
||||||
- Comprehensive test suite (283 tests)
|
- Comprehensive test suite (284 tests)
|
||||||
- PKI audit logging (certificate lifecycle events)
|
- PKI audit logging (certificate lifecycle events)
|
||||||
- Request duration metrics (Prometheus histogram)
|
- Request duration metrics (Prometheus histogram)
|
||||||
- Memory leak detection in CI pipeline
|
- Memory leak detection in CI pipeline
|
||||||
@@ -119,9 +120,10 @@ Focus: Integration with external systems.
|
|||||||
├───┼─────────────────────────────────┼────────────────────────────────────┤
|
├───┼─────────────────────────────────┼────────────────────────────────────┤
|
||||||
│ 1 │ CLI client (fpaste) │ Done (with E2E + PKI)
|
│ 1 │ CLI client (fpaste) │ Done (with E2E + PKI)
|
||||||
│ 2 │ /client endpoint │ Done (downloadable CLI)
|
│ 2 │ /client endpoint │ Done (downloadable CLI)
|
||||||
│ 3 │ Ansible deployment role │ Planned
|
│ 3 │ systemd service unit │ Done (with security hardening)
|
||||||
│ 4 │ Kubernetes manifests │ Planned
|
│ 4 │ Ansible deployment role │ Planned
|
||||||
│ 5 │ Shell aliases/functions │ 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 | PKI audit logging | Full certificate lifecycle traceability
|
||||||
| 2024-12 | Request duration metrics | Prometheus histogram for observability
|
| 2024-12 | Request duration metrics | Prometheus histogram for observability
|
||||||
| 2024-12 | Memory leak CI job | tracemalloc-based leak detection in CI
|
| 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
|
## 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
|
## Ideas
|
||||||
|
|
||||||
- Rate limit headers in responses (X-RateLimit-*)
|
|
||||||
- Paste compression for large text content
|
- Paste compression for large text content
|
||||||
- ETag support for conditional requests
|
- ETag support for conditional requests
|
||||||
- Neovim/Vim plugin for editor integration
|
- 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
|
- PKI audit events now logged: CERT_ISSUED, CERT_REVOKED, AUTH_FAILURE
|
||||||
- Request duration metrics recorded via Prometheus histogram
|
- Request duration metrics recorded via Prometheus histogram
|
||||||
- Memory leak tests use tracemalloc to detect leaks (CI job)
|
- 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
|
## Questions
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ Unstructured intake buffer for ideas, issues, and observations. Items here are r
|
|||||||
## Debt
|
## Debt
|
||||||
|
|
||||||
- Mypy has pre-existing type errors (runs with --ignore-missing-imports)
|
- 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
|
## External Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -58,38 +58,37 @@ gunicorn \
|
|||||||
|
|
||||||
### Systemd Service
|
### Systemd Service
|
||||||
|
|
||||||
Create `/etc/systemd/system/flaskpaste.service`:
|
Use the provided examples in `examples/`:
|
||||||
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```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 daemon-reload
|
||||||
sudo systemctl enable --now flaskpaste
|
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
|
## Production: Container Deployment
|
||||||
@@ -277,6 +276,8 @@ podman run --rm \
|
|||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
|
See `examples/flaskpaste.env` for a complete template.
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
|----------|---------|-------------|
|
|----------|---------|-------------|
|
||||||
| `FLASK_ENV` | `development` | Set to `production` in production |
|
| `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_ID_LENGTH` | `12` | Paste ID length (hex chars) |
|
||||||
| `FLASKPASTE_MAX_ANON` | `3145728` | Max anonymous paste (bytes) |
|
| `FLASKPASTE_MAX_ANON` | `3145728` | Max anonymous paste (bytes) |
|
||||||
| `FLASKPASTE_MAX_AUTH` | `52428800` | Max authenticated paste (bytes) |
|
| `FLASKPASTE_MAX_AUTH` | `52428800` | Max authenticated paste (bytes) |
|
||||||
| `FLASKPASTE_EXPIRY` | `432000` | Paste expiry (seconds) |
|
| `FLASKPASTE_EXPIRY_ANON` | `86400` | Anonymous paste expiry (1 day) |
|
||||||
| `FLASKPASTE_PROXY_SECRET` | (empty) | Shared secret for proxy trust validation |
|
| `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
|
## Security Checklist
|
||||||
|
|
||||||
- [ ] Run behind reverse proxy with TLS
|
- [ ] 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
|
- [ ] Set appropriate file permissions on database
|
||||||
- [ ] Configure firewall (only expose reverse proxy)
|
- [ ] Configure firewall (only expose reverse proxy)
|
||||||
- [ ] Set `FLASK_ENV=production`
|
- [ ] Set `FLASK_ENV=production`
|
||||||
@@ -300,6 +309,10 @@ podman run --rm \
|
|||||||
- [ ] Set `FLASKPASTE_PROXY_SECRET` for defense-in-depth
|
- [ ] Set `FLASKPASTE_PROXY_SECRET` for defense-in-depth
|
||||||
- [ ] Configure proxy to send `X-Proxy-Secret` header
|
- [ ] Configure proxy to send `X-Proxy-Secret` header
|
||||||
- [ ] Configure proxy to pass/generate `X-Request-ID`
|
- [ ] 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
|
- [ ] Set up log rotation
|
||||||
- [ ] Enable automatic backups
|
- [ ] Enable automatic backups
|
||||||
- [ ] Monitor disk usage (paste storage)
|
- [ ] Monitor disk usage (paste storage)
|
||||||
|
- [ ] Monitor rate limit headers (`X-RateLimit-*`)
|
||||||
|
|||||||
Reference in New Issue
Block a user