Trace: nginx

Nginx

This is an old revision of the document!


Nginx

Usage with acme.sh

1. You need to create a blank site.

server {
    server_tokens off;
    listen 80;
    listen [::]:80;
    server_name example.com;
    
    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root /var/www/acme-challenge/;
    }
}

Don't forget to link and restart nginx.

2. Install acme.sh to get a cert.

curl  https://get.acme.sh | sh

3. Get a cert.

acme.sh --issue -d example.com -w /var/www/acme-challenge/

Note: if you plan to use wildcard, then do this:

acme.sh --issue -d example.com -d '*.example.com' --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
acme.sh --renew -d example.com -d '*.example.com' --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please

4. Copy the cert to nginx folder.

acme.sh --install-cert -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd     "service nginx force-reload"

5. Rewrite the site's config file.

Here is an example secure conf.

example.com
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://assets.zendesk.com; font-src 'self' https://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src 'none'";

server {
    server_tokens off;
    listen 80;
    listen [::]:80;
    server_name example.com;
    
    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root /var/www/acme-challenge/;
    }

    return 301 https://$host$request_uri;
}
server {
    server_tokens off;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # enables server-side protection from BEAST attacks
    # http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html
    ssl_prefer_server_ciphers on;
    # disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # ciphers chosen for forward secrecy and compatibility
    # http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

    # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
    # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
    resolver 1.1.1.1 1.0.0.1;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/example.com.crt;

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

    root /home/wwwroot/example.com;
    index index.php index.html;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    }

    location ~ /\.ht {
       deny all;
    }

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

}

dhparam.pem

Diffie–Hellman key exchange (DH) is a method of securely exchanging cryptographic keys over a public channel and was one of the first public-key protocols as originally conceptualized by Ralph Merkle and named after Whitfield Diffie and Martin Hellman. DH is one of the earliest practical examples of public key exchange implemented within the field of cryptography. (Source: Wikipedia)

openssl dhparam -out dhparam.pem 4096

Cool stuff

    # Apple CNA
    location /hotspot-detect.html {
        return 200 '<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>';
        add_header Content-Type text/html;
    }

    # Apple CNA
    location /library/test/success.html {
        return 200 '<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>';
        add_header Content-Type text/html;
    }

    # ChromeOS
    location /generate_204 {
        return 204;
    }

    # Windows connectivity detection (http://blog.superuser.com/2011/05/16/windows-7-network-awareness/)
    location /ncsi.txt {
        return 200 'Microsoft NCSI';
    }

Ban direct access

1. Just modify default

default
server {
   listen 80 default_server;
   listen [::]:80 default_server;

   server_name _;

   return 304;
}

server {
    listen 443 default_server;
    listen [::]:443 default_server;
    server_name _;
    ssl on;
    ssl_certificate /etc/nginx/ssl/null/null.crt;
    ssl_certificate_key /etc/nginx/ssl/null/null.key;
    return 304;
}

2. Generate a self-signed certificate

openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout /etc/nginx/ssl/null/null.key -out /etc/nginx/ssl/null/null.crt