forked from username/flaskpaste
add systemd service unit and rate limit headers
Systemd deployment: - examples/flaskpaste.service with security hardening - examples/flaskpaste.env with all config options - README deployment section updated Rate limit headers (X-RateLimit-*): - Limit, Remaining, Reset on 201 and 429 responses - Per-IP tracking with auth multiplier - api.md documented
This commit is contained in:
48
examples/flaskpaste.env
Normal file
48
examples/flaskpaste.env
Normal file
@@ -0,0 +1,48 @@
|
||||
# FlaskPaste environment configuration
|
||||
# Install: sudo mkdir -p /etc/flaskpaste && sudo cp flaskpaste.env /etc/flaskpaste/env
|
||||
# Permissions: sudo chmod 600 /etc/flaskpaste/env
|
||||
|
||||
# Flask environment
|
||||
FLASK_ENV=production
|
||||
|
||||
# Database path
|
||||
FLASKPASTE_DB=/opt/flaskpaste/data/pastes.db
|
||||
|
||||
# Paste limits
|
||||
FLASKPASTE_MAX_ANON=3145728
|
||||
FLASKPASTE_MAX_AUTH=52428800
|
||||
|
||||
# Expiry (tiered by authentication level)
|
||||
FLASKPASTE_EXPIRY_ANON=86400
|
||||
FLASKPASTE_EXPIRY_UNTRUSTED=604800
|
||||
FLASKPASTE_EXPIRY_TRUSTED=2592000
|
||||
|
||||
# Proof-of-work (set to 0 to disable)
|
||||
FLASKPASTE_POW_DIFFICULTY=20
|
||||
FLASKPASTE_POW_TTL=300
|
||||
|
||||
# Anti-flood
|
||||
FLASKPASTE_ANTIFLOOD=1
|
||||
FLASKPASTE_ANTIFLOOD_THRESHOLD=5
|
||||
FLASKPASTE_ANTIFLOOD_MAX=28
|
||||
|
||||
# Rate limiting
|
||||
FLASKPASTE_RATE_LIMIT=1
|
||||
FLASKPASTE_RATE_WINDOW=60
|
||||
FLASKPASTE_RATE_MAX=10
|
||||
FLASKPASTE_RATE_AUTH_MULT=5
|
||||
|
||||
# Content deduplication
|
||||
FLASKPASTE_DEDUP_WINDOW=3600
|
||||
FLASKPASTE_DEDUP_MAX=3
|
||||
|
||||
# URL prefix (for reverse proxy path-based routing)
|
||||
# FLASKPASTE_URL_PREFIX=/paste
|
||||
|
||||
# Proxy trust (set shared secret for header validation)
|
||||
# FLASKPASTE_PROXY_SECRET=your-secret-here
|
||||
|
||||
# PKI (uncomment to enable certificate authority)
|
||||
# FLASKPASTE_PKI_ENABLED=1
|
||||
# FLASKPASTE_PKI_CA_PASSWORD=change-this-secure-password
|
||||
# FLASKPASTE_PKI_CERT_DAYS=365
|
||||
83
examples/flaskpaste.service
Normal file
83
examples/flaskpaste.service
Normal file
@@ -0,0 +1,83 @@
|
||||
# FlaskPaste systemd service unit
|
||||
# Install: sudo cp flaskpaste.service /etc/systemd/system/
|
||||
# Enable: sudo systemctl daemon-reload && sudo systemctl enable --now flaskpaste
|
||||
#
|
||||
# Configuration via environment file: /etc/flaskpaste/env
|
||||
# See README.md for all available environment variables
|
||||
|
||||
[Unit]
|
||||
Description=FlaskPaste REST API pastebin
|
||||
Documentation=https://github.com/username/flaskpaste
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=flaskpaste
|
||||
Group=flaskpaste
|
||||
WorkingDirectory=/opt/flaskpaste
|
||||
|
||||
# Environment configuration
|
||||
EnvironmentFile=-/etc/flaskpaste/env
|
||||
|
||||
# Gunicorn WSGI server
|
||||
# Workers = 2 * CPU cores + 1 (adjust based on load)
|
||||
ExecStart=/opt/flaskpaste/venv/bin/gunicorn \
|
||||
--bind 127.0.0.1:5000 \
|
||||
--workers 4 \
|
||||
--worker-class sync \
|
||||
--timeout 30 \
|
||||
--keep-alive 5 \
|
||||
--max-requests 1000 \
|
||||
--max-requests-jitter 50 \
|
||||
--access-logfile - \
|
||||
--error-logfile - \
|
||||
--capture-output \
|
||||
wsgi:app
|
||||
|
||||
# Restart policy
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
StartLimitIntervalSec=60
|
||||
StartLimitBurst=3
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
# Security hardening (systemd v232+)
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectClock=yes
|
||||
ProtectHostname=yes
|
||||
RestrictRealtime=yes
|
||||
RestrictSUIDSGID=yes
|
||||
RestrictNamespaces=yes
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
LockPersonality=yes
|
||||
MemoryDenyWriteExecute=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged @resources
|
||||
|
||||
# Read-write paths (database, data directory)
|
||||
ReadWritePaths=/opt/flaskpaste/data
|
||||
|
||||
# Capabilities
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
|
||||
# Logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=flaskpaste
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user