install | source | nginx | advanced | analyze | php | redirect
It is usually assumed that everybody wants HTTPS, right? This is untrue esp. if your website is read-only or provides content publicly. You can have a strong SSL setup if you like, while still allowing plain HTTP at the same time. For those out there who are stuck in the past, and sometimes don’t even have SSL support on their ante-diluvian systems, why not serve anything that’s already public without crypto?
Of course HSTS comes in da game and any modern browser might forget about HTTP. However it is NOT a problem to serve HSTS while talking HTTP, as it does not make any difference to e.g. Lynx which does NOT implement HSTS (as of Jan 2021).
install from binaries –or– build from scratch.
prepare optimal DH
grep --color=always aes /proc/cpuinfo grep --color=always avx /proc/cpuinfo ls -lF /dev/*random* ls -lhF /etc/nginx/dhparms.pem # no exist openssl dhparam 2048 > /etc/nginx/dhparms.pem # -rand /dev/random:/dev/urandom
tune the daemon
assuming official release tarball
cd /etc/nginx/ cp -pi mime.types mime.types.dist #diff mime.types.default mime.types.dist vi mime.types
#application/javascript js; #application/json json; text/plain conf j2 log md out tex; text/plain unused disabled; text/plain bash ksh sh; text/plain yml yaml; text/plain js json; application/gzip gz tgz;
cp -pi nginx.conf nginx.conf.dist #diff nginx.conf.default nginx.conf.dist grep -vE '^[[:space:]]*(#|$)' nginx.conf.dist > nginx.conf.clean grep -vE '^[[:space:]]*(#|$)' nginx.conf.dist > nginx.conf vi nginx.conf
see https://pub.nethence.com/bin/www/nginx.conf
and if you’re doing a reverse-proxy
'"upstream": "$upstream_addr", ' '"upstream_cache_status": "$upstream_cache_status", ' '"upstream_connect_time": "$upstream_connect_time", ' '"upstream_header_time": "$upstream_header_time", ' '"upstream_response_length": "$upstream_response_length", ' '"upstream_response_time": "$upstream_response_time", '
moar / unused
'"body_bytes_sent": "$body_bytes_sent", '
mkdir -p /data/www/ cd /etc/nginx/conf.d/ # official repo provides default.conf mv default.conf default.conf.disabled
error vhost same as hostname
ln -s /var/www/html catch-all
define the default server stanza - we need an ssl cert anyway
domain=DOMAIN.TLD
–either– HTTP-only
cat > catch-all.conf <<EOF server { listen 80 default_server; listen [::]:80 default_server; server_name _; http2 on; access_log /var/log/nginx/catch-all.access.log main; error_log /var/log/nginx/catch-all.error.log warn; # we need to define location otherwise takes over of .well-known/ location / { # wrong vhost hence no host request_uri vars return 301 https://$domain/; } # deal with http-01 challenges (no http2 there) location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; # trailing slash matters alias /var/www/dehydrated/; } autoindex off; autoindex_exact_size off; location = /robots.txt { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } location ~ /apple-touch-icon { access_log off; log_not_found off; } } EOF
–or– HTTP & HTTPS – we need an ssl cert anyway, but let’s assume you have a corporate network private CA
cat > catch-all.conf <<EOF server { listen 80 default_server; listen [::]:80 default_server; listen 443 default_server ssl; listen [::]:443 default_server ssl; server_name _; http2 on; access_log /var/log/nginx/catch-all.access.log json; error_log /var/log/nginx/catch-all.error.log warn; # http-01 sample ssl_certificate /etc/dehydrated/certs/$domain/fullchain.pem; ssl_certificate_key /etc/dehydrated/certs/$domain/privkey.pem; ssl_certificate /etc/dehydrated/certs/ECC/$domain/fullchain.pem; ssl_certificate_key /etc/dehydrated/certs/ECC/$domain/privkey.pem; # wrong vhost hence no host request_uri vars return 301 https://$domain/; autoindex off; autoindex_exact_size off; location = /robots.txt { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } location ~ /apple-touch-icon { access_log off; log_not_found off; } } EOF
put your certs in place and define SNIs.
here’s the publicly available HTTP+HTTPS vhost sample for static pages.
vhost=static.nethence.com short=${vhost%%\.*}
cd /etc/nginx/conf.d/ # warning escapes in here cat >> $short.conf <<EOF server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; server_name $vhost; http2 on; access_log /var/log/nginx/$short.access.log json; error_log /var/log/nginx/$short.error.log warn; # http-01 sample ssl_certificate /etc/dehydrated/certs/$vhost/fullchain.pem; ssl_certificate_key /etc/dehydrated/certs/$vhost/privkey.pem; ssl_certificate /etc/dehydrated/certs/ECC/$vhost/fullchain.pem; ssl_certificate_key /etc/dehydrated/certs/ECC/$vhost/privkey.pem; location / { root /data/www/\$server_name; index index index.html index.htm; try_files \$uri \$uri/ =404; } # deal with http-01 challenges (no http2 there) location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; # trailing slash matters alias /var/www/dehydrated/; } ssi off; autoindex on; autoindex_exact_size off; location = /robots.txt { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } location ~ /apple-touch-icon { access_log off; log_not_found off; } } EOF #location ~ /\. { access_log off; log_not_found off; deny all; } #location ~ ~$ { access_log off; log_not_found off; deny all; }
And of course, if you really need a redirect instead of serving HTTP, here’s the sample when there is truly and mandatory need for SSL. Note the root location must be there for the redirect, to avoid overriding the .well-known location.
cd /etc/nginx/conf.d/ cat >> $short.conf <<EOF server { listen 80; listen [::]:80; server_name $vhost; # we need to define location otherwise takes over .well-known/ location / { return 301 https://$host$request_uri; } # deal with http-01 challenges (no http2 there) location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; # trailing slash matters alias /var/www/dehydrated/; } } EOF
check configuration
nginx -t
start and enable at boot time
# official repo list-unit-files | grep nginx systemctl status nginx # from source debian list-unit-files | grep rc-local systemctl status rc-local.service vi /etc/rc.local # from source slackware vi /etc/rc.d/rc.local echo -n nginx ... /usr/local/sbin/nginx && echo done || echo FAIL
status
pgrep -a nginx ps auxfww | less cat /var/run/nginx.pid # gnu/linux cat /var/lock/nginx.lock # absent? # netbsd cat /var/db/nginx/nginx.lock
reload
nginx -s reload
shutdown gracefully
nginx -s quit
exit brutally
nginx -s stop
remotely
redirect to HTTS or serve HTTP?
curl -i http://nethence.com/ curl -i http://SHORT.nethence.com/
HTTPS just works
curl -i https://nethence.com/ curl -i https://SHORT.nethence.com/
what happens if you’re talking SSL to a non-existing vhost?
curl -i https://ipsec.nethence.com/
check 301 on 404
curl -i https://nethence.com/lala curl -i https://SHORT.nethence.com/lala
Pitfalls and Common Mistakes https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
Getting Started https://www.nginx.com/resources/wiki/start/index.html
Syntax: server { … } https://nginx.org/en/docs/http/ngx_http_core_module.html#server
Default NGINX Configuration https://gist.github.com/ArunMichaelDsouza/471395af64fb52943bf1
NGINXConfig https://nginxconfig.io/
http://wiki.nginx.org/QuickStart
http://wiki.nginx.org/Configuration
https://docs.nginx.com/nginx/admin-guide/monitoring/logging/
http://nginx.org/en/docs/ngx_core_module.html#include
https://www.nginx.com/resources/wiki/start/topics/examples/full/
https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/
Module ngx_http_sub_module https://nginx.org/en/docs/http/ngx_http_sub_module.html
Module ngx_http_addition_module https://nginx.org/en/docs/http/ngx_http_addition_module.html
Beautiful listing of files and directories in nginx https://weekly-geekly.github.io/articles/353478/index.html
Directory Theme https://github.com/jessfraz/directory-theme/blob/master/README.md
https://nginx.org/en/docs/http/configuring_https_servers.html
https://docs.nginx.com/nginx/admin-guide/dynamic-modules/brotli/
https://www.brotli.pro/enable-brotli/servers/nginx/
HTTP Strict Transport Security (HSTS) and NGINX https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
The Importance of a Proper HTTP Strict Transport Security Implementation on Your Web Server https://blog.qualys.com/vulnerabilities-research/2016/03/28/the-importance-of-a-proper-http-strict-transport-security-implementation-on-your-web-server
Integration Guide https://letsencrypt.org/docs/integration-guide/
Hybrid RSA and ECDSA certificates with NginX https://scotthelme.co.uk/hybrid-rsa-and-ecdsa-certificates-with-nginx/
Controlling NGINX Processes at Runtime https://docs.nginx.com/nginx/admin-guide/basic-functionality/runtime-control/
nginx -s stop and -s quit what is the difference? https://serverfault.com/questions/271810/nginx-s-stop-and-s-quit-what-is-the-difference
Debugging Nginx Errors https://blog.martinfjordvald.com/debugging-nginx-errors/ https://blog.martinfjordvald.com/optimizing-nginx-for-high-traffic-loads/ https://blog.martinfjordvald.com/?s=nginx
https://serverfault.com/questions/706438/what-is-the-difference-between-nginx-variables-host-http-host-and-server-na ==> host instead of http_host
https://www.slingacademy.com/article/nginx-variables-cheat-sheet/ ==> server_protocol
https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens ==> disable
https://nginx.org/en/docs/http/ngx_http_v2_module.html ==> new syntax for http2