Setting up NGINX

install | source | nginx | advanced | analyze | php | redirect

Introduction

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

install from binaries –or– build from scratch.

Setup

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", '

Catch all virtual host

    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

sample virtual host

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

Ready to go

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

Acceptance

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

Resources

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/

setup

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/

substitution vs. additions vs. fancy

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

ssl

https://nginx.org/en/docs/http/configuring_https_servers.html

brotli

https://docs.nginx.com/nginx/admin-guide/dynamic-modules/brotli/

https://www.brotli.pro/enable-brotli/servers/nginx/

hsts

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

dual cert

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/

operations

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

nginx variables

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


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Copyright © 2024 Pierre-Philipp Braun