vastly expanded nginx config
This commit is contained in:
parent
0144d4966e
commit
ef61e746e7
9 changed files with 139 additions and 41 deletions
10
add-site.sh
10
add-site.sh
|
@ -39,7 +39,7 @@ main_web_root="/var/www/$domain"
|
|||
sudo mkdir -p "$main_web_root"/{_main/www,subdomains,logs}
|
||||
|
||||
# Create the user with the web root as home directory and add to www-data and websftpusers groups
|
||||
sudo useradd -m -d /var/www/$domain -s /usr/sbin/nologin -U -G www-data,websftpusers $username
|
||||
sudo useradd -m -d /var/www/$domain -s /bin/false -U -G www-data,websftpusers $username
|
||||
echo "$username:$password" | sudo chpasswd
|
||||
|
||||
# Set ownership and permissions for the main site directory
|
||||
|
@ -47,6 +47,11 @@ sudo chown -R "$username:www-data" "$main_web_root"
|
|||
sudo find "$main_web_root" -type d -exec chmod 2750 {} +
|
||||
sudo find "$main_web_root" -type f -exec chmod 640 {} +
|
||||
|
||||
# Set ownership and permissions for the main web root
|
||||
# SFTP chroot requires the user's home directory to be owned by root and not writable by others
|
||||
sudo chown "root:www-data" "$main_web_root"
|
||||
sudo chmod 755 "$main_web_root"
|
||||
|
||||
# Set ownership and permissions for the logs directory
|
||||
sudo chown root:www-data "$main_web_root/logs"
|
||||
sudo chmod 755 "$main_web_root/logs"
|
||||
|
@ -104,9 +109,6 @@ sudo cp "$(realpath "site-config.conf")" "$nginx_config"
|
|||
# replace $DOMAIN placeholder in the nginx config file
|
||||
sudo sed -i "s/\$DOMAIN/$domain/g" "$nginx_config"
|
||||
|
||||
# replace $MAIN_WEB_ROOT placeholder in the nginx config file
|
||||
sudo sed -i "s#\$MAIN_WEB_ROOT#$main_web_root#g" "$nginx_config"
|
||||
|
||||
# Enable the site
|
||||
sudo ln -sf "$nginx_config" /etc/nginx/sites-enabled/
|
||||
|
||||
|
|
29
install/nginx-conf.sh
Normal file
29
install/nginx-conf.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if script is run as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root or with sudo"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define source and destination directories
|
||||
SRC_DIR="nginx-conf"
|
||||
DEST_DIR="/etc/nginx/conf.d"
|
||||
|
||||
# Check if source directory exists
|
||||
if [ ! -d "$SRC_DIR" ]; then
|
||||
echo "Source directory '$SRC_DIR' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create destination directory if it doesn't exist
|
||||
mkdir -p "$DEST_DIR"
|
||||
|
||||
# Copy all .conf files
|
||||
echo "Copying configuration files..."
|
||||
cp -v "$SRC_DIR"/*.conf "$DEST_DIR/"
|
||||
|
||||
# Set proper permissions
|
||||
echo "Setting permissions..."
|
||||
chown root:root "$DEST_DIR"/*.conf
|
||||
chmod 644 "$DEST_DIR"/*.conf
|
26
install/nginx-conf/00-cloudflare.conf
Normal file
26
install/nginx-conf/00-cloudflare.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Cloudflare IP Ranges
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
set_real_ip_from 103.22.200.0/22;
|
||||
set_real_ip_from 103.31.4.0/22;
|
||||
set_real_ip_from 141.101.64.0/18;
|
||||
set_real_ip_from 108.162.192.0/18;
|
||||
set_real_ip_from 190.93.240.0/20;
|
||||
set_real_ip_from 188.114.96.0/20;
|
||||
set_real_ip_from 197.234.240.0/22;
|
||||
set_real_ip_from 198.41.128.0/17;
|
||||
set_real_ip_from 162.158.0.0/15;
|
||||
set_real_ip_from 104.16.0.0/13;
|
||||
set_real_ip_from 104.24.0.0/14;
|
||||
set_real_ip_from 172.64.0.0/13;
|
||||
set_real_ip_from 131.0.72.0/22;
|
||||
set_real_ip_from 2400:cb00::/32;
|
||||
set_real_ip_from 2606:4700::/32;
|
||||
set_real_ip_from 2803:f800::/32;
|
||||
set_real_ip_from 2405:b500::/32;
|
||||
set_real_ip_from 2405:8100::/32;
|
||||
set_real_ip_from 2a06:98c0::/29;
|
||||
set_real_ip_from 2c0f:f248::/32;
|
||||
|
||||
# Pull real IP from Cloudflare
|
||||
real_ip_header CF-Connecting-IP;
|
3
install/nginx-conf/00-rate-limiting-zones.conf
Normal file
3
install/nginx-conf/00-rate-limiting-zones.conf
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Basic rate limiting zones
|
||||
limit_req_zone $binary_remote_addr zone=general:10m rate=50r/s;
|
||||
limit_req_zone $binary_remote_addr zone=php:10m rate=10r/s;
|
6
install/nginx-conf/10-ssl-config.conf
Normal file
6
install/nginx-conf/10-ssl-config.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SSL configuration
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
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;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 24h;
|
8
install/nginx-conf/20-security-headers.conf
Normal file
8
install/nginx-conf/20-security-headers.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Security headers
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-Frame-Options SAMEORIGIN always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "geolocation=(),microphone=(),camera=(),payment=(),usb=(),battery=(),display-capture=()" always;
|
||||
server_tokens off;
|
6
install/nginx-conf/40-gzip.conf
Normal file
6
install/nginx-conf/40-gzip.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Turn on gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
|
10
install/nginx-conf/40-php-config.conf
Normal file
10
install/nginx-conf/40-php-config.conf
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Basic PHP configuration
|
||||
location ~ \.php$ {
|
||||
limit_req zone=php burst=20 nodelay;
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
# HTTP redirect
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
@ -5,75 +6,82 @@ server {
|
|||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# HTTPS server
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name .$DOMAIN;
|
||||
|
||||
# SSL Configuration
|
||||
# SSL certificates
|
||||
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
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;
|
||||
|
||||
# Determine the subdomain and set the root accordingly
|
||||
# subdomains are the default, so that we get 404s for nonexistant subdomains
|
||||
# Apply general rate limit
|
||||
limit_req zone=general burst=100 nodelay;
|
||||
|
||||
# Content Security Policy (needs to be per-domain)
|
||||
add_header Content-Security-Policy "
|
||||
default-src 'self' *.$DOMAIN;
|
||||
script-src 'self' 'unsafe-inline' 'unsafe-eval' *.$DOMAIN;
|
||||
style-src 'self' 'unsafe-inline' *.$DOMAIN;
|
||||
img-src 'self' data: *.$DOMAIN;
|
||||
font-src 'self' data: *.$DOMAIN;
|
||||
connect-src 'self' *.$DOMAIN;
|
||||
frame-src 'self' *.$DOMAIN;
|
||||
media-src 'self' *.$DOMAIN;
|
||||
object-src 'none';
|
||||
base-uri 'self';
|
||||
form-action 'self' *.$DOMAIN;
|
||||
" always;
|
||||
|
||||
# Subdomain handling
|
||||
set $subdomain '';
|
||||
set $full_root $MAIN_WEB_ROOT/_main/www;
|
||||
set $access_log_path $MAIN_WEB_ROOT/logs/$subdomain.access.log;
|
||||
set $error_log_path $MAIN_WEB_ROOT/logs/$subdomain.error.log;
|
||||
set $full_root "/var/www/$DOMAIN/_main/www";
|
||||
set $access_log_path "/var/www/$DOMAIN/logs/main.access.log";
|
||||
set $error_log_path "/var/www/$DOMAIN/logs/main.error.log";
|
||||
if ($host ~* ^([^.]+)\.$DOMAIN$) {
|
||||
set $subdomain $1;
|
||||
set $full_root $MAIN_WEB_ROOT/subdomains/$subdomain/www;
|
||||
set $access_log_path $MAIN_WEB_ROOT/logs/_main.access.log;
|
||||
set $error_log_path $MAIN_WEB_ROOT/logs/_main.error.log;
|
||||
set $full_root "/var/www/$DOMAIN/subdomains/$subdomain/www";
|
||||
set $access_log_path "/var/www/$DOMAIN/logs/$subdomain.access.log";
|
||||
set $error_log_path "/var/www/$DOMAIN/logs/$subdomain.error.log";
|
||||
}
|
||||
root $full_root;
|
||||
|
||||
# Index file names
|
||||
# Basic settings
|
||||
index index.html index.htm index.php;
|
||||
client_max_body_size 20M;
|
||||
|
||||
# Try files first, then use the router.php file if it exists
|
||||
# Block .ht* files
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Main location block
|
||||
location / {
|
||||
try_files $uri $uri/ @router;
|
||||
}
|
||||
|
||||
# Use the router.php file for all nonexistant file requests if it exists
|
||||
# Router handling
|
||||
location @router {
|
||||
if (!-f $document_root/router.php) {
|
||||
return 404;
|
||||
}
|
||||
limit_req zone=php burst=20 nodelay;
|
||||
fastcgi_pass unix:/var/run/php/php-fpm.sock;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/router.php;
|
||||
}
|
||||
|
||||
# PHP Configuration
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
# Static file handling
|
||||
location ~* ^.+\.((?!php).)*$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, no-transform";
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# Deny access to .ht* files
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Additional config options
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
|
||||
client_max_body_size 20M;
|
||||
|
||||
# Log to both default location and custom site directory, named by subdomain
|
||||
# Logging
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
access_log $access_log_path;
|
||||
error_log $error_log_path;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue