我有一堆客户(太多而无法轻松改造),每个客户都持有一个证书(由我无法控制的非标准 CA 签名;我刚刚生成了 CSR)。
现在我需要设置一个“安全”的 Web 服务,其中服务器以通常的 ssl (https) 方式标识,客户端应该使用其证书来标识(主题已经保存了我唯一标识客户端所需的所有信息)。
不幸的是,在签名过程中,几乎所有“目的”标志都被清除了:
openssl x509 -in 57EMM020001.cer -noout -purpose
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : No
SSL server CA : No
Netscape SSL server : No
Netscape SSL server CA : No
S/MIME signing : Yes
S/MIME signing CA : No
S/MIME encryption : No
S/MIME encryption CA : No
CRL signing : No
CRL signing CA : No
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : No
Time Stamp signing : No
Time Stamp signing CA : No
我假设“400 SSL证书错误”的“罪魁祸首”是第一个:“SSL客户端:否”。
有没有办法告诉我的本地 nginx 服务器(我可以完全控制它)忽略这些设置?
我完全理解这通常是“不好的”,因为如果没有为特定目的生成证书......那么,它不应该用于该目的!但这是我非常具体的服务器,我觉得我有权决定我信任谁。
有什么方法可以说服 nginx 以稍微宽松的方式做事吗?
我当前(不工作)的设置非常简单:
server {
listen 443 ssl;
resolver 127.0.0.1 8.8.8.8;
set $backend "http://localhost:5000";
server_name updates.example.com;
ssl_certificate /etc/ssl/certs/server.pem;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_client_certificate /etc/ssl/certs/CAroot.cer;
ssl_verify_client on;
location / {
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_intercept_errors off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Client-Subject $ssl_client_s_dn;
proxy_pass $backend;
}
}
当然,我检查了:
openssl verify -verbose -CAfile /etc/ssl/certs/CAroot.cer 57EMM020001.cer
57EMM020001.cer: OK
提前致谢
我找到了一个可行的解决方案,但这并不是很优雅,所以我会暂时不接受它,希望有人能提出更好的解决方案。
删除
ssl_client_certificate
并切换到ssl_verify_client optional_no_ca
实际上会获取客户端证书,但它不会尝试检查它,因此后端可以自主进行检查。我当前的 nginx 设置是:
后端(一个简单的 python/flask 安装)包括: