我有 Nginx 1.10ssl_verify_client = on一切正常,只是服务器完成 TLS 握手并继续解析标头,即使客户端尚未发送证书。
可以通过发送没有客户端证书和非常大的 http 头的 http 请求来验证,nginx 返回“400 请求标头或 Cookie 太大“。
根据我们的安全审计员的说法,服务器应该无法进行 TLS 握手,因为解析标头“会增加可能的攻击面。
我的 nginx 配置:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name myserver.com;
ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem;
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/ca.pem;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
} }
答案1
我认为您需要要求使用 SNI 来避免标头检查。Nginx 必须确定服务器块是否与请求匹配,为此,它需要一个主机名。它可以在 TLS 握手期间从 SNI 获取主机名,但如果不使用 SNI,则需要从 http 标头中读取主机信息。
您可以通过为非 SNI 客户端请求设置默认服务器块处理程序来要求使用 SNI,该处理程序会拒绝这些连接。为此,请default_server
从主 SSL 服务器块中删除该指令,并在其上方添加一个显式默认服务器,该服务器 1) 侦听 443,2) 匹配没有主机名的请求,3) 始终返回 444。示例:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name "";
ssl_ciphers aNULL;
ssl_certificate /path/to/dummy.crt;
ssl_certificate_key /path/to/dummy.key;
return 444;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name myserver.com;
ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem;
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/ca.pem;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
} }
然后,默认服务器将处理任何不使用 SNI 的 SSL 请求。返回的 444 是 nginx 非标准代码,用于关闭连接。此结构还关闭了一个潜在的安全漏洞,默认服务器的证书可能会以意想不到的方式暴露资源。现在,nginx 将仅处理使用 SNI 且主机名与您的其他服务器块之一匹配的请求。