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:10m; ssl_session_timeout 10m; 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; # Update 2019-05-08: Uses TLSv1.3 only, this requires nginx >= 1.13.0 else use TLS1.2 ssl_protocols TLSv1.3; # 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'; ssl_ecdh_curve secp384r1; # 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 valid=300s; resolver_timeout 5s; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/nginx/ssl/example.com.crt; add_header Strict-Transport-Security "max-age=63072000; 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
If your openssl
or nginx
still uses a lot of CPU after that, then use:
openssl dhparam -dsaparam -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