我有 nginx,想让它验证客户端证书。所以我为服务器购买了商业证书,为客户端购买了非商业证书。基本上,我已经使用 easy-rsa 脚本生成了客户端证书。禁用客户端证书验证后连接工作正常。使用“ssl_verify_client on;”连接失败,代码为 400,错误或访问日志中没有任何信息。
nginx -V 输出:
nginx version: nginx/1.8.0
built with OpenSSL 1.0.2a 19 Mar 2015
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/bin/nginx --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --user=http --group=http --http-log-path=/var/log/nginx/access.log --error-log-path=stderr --http-client-body-temp-path=/var/lib/nginx/client-body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-imap --with-imap_ssl_module --with-ipv6 --with-pcre-jit --with-file-aio --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_realip_module --with-http_spdy_module --with-http_ssl_module --with-http_stub_status_module --with-http_addition_module --with-http_degradation_module --with-http_flv_module --with-http_mp4_module --with-http_secure_link_module --with-http_sub_module
我的 nginx 配置如下
server {
listen my.addr.here:443 ssl;
server_name my-server;
ssl on;
ssl_certificate /etc/nginx/ssl/my-server.crt;
ssl_certificate_key /etc/nginx/ssl/my-server.key;
ssl_dhparam /etc/nginx/ssl/my-server.dhparam;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_client_certificate /etc/nginx/ssl/client-ca.crt;
ssl_verify_client optional;
add_header X-Client-Certificate-Status $ssl_client_verify;
# unrelated stuff here
}
当我通过 OpenSSL 客户端进行测试时,像这样执行
openssl s_client -connect my-server:443 -cert client.crt -key client.key
我收到以下输出
openssl s_client -connect my-server:443 -cert client.crt -key client.key
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Multi-Domain, CN = my-server
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL Multi-Domain/CN=my-server
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
3 s:/OU=Domain Control Validated/OU=PositiveSSL Multi-Domain/CN=my-server
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGczCCBVugAwIBAgIRAO+Wb7x6RNHrhAhvUhGKg4EwDQYJKoZIhvcNAQELBQAw
................................................................
................................................................
/CEp3cHZNnU7JQbgq+r7R16oIONxthXGQQVjE36Bt9KS1ibpaIUThidUDCqzLYjn
IOKTJM0r8DVzO2leJDTnuDayOXCji/I=
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL Multi-Domain/CN=my-server
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 7198 bytes and written 474 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 727A........................................................1F7C
Session-ID-ctx:
Master-Key: 0019........................................................................................3CF8
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 0c 72 58 ce 43 33 3f 3f-aa e9 e1 e2 fa 9f 67 ae .rX.C3??......g.
.........................................................................
.........................................................................
00a0 - a4 14 27 fe 80 19 56 af-2d e6 f2 65 3b 0d cd e4 ..'...V.-..e;...
Start Time: 1433018240
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
请注意“未发送客户端证书 CA 名称”字符串,据我所知,这意味着 nginx 未正确配置以验证客户端证书。
当我发出这样的请求时
GET https://my-server/robots.txt HTTP/1.1
Host: my-server
我得到这样的输出
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 30 May 2015 20:37:38 GMT
Content-Type: text/plain
Content-Length: 103
Last-Modified: Sun, 12 Oct 2014 17:57:25 GMT
Connection: keep-alive
ETag: "543ac105-67"
Expires: Sat, 30 May 2015 20:37:37 GMT
Cache-Control: no-cache
X-Client-Certificate-Status: NONE
Accept-Ranges: bytes
User-agent: *
Disallow: /admin/
Host: my-server
请注意“X-Client-Certificate-Status”等于NONE,所以$ssl_client_verify 为NONE,所以不进行验证。
这可能是什么原因造成的?我该如何调试这个问题?
答案1
原因是 nginx 配置错误,SSL 选项指定了两次。