Nginx
Open source web server and reverse proxy.
Project Homepage: Nginx Homepage Documentation: Nginx Docs
Commands #
| COMMAND | DESCRIPTION |
|---|---|
sudo nginx -t | Test the configuration |
sudo nginx -T | Test and dump the full config |
sudo systemctl reload nginx | Apply config without dropping connections |
sudo systemctl restart nginx | Restart |
sudo tail -f /var/log/nginx/error.log | Follow the error log |
nginx -V 2>&1 | tr ' ' '\n' | grep module | Compiled-in modules |
Debian layout: sites-available/ holds configs, link them into sites-enabled/ (sudo ln -s /etc/nginx/sites-available/<SITE> /etc/nginx/sites-enabled/).
Basic configuration arguments and examples #
Logging and debugging:
error_log <file> <loglevel>
error_log logs/error.log;
error_log logs/debug.log debug;
error_log logs/error.log notice;basic listening ports:
listen <port> <options>
listen 80;
listen 443 ssl;
http2 on;
listen 443 quic reuseport; # HTTP/3header modifications:
add_header Alt-Svc 'h3=":443"; ma=86400'; # advertise HTTP/3
add_header Strict-Transport-Security "max-age=63072000" always;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
server_name domain1.com *.domain1.com;
root /var/www/html/domain1;
index index.php index.html;location blocks:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png|svg|webp)$ {
expires max;
log_not_found off;
}Redirect HTTP to HTTPS #
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}Reverse Proxy #
Show Client’s real IP #
server {
server_name example.com;
location / {
proxy_pass http://localhost:4000;
proxy_set_header Host $host;
# Show clients real IP behind a proxy
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;
}
}WebSockets #
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";mTLS (Client Certificates) #
Require clients to present a certificate signed by your CA. See mTLS (Mutual TLS) for creating the CA and client certificates.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
ssl_client_certificate /etc/nginx/certs/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
proxy_pass http://localhost:4000;
proxy_set_header X-Client-DN $ssl_client_s_dn;
}
}| DIRECTIVE | NOTE |
|---|---|
ssl_client_certificate <FILE> | CA that signs client certificates. Also sends the CA list to clients (ssl_trusted_certificate does not) |
ssl_verify_client on|off|optional|optional_no_ca | Default off. optional accepts no certificate, so check $ssl_client_verify yourself |
ssl_verify_depth <N> | Chain length to verify, default 1 |
ssl_crl <FILE> | PEM revocation list, including those for intermediates |
$ssl_client_verify | SUCCESS, FAILED:<reason> or NONE |
$ssl_client_s_dn | Client subject DN (RFC 2253) |
$ssl_client_fingerprint | SHA1 fingerprint of the client certificate |
Failures return special codes 496 (no certificate) and 495 (verification failed), which error_page can catch. A plain 400 is also possible (not confirmed for every case).
To present a client certificate to a backend:
proxy_ssl_certificate /etc/nginx/certs/client.crt;
proxy_ssl_certificate_key /etc/nginx/certs/client.key;
proxy_ssl_trusted_certificate /etc/nginx/certs/backend-ca.crt;
proxy_ssl_verify on; # default offDocumentation: ngx_http_ssl_module · ngx_http_proxy_module
Useful Snippets #
client_max_body_size 100M; # uploads
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; # in http {}
limit_req zone=perip burst=20 nodelay; # in location {}
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd; # htpasswd -c /etc/nginx/.htpasswd <USER>TLS settings: see SSL Security Cheat-Sheet. Alternatives: Traefik.