nginx安全设置模板
# cat nginx.conf
user nobody;
worker_processes 4;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log error;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535;
multi_accept off;
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
log_format json '{"@timestamp":"$time_iso8601",'
'"server_addr":"$server_addr",'
'"server_name":"$server_name",'
'"server_port":"$server_port",'
'"server_protocol":"$server_protocol",'
'"client_ip":"$remote_addr",'
'"client_user":"$remote_user",'
'"status":"$status",'
'"request_method": "$request_method",'
'"request_length":"$request_length",'
'"request_time":"$request_time",'
'"request_url":"$request_uri",'
'"request_line":"$request",'
'"send_client_size":"$bytes_sent",'
'"send_client_body_size":"$body_bytes_sent",'
'"proxy_protocol_addr":"$proxy_protocol_addr",'
'"proxy_add_x_forward":"$proxy_add_x_forwarded_for",'
'"proxy_port":"$proxy_port",'
'"proxy_host":"$proxy_host",'
'"upstream_host":"$upstream_addr",'
'"upstream_status":"$upstream_status",'
'"upstream_cache_status":"$upstream_cache_status",'
'"upstream_connect_time":"$upstream_connect_time",'
'"upstream_response_time":"$upstream_response_time",'
'"upstream_header_time":"$upstream_header_time",'
'"upstream_cookie_name":"$upstream_cookie_name",'
'"upstream_response_length":"$upstream_response_length",'
'"upstream_bytes_received":"$upstream_bytes_received",'
'"upstream_bytes_sent":"$upstream_bytes_sent",'
'"http_host":"$host",'
'"http_cookie":"$http_cooke",'
'"http_user_agent":"$http_user_agent",'
'"http_origin":"$http_origin",'
'"http_upgrade":"$http_upgrade",'
'"http_referer":"$http_referer",'
'"http_x_forward":"$http_x_forwarded_for",'
'"http_x_forwarded_proto":"$http_x_forwarded_proto",'
'"https":"$https",'
'"http_scheme":"$scheme",'
'"invalid_referer":"$invalid_referer",'
'"gzip_ratio":"$gzip_ratio",'
'"realpath_root":"$realpath_root",'
'"document_root":"$document_root",'
'"is_args":"$is_args",'
'"args":"$args",'
'"connection_requests":"$connection_requests",'
'"connection_number":"$connection",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher"}';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
server_tokens off;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_proxied any;
server {
listen 80 default_server;
server_name _;
return 403;
}
server {
listen 443 default_server ssl;
server_name _;
ssl_certificate cert/6339068_jump.jdd966.cn.pem;
ssl_certificate_key cert/6339068_jump.jdd966.cn.key;
return 444;
}
include conf.d/*.conf;
}
# cat conf.d/*.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name jump.jdd966.cn;
ssl_certificate cert/6339068_jump.jdd966.cn.pem;
ssl_certificate_key cert/6339068_jump.jdd966.cn.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
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;
ssl_prefer_server_ciphers off;
ssl_protocols TLSv1.2;
client_max_body_size 2048m;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header Content-Security-Policy "upgrade-insecure-requests;default-src 'self' 'unsafe-inline' 'unsafe-eval'";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Xss-Protection "1;mode=block";
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
add_header Permissions-Policy "camera=(),microphone=(),geolocation=();interest-cohort=()";
add_header Expect-CT "max-age=86400; enforce;";
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Opener-Policy same-origin;
add_header Cross-Origin-Resource-Policy same-origin;
location / {
allow 117.159.26.211;
deny all;
proxy_pass http://10.0.0.5:81;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
access_log /var/log/nginx/jumpjson.access.log json;
}
有关说明:
参考手册地址:
HTTP 安全响应头(Security Response header)配置手册: https://zhuanlan.zhihu.com/p/335165168
火狐浏览器关于 http响应头的说明: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers
在线监测网站web等级:https://securityheaders.com/
前端安全配置xss预防针Content-Security-Policy(csp)配置详解:https://www.xaheimi.com/jianzhan/117.html
其中:
add_header Content-Security-Policy "upgrade-insecure-requests;default-src 'self' 'unsafe-inline' 'unsafe-eval'";
jumpserver堡垒机依赖于 'unsafe-inline', elk中的kibana依赖于 'unsafe-eval'
-
当存在unsafe-inline,unsafe-eval时,网站web等级是A
-
当不存在unsafe-inline,unsafe-eval时,网站web等级是A+ (最高等级)
代价是前端页面中的js无法运行,导致页面错乱
正常显示
非正常显示
访问kibana页面直接报错
另外portainer软件,有引用外部js文件的,以及通过data来请求咨询 (比如用Base64 编码过的图片)的,因此有些策略需要调整一下
add_header Content-Security-Policy "upgrade-insecure-requests;default-src 'self' 'unsafe-inline' 'unsafe-eval';script-src-elem 'self' cdn.matomo.cloud 'unsafe-eval' 'unsafe-inline';font-src 'self' data:;img-src 'self' data:;connect-src 'self' portainer-ce.matomo.cloud";
add_header Expect-CT "max-age=86400; enforce;";
#add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Embedder-Policy credentialless;
add_header Cross-Origin-Opener-Policy same-origin;
#add_header Cross-Origin-Resource-Policy same-origin;
add_header Cross-Origin-Resource-Policy cross-origin;
此时web等级还是A
总结:有关请求头的完整配置
add_header Strict-Transport-Security "max-age=63072000" always;
# 根据情况来定
add_header Content-Security-Policy "upgrade-insecure-requests;default-src 'self' 'unsafe-inline' 'unsafe-eval'";
#add_header Content-Security-Policy "upgrade-insecure-requests;default-src 'self' 'unsafe-inline' 'unsafe-eval';script-src-elem 'self' cdn.matomo.cloud 'unsafe-eval' 'unsafe-inline';font-src 'self' data:;img-src 'self' data:;connect-src 'self' portainer-ce.matomo.cloud";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Xss-Protection "1;mode=block";
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
add_header Permissions-Policy "camera=(),microphone=(),geolocation=();interest-cohort=()";
add_header Expect-CT "max-age=86400; enforce;";
add_header Cross-Origin-Opener-Policy same-origin;
# 根据情况来定
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Resource-Policy same-origin;
#add_header Cross-Origin-Embedder-Policy credentialless;
#add_header Cross-Origin-Resource-Policy cross-origin;
add_header Set-Cookie "Max-Age=21600;Secure;HttpOnly;SameSite=Strict;Path=/";
add_header X-Download-Options value;
add_header X-Permitted-Cross-Domain-Policies master-only;