Я использую nginx в качестве терминатора TLS перед сервером Apache 2.4.
я использую add_header X-Content-Type-Options nosniff;
в nginx, чтобы добавить этот заголовок к каждому ответу.
Если код статуса HTTP, возвращаемый Apache, ниже 400, заголовок установлен правильно, но если статус больше или равен 400, заголовок опускается.
То же самое для модуля gzip. Если код состояния ниже 500, модуль gzip автоматически сжимает тело ответа. Но если код состояния HTTP, возвращаемый Apache, больше или равен 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;
}
/ и т.д. / nginx / сайты-включен / по умолчанию
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;
}
/ и т.д. / nginx / сайты с поддержкой / субдомен
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;
}
}
/ и т.д. / 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;
/ и т. д. / nginx / временная ошибка_парамс
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 labs здесь: https://community.qualys.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), поле заголовка будет добавлено независимо от кода ответа.
Это помогает, и теперь для каждого ответа (включая ошибки) все заголовки установлены должным образом.