diff --git a/configs/nginx/nginx.sh b/configs/nginx/nginx.sh index b614fbd5..798690f0 100755 --- a/configs/nginx/nginx.sh +++ b/configs/nginx/nginx.sh @@ -5,17 +5,27 @@ [[ "$EUID" -ne 0 ]] && echo "Please run as root" && exit; echo "[jschan nginx configuration helper]" -read -p "Enter the directory you cloned jschan (blank=$(pwd)): " JSCHAN_DIRECTORY +read -p "Enter the directory you cloned jschan, no trailing slash. (blank=$(pwd)): " JSCHAN_DIRECTORY JSCHAN_DIRECTORY=${JSCHAN_DIRECTORY:-$(pwd)} read -p "Enter your clearnet domain name e.g. example.com (blank=no clearnet domain): " CLEARNET_DOMAIN SITES_AVAILABLE_NAME=${CLEARNET_DOMAIN:-jschan} #not sure on a good default, used for sites-available config name read -p "Enter tor .onion address (blank=no .onion address): " ONION_DOMAIN read -p "Enter lokinet .loki address (blank=no .loki address): " LOKI_DOMAIN +read -p "Would you like to add a www. subdomain? (y/n): " ADD_WWW_SUBDOMAIN +if [[ "$CLEARNET_DOMAIN" != "" ]]; then + read -p "Run certbot standalone and automatically configure a certificate for https on clearnet? (y/n): " CERTBOT + if [[ "$CERTBOT" == "n" ]]; then + read -p "Generate a self-signed certificate instead? (y/n): " SELFSIGNED + fi + if [[ "$SELFSIGNED" == "n" ]]; then + read -p "Warning: no https certificate chosen for clearnet. Continue without https? (y/n): " NOCERTIFICATE + [[ "$NOCERTIFICATE" == "n" ]] && echo "Exiting..." && exit; + fi +fi read -p "Should robots.txt disallow compliant crawlers? (y/n): " ROBOTS_TXT_DISALLOW read -p "Allow google captcha in content-security policy? (y/n): " GOOGLE_CAPTCHA read -p "Allow Hcaptcha in content-security policy? (y/n): " H_CAPTCHA read -p "Download and setup geoip for post flags? (y/n): " GEOIP -read -p "Use certbot to install letsencrypt certificate for https? (y/n): " LETSENCRYPT #looks good? read -p "Is this correct? @@ -23,6 +33,10 @@ jschan directory: $JSCHAN_DIRECTORY clearnet domain: $CLEARNET_DOMAIN .onion address: $ONION_DOMAIN .loki address: $LOKI_DOMAIN +www subdomains: $ADD_WWW_SUBDOMAIN +certbot https cert: $CERTBOT +self-signed https cert: $SELFSIGNED +no https cert: $NOCERTIFICATE robots.txt disallow all: $ROBOTS_TXT_DISALLOW google captcha: $GOOGLE_CAPTCHA hcaptcha: $H_CAPTCHA @@ -37,6 +51,10 @@ if [[ -f /etc/nginx/sites-available/$SITES_AVAILABLE_NAME ]]; then [[ "$OVERWRITE" == "n" ]] && echo "Exiting..." && exit; fi +echo "Stopping nginx..." +sudo systemctl stop nginx + +echo "Copying snippets to nginx folder & replacing paths..." #copy the snippets and replace install path, they aren't templated sudo cp $JSCHAN_DIRECTORY/configs/nginx/snippets/* /etc/nginx/snippets sudo sed -i "s|/path/to/jschan|$JSCHAN_DIRECTORY|g" /etc/nginx/snippets/* @@ -46,13 +64,66 @@ JSCHAN_CONFIG="upstream chan { server 127.0.0.1:7000; }" +#Use some variabels to make the templating easier later, depending on if they want www. or not +CLEARNET_SERVER_NAME="$CLEARNET_DOMAIN" +LOKI_SERVER_NAME="$LOKI_DOMAIN" +ONION_SERVER_NAME="$ONION_DOMAIN" +if [ "$ADD_WWW_SUBDOMAIN" == "y" ]; then + CLEARNET_SERVER_NAME="$CLEARNET_DOMAIN www.$CLEARNET_DOMAIN" + LOKI_SERVER_NAME="$LOKI_DOMAIN www.$LOKI_DOMAIN" + ONION_SERVER_NAME="$ONION_DOMAIN www.$ONION_DOMAIN" +fi + if [ "$CLEARNET_DOMAIN" != "" ]; then - if [ "$LETSENCRYPT" == "y" ]; then + HTTPS_MIDSECTION="" + HTTPS_CERT_SECTION="" + if [ "$CERTBOT" == "y" ]; then #run certbot for certificate - sudo certbot certonly --standalone -d $CLEARNET_DOMAIN -d www.$CLEARNET_DOMAIN + if [ "$ADD_WWW_SUBDOMAIN" == "y" ]; then + echo "Running certbot to get SSL cert for $CLEARNET_DOMAIN and www.$CLEARNET_COMAIN..." + sudo certbot certonly --standalone -d $CLEARNET_DOMAIN -d www.$CLEARNET_DOMAIN + else + echo "Running certbot to get SSL cert for $CLEARNET_DOMAIN..." + sudo certbot certonly --standalone -d $CLEARNET_DOMAIN + fi + HTTPS_CERT_SECTION=" + ssl_certificate /etc/letsencrypt/live/$CLEARNET_DOMAIN/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/$CLEARNET_DOMAIN/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + " + elif [[ "$SELFSIGNED" == "y" ]]; then + read -p "Warning: no https certificate chosen for clearnet. Continue without any https? (y/n): " NOCERTIFICATE + if [[ "$NOCERTIFICATE" == "n" ]]; then + echo "Exiting..." + exit; + else + + fi fi + if [ "$CERTBOT" == "y" ] + HTTPS_MIDSECTION=" + listen [::]:443 ssl ipv6only=on; + listen 443 ssl; + $HTTPS_CERT_SECTION + +} + +server { + if (\$host = www.$CLEARNET_DOMAIN) { + return 301 https://\$host\$request_uri; + } + + if (\$host = $CLEARNET_DOMAIN) { + return 301 https://\$host\$request_uri; + } + + server_name $CLEARNET_SERVER_NAME; + return 444; + " + #onion_location rediret header ONION_LOCATION="" if [ "$ONION_DOMAIN" != "" ]; then @@ -63,41 +134,24 @@ if [ "$CLEARNET_DOMAIN" != "" ]; then JSCHAN_CONFIG="${JSCHAN_CONFIG} server { - server_name www.$CLEARNET_DOMAIN $CLEARNET_DOMAIN; + server_name $CLEARNET_SERVER_NAME; client_max_body_size 0; $ONION_LOCATION - listen [::]:443 ssl ipv6only=on; # managed by Certbot - listen 443 ssl; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/$CLEARNET_DOMAIN/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/$CLEARNET_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 - include /etc/nginx/snippets/security_headers.conf; include /etc/nginx/snippets/error_pages.conf; include /etc/nginx/snippets/jschan_clearnet_routes.conf; include /etc/nginx/snippets/jschan_common_routes.conf; -} - -server { - if (\$host = www.$CLEARNET_DOMAIN) { - return 301 https://\$host\$request_uri; - } # managed by Certbot - - if (\$host = $CLEARNET_DOMAIN) { - return 301 https://$host\$request_uri; - } # managed by Certbot - - server_name www.$CLEARNET_DOMAIN $CLEARNET_DOMAIN; +$HTTPS_MIDSECTION + listen 80; listen [::]:80; - return 444; # managed by Certbot }" #replace clearnet domain in snippets + echo "Replacing clearnet domain in snippets..." sudo sed -i "s/example.com/$CLEARNET_DOMAIN/g" /etc/nginx/snippets/* fi @@ -122,10 +176,12 @@ server { }" #replace onion domain in snippets + echo "Replacing onion domain in snippets..." sudo sed -i "s/example.onion/$ONION_DOMAIN/g" /etc/nginx/snippets/* else #no onion, remove it from CSP + echo "No onion, removing example.onion from CSP..." sudo sed -i 's/ wss:\/\/www.example.onion\/ wss:\/\/example.onion\///g' /etc/nginx/snippets/security_headers* fi @@ -148,24 +204,29 @@ server { }" #replace lokinet domain in snippets + echo "Replacing loki domain in snippets..." sudo sed -i "s/example.loki/$LOKI_DOMAIN/g" /etc/nginx/snippets/* else #no lokinet, remove it from csp + echo "No lokinet, removing example.loki from CSP..." sudo sed -i 's/ wss:\/\/www.example.loki\/ wss:\/\/example.loki\///g' /etc/nginx/snippets/security_headers* fi #write the config to file and syymlink to sites-available +echo "Writing main jschan vhost config..." printf "$JSCHAN_CONFIG" > /etc/nginx/sites-available/$SITES_AVAILABLE_NAME sudo ln -s -f /etc/nginx/sites-available/$SITES_AVAILABLE_NAME /etc/nginx/sites-enabled/$SITES_AVAILABLE_NAME if [ "$GOOGLE_CAPTCHA" == "y" ]; then + echo "Allowing recaptcha in CSP..." #add google captcha CSP exceptions sudo sed -i "s|script-src|script-src https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ |g" /etc/nginx/snippets/* sudo sed -i "s|frame-src|frame-src https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/ |g" /etc/nginx/snippets/* fi if [ "$H_CAPTCHA" == "y" ]; then + echo "Allowing hcaptcha in CSP..." #add hcaptcha CSP exceptions sudo sed -i "s|script-src|script-src https://hcaptcha.com https://*.hcaptcha.com |g" /etc/nginx/snippets/* sudo sed -i "s|frame-src|frame-src https://hcaptcha.com https://*.hcaptcha.com |g" /etc/nginx/snippets/* @@ -174,12 +235,13 @@ if [ "$H_CAPTCHA" == "y" ]; then fi if [ "$ROBOTS_TXT_DISALLOW" == "y" ]; then + echo "Setting robots.txt to disallow all..." #add path / (all) to disallow to make robots.txt block all robots instead of allowing sudo sed -i "s|Disallow:|Disallow: /|g" /etc/nginx/snippets/jschan_common_routes.conf fi if [ "$GEOIP" == "y" ]; then - + echo "Downloading and installing geoip database for nginx..." #download geoip data cd /usr/share/GeoIP mv GeoIP.dat GeoIP.dat.bak @@ -195,8 +257,11 @@ if [ "$GEOIP" == "y" ]; then geoip_country /usr/share/GeoIP/GeoIP.dat;' /etc/nginx/nginx.conf fi else + echo "Geoip not installed, removing directives..." sudo sed '/geoip_country/d' /etc/nginx/nginx.conf + sudo sed '/geoip_country_code/d' /etc/nginx/snippets/jschan_clearnet_routes.conf fi +echo "Restarting nginx..." #and restart nginx sudo systemctl restart nginx