# cat /usr/local/etc/nginx/nginx.confload_module /usr/local/libexec/nginx/ngx_stream_module.so;load_module /usr/local/libexec/nginx/ngx_http_naxsi_module.so;load_module /usr/local/libexec/nginx/ngx_mail_module.so;load_module /usr/local/libexec/nginx/ngx_http_brotli_filter_module.so;load_module /usr/local/libexec/nginx/ngx_http_brotli_static_module.so;load_module /usr/local/libexec/nginx/ngx_http_js_module.so;load_module /usr/local/libexec/nginx/ngx_http_vhost_traffic_status_module.so;user www staff;worker_processes 1;#error_log /var/log/nginx/error.log;error_log syslog:server=unix:/var/run/log,facility=local6,nohostname warn;events { worker_connections 1024;}http {include mime.types;log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';log_format main_ext '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$host" sn="$server_name" ' 'rt=$request_time ' 'ua="$upstream_addr" us="$upstream_status" ' 'ut="$upstream_response_time" ul="$upstream_response_length" ' 'cs=$upstream_cache_status';log_format handshake '"$http_user_agent" "$ssl_ciphers" "$ssl_curves"';log_format anonymized ':: - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';#tcp_nopush on;# https intercept detectionjs_import /usr/local/opnsense/scripts/nginx/ngx_functions.js;js_set $tls_intercepted ngx_functions.check_intercept;# 200M should be big enough for file servers etc.client_max_body_size 200M;brotli_static on;brotli on;gzip_static on;gzip on;server_tokens off;sendfile Off;default_type application/octet-stream;keepalive_timeout 60;map $http_upgrade $connection_upgrade { default upgrade; '' close;}# Map used in location.conf for proxy_ssl_namemap $ssl_server_name $upstream_sni_name { default $ssl_server_name; '' $host;}include http_post/*.conf;# TODO add when core is ready for allowing nginx to serve the web interface# include nginx_web.conf;# UPSTREAM SERVERSupstream upstream<crypticnumbersandlettersupstream1> {server myfirstupstream.mydomain.de:8090 weight=1;}upstream upstream<crypticnumbersandlettersupstream2> {server mysecondupstream.mydomain.de:8080 weight=1;}include opnsense_http_vhost_plugins/*.conf;server { listen 80; listen [::]:80; listen 443 http2 ssl; listen [::]:443 http2 ssl; ssl_certificate_key /usr/local/etc/nginx/key/opnsense.mydomain.de.key; ssl_certificate /usr/local/etc/nginx/key/opnsense.mydomain.de.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_dhparam /usr/local/opnsense/data/OPNsense/Nginx/dh-parameters.4096.rfc7919; ssl_ciphers ECDHE-ECDSA-CAMELLIA256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CAMELLIA256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CAMELLIA128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CAMELLIA128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:ECDHE-RSA-AES128-SHA256; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_prefer_server_ciphers on; ssl_stapling off; sendfile On; server_name opnsense.mydomain.de; client_header_buffer_size 1k; large_client_header_buffers 4 8k; charset utf-8; access_log /var/log/nginx/opnsense.mydomain.de.access.log main; access_log /var/log/nginx/tls_handshake.log handshake; error_log /var/log/nginx/opnsense.mydomain.de.error.log error; satisfy any; #include tls.conf; error_page 403 /opnsense_error_403.html; error_page 404 /opnsense_error_404.html; error_page 405 /waf_denied.html; error_page 500 501 502 503 504 /opnsense_server_error.html; location = /opnsense_error_403.html { internal; root /usr/local/etc/nginx/views; } location = /opnsense_error_404.html { internal; root /usr/local/etc/nginx/views; } location = /opnsense_server_error.html { internal; root /usr/local/etc/nginx/views; } # location to ban the host permanently set $naxsi_extensive_log 0; location @permanentban { access_log /var/log/nginx/permanentban.access.log main; internal; add_header "Content-Type" "text/plain; charset=UTF-8" always; return 403 "You got banned permanently from this server."; } error_page 418 = @permanentban; location = /waf_denied.html { root /usr/local/etc/nginx/views; access_log /var/log/nginx/waf_denied.access.log main; } # block based on User Agents - stuff I have found over the years in my server log if ($http_user_agent ~* Python-urllib|Nmap|python-requests|libwww-perl|MJ12bot|Jorgee|fasthttp|libwww|Telesphoreo|A6-Indexer|ltx71|okhttp|ZmEu|sqlmap|LMAO/2.0|l9explore|l9tcpid|Masscan|zgrab|Ronin/2.0|Hakai/2.0) { return 418; } if ($http_user_agent ~ "Indy\sLibrary|Morfeus Fucking Scanner|MSIE [0-6]\.\d+") { return 418; } if ($http_user_agent ~ ^Mozilla/[\d\.]+$) { return 418; } location = /opnsense-report-csp-violation { include fastcgi_params; fastcgi_param QUERY_STRING $query_string; fastcgi_param SCRIPT_FILENAME /usr/local/opnsense/scripts/nginx/csp_report.php; fastcgi_param TLS-Cipher $ssl_cipher; fastcgi_param TLS-Protocol $ssl_protocol; fastcgi_param TLS-SNI-Host $ssl_server_name; fastcgi_param SERVER-UUID "<some-cryptic-numbers-and-letters>"; fastcgi_intercept_errors on; fastcgi_pass unix:/var/run/php-webgui.socket; } location /opnsense-auth-request { internal; fastcgi_pass unix:/var/run/php-webgui.socket; fastcgi_index index.php; fastcgi_param TLS-Cipher $ssl_cipher; fastcgi_param TLS-Protocol $ssl_protocol; fastcgi_param TLS-SNI-Host $ssl_server_name; fastcgi_param Original-URI $request_uri; fastcgi_param Original-HOST $host; fastcgi_param SERVER-UUID "<some-cryptic-numbers-and-letters>"; fastcgi_param SCRIPT_FILENAME /usr/local/opnsense/scripts/nginx/ngx_auth.php; fastcgi_param AUTH_SERVER "LDAP"; fastcgi_intercept_errors on; include fastcgi_params; } if ($scheme != "https") { return 302 https://$host$request_uri; } include <some-cryptic-numbers-and-letters>_pre/*.conf;location /myupstream1 { BasicRule wl:19; DeniedUrl "/waf_denied.html"; # IP ACL allow x1.y1.z1.0/24; allow x2.y2.0.0/16; allow x3.y3.z3.0/24; allow x4.y4.z4.0/24; allow x5.y5.z5.0/24; allow x6.y6.z6.154/32; allow x7.y7.z7.44/32; allow x8.y8.z8.0/24; deny all; satisfy any; autoindex off; auth_request /opnsense-auth-request; http2_push_preload on; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header Authorization $http_authorization; proxy_pass_header Authorization; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-TLS-Cipher $ssl_cipher; proxy_set_header X-TLS-Protocol $ssl_protocol; proxy_set_header X-TLS-SNI-Host $ssl_server_name; # proxy headers for backend server proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-TLS-Client-Intercepted $tls_intercepted; proxy_read_timeout 86400s; proxy_ignore_client_abort off; proxy_request_buffering on; proxy_max_temp_file_size 1024m; proxy_buffering on; proxy_pass http://upstream<yetanotercrypticnumbersandletters>; proxy_hide_header X-Powered-By; include <some-cryptic-numbers-and-letters>_post/*.conf;}location / { BasicRule wl:19; DeniedUrl "/waf_denied.html"; if ($scheme != "https") { return 302 https://$host$request_uri; } root /srv/crm; index index.html; autoindex off; http2_push_preload off; include <some-more-cryptic-numbers-and-letters>_post/*.conf;}location /myupstream2 { BasicRule wl:19; DeniedUrl "/waf_denied.html"; autoindex off; http2_push_preload on; proxy_set_header Host $host; proxy_set_header X-TLS-Cipher $ssl_cipher; proxy_set_header X-TLS-Protocol $ssl_protocol; proxy_set_header X-TLS-SNI-Host $ssl_server_name; # proxy headers for backend server proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-TLS-Client-Intercepted $tls_intercepted; proxy_ignore_client_abort off; proxy_request_buffering on; proxy_max_temp_file_size 1024m; proxy_buffering on; proxy_pass http://upstream<stillmorecrypticnumbersandletters>; proxy_hide_header X-Powered-By; include <third-set-of-cryptic-numbers-and-letters-with-hyphen>_post/*.conf;} include <some-cryptic-numbers-and-letters>_post/*.conf;}}stream { # LOG FORMATS log_format main '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; log_format anonymized ':: [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; # UPSTREAM SERVERS upstream upstream<crypticnumbersandlettersupstream1> { server myupstream1.mydomain.de:8090 weight=1; } upstream upstream<crypticnumbersandlettersupstream2> { server myupstream2.mydomain.de:8080 weight=1; } upstream upstream<crypticnumbersandlettersupstream3> { server w.x.y.z:443 weight=1; } # upstream maps include opnsense_stream_vhost_plugins/*.conf;}# mail {# }