user www-data; worker_processes 1; error_log stderr; pid /run/nginx/nginx.pid; # Nginx requires this section, even if no options events { } # Note that a lot of these settings come from the OWASP Secure # Configuration guide for nginx # https://www.owasp.org/index.php/SCG_WS_nginx # and the OWASP Secure Headers project # https://www.owasp.org/index.php/OWASP_Secure_Headers_Project # and the mozilla security guidelines # https://wiki.mozilla.org/Security/Server_Side_TLS http { include mime.types; # For certain locations, only allow one connection per IP limit_conn_zone $binary_remote_addr zone=addr:10m; # Default log format log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # Comment out to enable access log in /var/log/nginx/ access_log off; client_body_timeout 30; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 30; # Do not return nginx version to clients server_tokens off; client_max_body_size 100k; client_body_buffer_size 100K; client_header_buffer_size 1k; large_client_header_buffers 4 8k; # redirect all http traffic to https server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name 127.0.0.1; ssl on; ssl_certificate @CERTPATH@/cert.pem; ssl_certificate_key @CERTPATH@/cert.pem; ssl_session_timeout 5m; ssl_protocols TLSv1.2; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"; ssl_prefer_server_ciphers on; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; location / { # This location lets us serve the static pre-compressed webui # content (rooted at /usr/share/www). Also if the URI points to # something else (that is unmatched by other locations), we # fallback to the rest server. This approach is based on the # guide at https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content. root /usr/share/www; # For clients that support gzip encoding, serve them # pre-compressed gzip content. For clients that don't, # uncompress on the BMC. The module gunzip requires # gzip_static to be set to 'always'; gzip_static is the # module that serves compressed content for clients that # support gzip. gunzip on; gzip_static always; try_files $uri $uri/ @rest_server; add_header X-Frame-Options deny; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options nosniff; add_header Content-Security-Policy "frame-ancestors 'none'; default-src 'self' wss: 'unsafe-eval' 'unsafe-inline'"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; add_header Cache-Control "no-store,no-cache"; add_header Pragma "no-cache"; add_header Expires 0; } location @rest_server { # Use 127.0.0.1 instead of localhost since nginx will # first use ipv6 address of ::1 which the upstream server # is not listening on. This generates an error msg to # the journal. Nginx then uses the 127.0.0.1 and everything # works fine but want to avoid the error msg to the log. proxy_pass http://127.0.0.1:8081; # WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $remote_addr; } location ~ (/org/openbmc/control/flash/bmc/action/update|/upload/image|/download/dump) { # Marked as 33MB to allow for firmware image updating and dump # downloads client_max_body_size 33M; # Only 1 connection at a time here from an IP limit_conn addr 1; proxy_pass http://127.0.0.1:8081; } location /redfish { proxy_pass http://127.0.0.1:8082; proxy_http_version 1.1; } include /etc/nginx/sites-enabled/443_*.conf; } }