-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnginx.conf
More file actions
138 lines (115 loc) · 4.33 KB
/
nginx.conf
File metadata and controls
138 lines (115 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Nginx configuration for PicoBlog
# Place this file in /etc/nginx/sites-available/PicoBlog
# Then symlink to sites-enabled: ln -s /etc/nginx/sites-available/PicoBlog /etc/nginx/sites-enabled/
# Rate limiting zone - protects against DoS
limit_req_zone $binary_remote_addr zone=app_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
# Upstream application server (Gunicorn)
upstream PicoBlog_app {
server 127.0.0.1:8000;
# For socket-based deployment, use:
# server unix:/var/www/PicoBlog/gunicorn.sock fail_timeout=0;
}
# HTTP server - redirect all traffic to HTTPS
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;
# Allow certbot to verify domain ownership
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# Redirect all other HTTP traffic to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your-domain.com www.your-domain.com;
# SSL certificate paths (certbot will update these)
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/your-domain.com/chain.pem;
# SSL configuration (Mozilla Intermediate compatibility)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Max upload size (should match Flask's MAX_CONTENT_LENGTH)
client_max_body_size 16M;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
gzip_min_length 1024;
# Logging
access_log /var/log/nginx/PicoBlog_access.log;
error_log /var/log/nginx/PicoBlog_error.log;
# Root directory (for static files)
root /var/www/PicoBlog;
# Serve static files directly
location /static/ {
alias /var/www/PicoBlog/app/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Rate limit login endpoint
location = /login {
limit_req zone=login_limit burst=5 nodelay;
limit_req_status 429;
proxy_pass http://PicoBlog_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
# Admin panel - stricter rate limiting
location /admin {
limit_req zone=app_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://PicoBlog_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
# Proxy all other requests to Flask application
location / {
limit_req zone=app_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://PicoBlog_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Deny access to hidden files
location ~ /\. {
deny all;
}
# Deny access to sensitive files
location ~ \.(env|py|pyc|db|log)$ {
deny all;
}
}