From 2be99ba163c56d28b9372f407922baac56bd2b71 Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Fri, 23 Aug 2024 19:24:21 -0400 Subject: [PATCH 1/6] feat: harden nginx relay configuration --- pkg/network/nginx_https.go | 68 ++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index eb6c2a4..624e8af 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -32,9 +32,15 @@ upstream websocket { server { listen 443 ssl; listen [::]:443 ssl; + http2 on; server_name %s; + root /var/www/%s; + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying 404. + try_files $uri $uri/ =404; proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; @@ -44,24 +50,66 @@ server { } #### SSL Configuration #### + # Test configuration: + # https://www.ssllabs.com/ssltest/analyze.html + # https://cryptcheck.fr/ ssl_certificate /etc/letsencrypt/live/%s/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/%s/privkey.pem; + # Verify chain of trust of OCSP response using Root CA and Intermediate certs + ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 10m; - ssl_protocols TLSv1.2 TLSv1.1 TLSv1; + # Only return Nginx in server header + server_tokens off; + + # TODO + # Add support to generate the file in the script + #ssl_dhparam /etc/ssl/certs/dhparam.pem; + + ssl_protocols TLSv1.2 TLSv1.3; + + # For more information on the security of different cipher suites, you can refer to the following link: + # https://ciphersuite.info/ + # Compilation of the top cipher suites 2024: + # https://ssl-config.mozilla.org/#server=nginx + 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:DHE-RSA-CHACHA20-POLY1305"; + + # Perfect Forward Secrecy (PFS) is frequently compromised without this ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; + + ssl_session_tickets off; + + # Enable SSL session caching for improved performance + # Try setting ssl_session_timeout to 1d if performance is bad + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + + # By default, the buffer size is 16k, which corresponds to minimal overhead when sending big responses. + # To minimize Time To First Byte it may be beneficial to use smaller values + ssl_buffer_size 8k; + + # OCSP stapling ssl_stapling on; ssl_stapling_verify on; - ssl_ecdh_curve secp384r1; - add_header Strict-Transport-Security "max-age=31536000; includeSubdomains"; + # Security headers + # Test configuration: + # https://securityheaders.com/ + # https://observatory.mozilla.org/ + add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; + add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header Referrer-Policy same-origin; - add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;"; + + # Avoid MIME type sniffing + add_header X-Content-Type-Options nosniff always; + + add_header Referrer-Policy "no-referrer" always; + + add_header X-XSS-Protection 0 always; + + add_header Permissions-Policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()" always; + + # Content-Security-Policy (CSP) + add_header Content-Security-Policy "base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;" always; } server { From 1d8dd798dbaa4833d4ceced7dfa96963d2b738c8 Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Mon, 26 Aug 2024 10:58:52 -0400 Subject: [PATCH 2/6] chore: update nginx_https.go config format --- pkg/network/nginx_https.go | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index 624e8af..a7d905e 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -32,16 +32,16 @@ upstream websocket { server { listen 443 ssl; listen [::]:443 ssl; - http2 on; + http2 on; server_name %s; - root /var/www/%s; + root /var/www/%s; location / { - # First attempt to serve request as file, then - # as directory, then fall back to displaying 404. - try_files $uri $uri/ =404; - proxy_pass http://websocket; + # First attempt to serve request as file, then + # as directory, then fall back to displaying 404. + try_files $uri $uri/ =404; + proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; @@ -50,26 +50,26 @@ server { } #### SSL Configuration #### - # Test configuration: + # Test configuration: # https://www.ssllabs.com/ssltest/analyze.html - # https://cryptcheck.fr/ + # https://cryptcheck.fr/ ssl_certificate /etc/letsencrypt/live/%s/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/%s/privkey.pem; - # Verify chain of trust of OCSP response using Root CA and Intermediate certs - ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; + # Verify chain of trust of OCSP response using Root CA and Intermediate certs + ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; - # Only return Nginx in server header + # Only return Nginx in server header server_tokens off; - # TODO - # Add support to generate the file in the script + # TODO + # Add support to generate the file in the script #ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_protocols TLSv1.2 TLSv1.3; - # For more information on the security of different cipher suites, you can refer to the following link: + # For more information on the security of different cipher suites, you can refer to the following link: # https://ciphersuite.info/ - # Compilation of the top cipher suites 2024: + # Compilation of the top cipher suites 2024: # https://ssl-config.mozilla.org/#server=nginx 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:DHE-RSA-CHACHA20-POLY1305"; @@ -92,9 +92,9 @@ server { ssl_stapling_verify on; # Security headers - # Test configuration: - # https://securityheaders.com/ - # https://observatory.mozilla.org/ + # Test configuration: + # https://securityheaders.com/ + # https://observatory.mozilla.org/ add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; add_header X-Frame-Options DENY; @@ -109,7 +109,7 @@ server { add_header Permissions-Policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()" always; # Content-Security-Policy (CSP) - add_header Content-Security-Policy "base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;" always; + add_header Content-Security-Policy "base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;" always; } server { From 86f1211d9d7575b03221991086e0128bd1b83dd2 Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Mon, 2 Sep 2024 19:11:15 -0400 Subject: [PATCH 3/6] fix: update nginx config to work with debian apt version --- pkg/network/nginx_https.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index a7d905e..168b322 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -30,9 +30,8 @@ upstream websocket { } server { - listen 443 ssl; - listen [::]:443 ssl; - http2 on; + listen 443 ssl http2; + listen [::]:443 ssl http2; server_name %s; root /var/www/%s; @@ -55,8 +54,6 @@ server { # https://cryptcheck.fr/ ssl_certificate /etc/letsencrypt/live/%s/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/%s/privkey.pem; - # Verify chain of trust of OCSP response using Root CA and Intermediate certs - ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; # Only return Nginx in server header server_tokens off; From 4e97018a0c4825d930cb00665a9cc7429547879a Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Mon, 2 Sep 2024 19:34:53 -0400 Subject: [PATCH 4/6] fix: add dirName argument --- pkg/network/nginx_https.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index 168b322..117d3b7 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -123,7 +123,7 @@ server { return 301 https://%s$request_uri; } } -`, domainName, domainName, domainName, domainName, dirName, domainName) +`, domainName, dirName, domainName, domainName, domainName, dirName, domainName) err = os.WriteFile("/etc/nginx/conf.d/nostr_relay.conf", []byte(configContent), 0644) if err != nil { From 8e5bb4d127bf8c9c3a28f4a3cbec503482e0198a Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Mon, 2 Sep 2024 20:23:32 -0400 Subject: [PATCH 5/6] feat: add ssl trusted certificate --- pkg/network/nginx_https.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index 117d3b7..28ecebf 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -54,6 +54,8 @@ server { # https://cryptcheck.fr/ ssl_certificate /etc/letsencrypt/live/%s/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/%s/privkey.pem; + # Verify chain of trust of OCSP response using Root CA and Intermediate certs + ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; # Only return Nginx in server header server_tokens off; @@ -123,7 +125,7 @@ server { return 301 https://%s$request_uri; } } -`, domainName, dirName, domainName, domainName, domainName, dirName, domainName) +`, domainName, dirName, domainName, domainName, domainName, domainName, dirName, domainName) err = os.WriteFile("/etc/nginx/conf.d/nostr_relay.conf", []byte(configContent), 0644) if err != nil { From f81f5085a930cdf81c74820952dacfac6dcb3712 Mon Sep 17 00:00:00 2001 From: J the Code Monkey Date: Mon, 2 Sep 2024 20:30:23 -0400 Subject: [PATCH 6/6] chore: format nginx https file --- pkg/network/nginx_https.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/network/nginx_https.go b/pkg/network/nginx_https.go index 28ecebf..8f0a39c 100644 --- a/pkg/network/nginx_https.go +++ b/pkg/network/nginx_https.go @@ -54,8 +54,8 @@ server { # https://cryptcheck.fr/ ssl_certificate /etc/letsencrypt/live/%s/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/%s/privkey.pem; - # Verify chain of trust of OCSP response using Root CA and Intermediate certs - ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; + # Verify chain of trust of OCSP response using Root CA and Intermediate certs + ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem; # Only return Nginx in server header server_tokens off;