通過 nginx 代理 http 錯誤時,http 標頭消失
我在 Apache 2.4 伺服器前使用 nginx 作為 TLS 終結器。
我
add_header X-Content-Type-Options nosniff;
在 nginx 中使用將此標頭添加到每個響應中。如果 Apache 返回的 HTTP 狀態程式碼低於 400,則標頭設置正確,但如果狀態大於或等於 400,則省略標頭。
gzip 模組也是如此。如果狀態碼低於 500,gzip 模組會自動壓縮響應體。但是如果 Apache 得到的 HTTP 狀態碼大於或等於 500,gzip 模組什麼也不做。
我的 nginx 配置的一些相關部分:
proxy_intercept_errors off; proxy_ignore_client_abort off; proxy_http_version 1.1; proxy_hide_header X-Powered-By; proxy_set_header Connection ""; #for keepalive to backend add_header X-Content-Type-Options nosniff; ### gzip ### gzip on; gzip_min_length 20; #default: 20 gzip_comp_level 9; gzip_proxied any; gzip_vary on; gzip_types *; gunzip on;
我可以做些什麼來停用此行為並將我的標頭添加到 HTTP 錯誤響應甚至 gzip HTTP 500 響應中?
編輯:這是我的其餘配置:
/etc/nginx/nginx.conf
user proxy; worker_processes 4; # 2 * num_cpus worker_priority -20; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*; events { worker_connections 32768; multi_accept on; use epoll; } worker_rlimit_nofile 70000; # slightly more than double of worker_connections http { types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
/etc/nginx/mime.types 是標準的 debian 文件。
在 /etc/nginx/modules-enabled 中有以下模組:
50-mod-http-auth-pam.conf 50-mod-http-dav-ext.conf 50-mod-http-echo.conf 50-mod-http-geoip.conf 50-mod-http-image-filter.conf 50-mod-http-subs-filter.conf 50-mod-http-upstream-fair.conf 50-mod-http-xslt-filter.conf 50-mod-mail.conf 50-mod-stream.conf
/etc/nginx/conf.d/sslproxy.conf
### global ### server_tokens off; server_name_in_redirect off; ignore_invalid_headers on; if_modified_since before; root /etc/nginx/content/; ssi off; ssi_silent_errors on; # testing=off limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; #all configured cache paths proxy_cache_path /var/lib/nginx/proxy/all keys_zone=all:64m inactive=168h; #7 tage proxy_cache_path /var/lib/nginx/proxy/temporaryerror keys_zone=temporaryerror:16m inactive=24h; #standard cache proxy_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503 http_504; proxy_cache_key "$request_method|$scheme://$server_name$uri$is_args$args"; proxy_temp_path /var/lib/nginx/tmp; proxy_cache_min_uses 1; proxy_cache_lock on; proxy_cache all; ### tcp ### tcp_nodelay on; tcp_nopush off; sendfile off; keepalive_requests 100; ### timeouts ### client_header_timeout 60; client_body_timeout 60; send_timeout 900; #keepalive_disable none; #was: non existent keepalive_timeout 300 300; ### gzip ### gzip on; gzip_min_length 20; #default: 20 gzip_comp_level 9; gzip_proxied any; gzip_vary on; gzip_types *; #text/* application/x-javascript; gunzip on; ### buffers ### client_header_buffer_size 4k; client_body_buffer_size 8m; large_client_header_buffers 4 8k; client_max_body_size 128m; output_buffers 1 32k; postpone_output 0; ssl_buffer_size 4k; ### errors ### recursive_error_pages on; error_page 401 402 403 405 406 407 408 409 410 411 413 414 415 416 417 421 422 423 424 426 428 429 431 451 /temporary_error.php; error_page 500 501 502 503 504 /temporary_error.php; error_page 404 =410 /temporary_error.php; error_page 443 =200 /temporary_error.php; ### acl ### deny all; ### ssl ### ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2; ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256"; ssl_ecdh_curve X25519:secp521r1:secp384r1; ssl_dhparam /etc/nginx/ssl/dhparam.pem; ssl_session_cache off; ssl_session_timeout 60m; ssl_session_tickets on; ssl_session_ticket_key /run/nginx_session_ticket.key; ssl_stapling on; resolver 127.0.0.1:53 valid=4s; resolver_timeout 8s; ssl_stapling_verify on; ssl_trusted_certificate /etc/nginx/ssl/trusted_certs.pem; ssl_client_certificate /etc/nginx/ssl/trusted_certs.pem;
/etc/nginx/conf.d/upstream.conf
upstream backend { server 127.0.0.1:8080; keepalive 32; } upstream remote { server 10.10.0.2:8080; keepalive 32; }
/etc/nginx/sites-enabled/default
server { ssl on; ssl_certificate ssl/www.example.org.crt; ssl_certificate_key ssl/www.example.org.key; listen [::]:443 ssl http2 default_server backlog=256 fastopen=256 so_keepalive=30s:1m:8; listen 443 ssl http2 default_server backlog=256 fastopen=256 so_keepalive=30s:1m:8; server_name ""; allow all; return 400; }
/etc/nginx/sites-enabled/子域
server { ssl on; ssl_certificate ssl/subdomain.example.org.crt; ssl_certificate_key ssl/subdomain.example.org.key; listen [::]:443 ssl http2; listen 443 ssl http2; allow all; server_name subdomain.example.org; location = /temporary_error.php { include /etc/nginx/proxy_params; include /etc/nginx/temporaryerror_params; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; proxy_pass http://remote; } location / { include /etc/nginx/proxy_params; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; proxy_pass http://remote; } }
/etc/nginx/proxy_params
proxy_intercept_errors off; proxy_ignore_client_abort off; #proxy_redirect off; proxy_connect_timeout 4; proxy_send_timeout 16; proxy_read_timeout 900; proxy_http_version 1.1; add_header X-Content-Type-Options nosniff; #proxy_set_header Accept-Encoding ""; proxy_set_header Host $server_name; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-By $server_addr:$server_port; proxy_set_header X-Forwarded-Proto $scheme; proxy_hide_header X-Powered-By; proxy_hide_header X-Accel-Expires; proxy_hide_header X-Accel-Buffering; proxy_set_header Connection ""; #for keepalive proxy_buffering off; proxy_buffers 32 4k; proxy_buffer_size 4k; proxy_busy_buffers_size 16k; proxy_max_temp_file_size 0; limit_conn perip 128; limit_conn perserver 512;
/etc/nginx/temporaryerror_params
proxy_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404; proxy_cache_key "$request_method|$scheme://$server_name$uri$is_args$args"; proxy_temp_path /var/lib/nginx/tmp; proxy_cache_min_uses 1; proxy_cache_lock on; proxy_cache temporaryerror;
我希望這有幫助。
今天我在這裡的 ssl 實驗室執行緒中偶然發現了解決方案: https ://community.quallys.com/thread/17333-hsts-header-not-being-set-by-nginx-on-error
基本上你必須在配置選項中添加
always
關鍵字。add_header
引用 nginx 文件(http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header):如果指定了 always 參數(1.7.5),則無論響應程式碼如何,都將添加標頭欄位。
這很有幫助,現在每個響應(包括錯誤)都按預期設置了所有標頭。