Useful Nginx Server Blocks

In the past weeks, I set up some different web servers with Nginx. Nginx is more lightweight and easier to handle than Apache2.

There are a lot of different uses for web servers. Some are reverse proxy, HTTPS, static sites, clouds, or PHP. In this article, I want to share my experiences with different server blocks for some of these cases. It’s basically more of a little wiki.

Redirect www to non-www Traffic

This solution works for any subdomain. You can also adjust the server_name to redirect from non-www to www traffic.

# redirect all www to non-www traffic
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name www.example.com;

    ssl_certificate /path/to/certificate.pem;
    ssl_certificate_key /path/to/certificate.pem;

    return 301 https://example.com$request_uri;
}

Redirect Http to Https Traffic

# redirect all http to https traffic
server {
    listen 80;
    listen [::]:80;

    # the underscore is a wildcard for every server name
    server_name _;

    return 301 https://$host$request_uri;
}

SSL Optimization

This server block is 90% based on this article about optimizing your HTTPS server block. It also explains what every line is doing.

ssl on;

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 120m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;

ssl_dhparam /etc/nginx/cert/dhparam.pem;

ssl_stapling on;
ssl_stapling_verify on;

Serving Static Files with SSL

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    server_name example.com;

    # include SSL custom settings for more safety and faster loading
    # optional (see chapter 'SSL optimization')
    #include /path/to/ssl/optimization.conf;

    ssl_certificate /path/to/certificate.pem;
    ssl_certificate_key /path/to/certificate.pem;

    # path to root directory for your files
    root /var/www/homepage;

    # paths for custom index and error pages (optional)
    # error_page 404 404.html;
    # index index.html;

    # deny all requests for any access files
    location ~ /\.ht {
        deny all;
    }

    # try to serve files, otherwise show 404 page
    location / {
        try_files $uri $uri/ =404;
    }
}

Reverse Proxy for large File-Transfer

I struggled a lot when using a reverse proxy for large file transfers, for example when setting up a cloud (like NextCloud) behind a reverse proxy.
These are my recommended settings, which caused the least problems.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    # include SSL custom settings for more safety and faster loading
    # optional (see chapter 'SSL optimization')
    #include /path/to/ssl/optimization.conf;

    ssl_certificate /path/to/certificate.pem;
    ssl_certificate_key /path/to/certificate.pem;

    # zero means unlimited. You can upload any file size you want
    client_max_body_size 0;
    underscores_in_headers on;

    location ~ {
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header Accept-Encoding "";
        proxy_set_header Proxy_Connection $http_connection;
        
        resolver 8.8.8.8;
        
        proxy_headers_hash_max_size 512;
        proxy_headers_hash_bucket_size 64;

        add_header Front-End-Https on;
        proxy_redirect off;
        proxy_buffering off;
        proxy_max_temp_file_size 0;

        proxy_pass http://domaintopass.com;
    }
}