Skip to content

Instantly share code, notes, and snippets.

@tq-bit
Last active April 28, 2023 08:44
Show Gist options
  • Save tq-bit/6cf1fed63998e6bce2387eb2ab694358 to your computer and use it in GitHub Desktop.
Save tq-bit/6cf1fed63998e6bce2387eb2ab694358 to your computer and use it in GitHub Desktop.
Nginx Configuration with SSL, HTTP2, Load Balancing, Caching, Security headers, disabled caching, Gzip
#!/bin/bash
# Add your server's username & domain here
USER_NAME=tqbit
SERVER_DOMAIN=test.q-bit.me
SERVER_FRONTEND_PATH=/var/www/html # static, don't change
SERVER_API_PATH=/api # Adjust to your backend's API path
SERVER_API_CACHE_NAME=api_cache # Adjust to your cache key
SERVER_API_CACHE_PATH=/var/tmp/nginx # Change if you have a specific place for your cache
SERVER_API_CACHE_LIFETIME=1m # Adjust the lifetime of your cache, e.g. 1d, 1m
NODEJS_SERVICE_UPSTREAM_NAME=http://node_services # Adjust the name of your backend service's upstream
NODEJS_SERVICE_ONE_URL=http://localhost:3000 # Adjust these to the local ports your apps are running
NODEJS_SERVICE_TWO_URL=http://localhost:4000 # OR to the hostnames of other machines in your cluster
NODEJS_SERVICE_THREE_URL=http://localhost:5000
SERVER_NGINX_CONFIG_PATH=/etc/nginx/nginx.conf # static, don't change
SERVER_NGINX_DOMAIN_CONFIG_PATH=/etc/nginx/sites-enabled/$SERVER_DOMAIN # static, don't change
set -e
# Run default update process
sudo apt update && sudo apt upgrade -y
# Install nginx package
sudo apt install nginx
# Install certbot and receive a HTTPS Certificate
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx -d $SERVER_DOMAIN
# Update /etc/nginc/nginx.conf AFTER running certbot
echo "user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
# Load modules
include /etc/nginx/modules-enabled/*.conf;
events {
multi_accept on;
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 50M;
# Set API cache
proxy_cache_path $SERVER_API_CACHE_PATH levels=1:2 keys_zone=$SERVER_API_CACHE_NAME:30m max_size=250m inactive=5m use_temp_path=off;
# Define upstream servers for load balancing
upstream node_services {
ip_hash;
server $NODEJS_SERVICE_ONE_URL;
server $NODEJS_SERVICE_TWO_URL;
server $NODEJS_SERVICE_THREE_URL;
}
# Include mimetypes
include mime.types;
default_type application/octet-stream;
# Disable logging
access_log off;
error_log /dev/null;
# Enable gzip for text
gzip on;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript:
# SSL
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
# Mozilla Intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Load configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}" | sudo tee $SERVER_NGINX_CONFIG_PATH
# Update your domain's entries
echo "server {
root $SERVER_FRONTEND_PATH;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection \"1; mode-block\";
add_header Vary Accept-Encoding;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
index index.html index.htm index.nginx-debian.html;
server_name $SERVER_DOMAIN; # managed by Certbot
listen [::]:443 http2 ssl ipv6only=on; # managed by Certbot
listen 443 http2 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/$SERVER_DOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/$SERVER_DOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# Set cache for static assets
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
add_header Vary Accept-Encoding;
}
# Create a backend location path
location $SERVER_API_PATH {
proxy_cache $SERVER_API_CACHE_NAME;
expires $SERVER_API_CACHE_LIFETIME;
add_header Pragma public;
add_header X-Cache-Status \$upstream_cache_status;
add_header Cache-Control "public";
proxy_ignore_headers Cache-Control;
proxy_cache_valid any $SERVER_API_CACHE_LIFETIME;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_pass '$NODEJS_SERVICE_UPSTREAM_NAME';
}
}
# Location for HTTP Server redirect
server {
if (\$host = $SERVER_DOMAIN) {
return 301 https://\$host\$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name $SERVER_DOMAIN;
return 404; # managed by Certbot
}
" | sudo tee $SERVER_NGINX_DOMAIN_CONFIG_PATH
# Remove default pages
sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/default
# Ensure your current user owns the server's root directory
sudo chown $USER_NAME:$USER_NAME html
sudo systemctl reload nginx
# This file results from running the setup_nginx.sh file from above
user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
# Load modules
include /etc/nginx/modules-enabled/*.conf;
events {
multi_accept on;
worker_connections 65535;
}
http {
upstream node_services {
server localhost:3000;
server localhost:4000;
server localhost:5000;
}
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 50M;
# Set API cache
proxy_cache_path /var/tmp/nginx levels=1:2 keys_zone=api_cache:30m max_size=250m inactive=5m use_temp_path=off;
# Include mimetypes
include mime.types;
default_type application/octet-stream;
# Disable logging
access_log off;
error_log /dev/null;
# Enable gzip for text
gzip on;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript:
# SSL
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
# Mozilla Intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Load configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
# This file results from running the setup_nginx.sh file from above
server {
root /var/www/html;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode-block";
add_header Vary Accept-Encoding;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
index index.html index.htm index.nginx-debian.html;
server_name test.q-bit.me; # managed by Certbot
listen [::]:443 http2 ssl ipv6only=on; # managed by Certbot
listen 443 http2 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/test.q-bit.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.q-bit.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# Set cache for static assets
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
}
# Create a backend location path
location /api {
proxy_cache api_cache;
expires 1m;
add_header Pragma public;
add_header X-Cache-Status $upstream_cache_status;
add_header Cache-Control public;
# proxy_ignore_headers Cache-Control;
proxy_cache_valid any 1m;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502
http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_pass 'http://node_services';
}
}
# Location for HTTP Server redirect
server {
if ($host = test.q-bit.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name test.q-bit.me;
return 404; # managed by Certbot
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment