【发布时间】:2017-09-29 18:34:45
【问题描述】:
我想保护我正在编写的一组 Web API。在订阅到期之前,必须向订阅者授予对这些 API 的访问权限; API 由远程 Web 服务使用。所以我认为 Mutual SSL 是最好的 这样做的方法。
我正在尝试设置自己的 CA 以向客户端颁发 x509 证书。
这是我第一次这样做;所以,自然而然地,什么都行不通。
这就是我想要得到的最终结果:我使用 Nginx 作为反向代理来部署我的 API;如果客户端向 Nginx 发送有效证书,反向代理接受连接并转发请求;否则连接将关闭。每当新客户签署订阅时,我都会生成一个新证书并将其发送给他/她。
所以我遵循this 指南,在我看来这比我阅读的其他指南更完整,我在/etc/ssl/ca/cert 中添加了一个自签名的ca.crt 用于签署来自客户和我的CSRs将 nginx 设置为
server {
listen *:443 ssl;
server_name api.example.com;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_certificate /etc/ssl/certs/server.pem; #certificate from an actual CA
ssl_certificate_key /etc/ssl/private/server.key; #PK of server.pem
ssl_client_certificate /etc/ssl/ca/certs/ca.crt;
ssl_crl /etc/ssl/ca/crl/ca.crl;
ssl_verify_client on;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on; #ensure your cert is capable
ssl_stapling_verify on; #ensure your cert is capable
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
#Redirects all traffic
location / {
proxy_pass http://mysecuredserver/api$request_uri;
limit_req zone=one burst=10;
}
}
但是当我使用Test api(它总是以200 OK 响应)使用
curl -k -v --key key.pem --cert cert.pem https://api.example.com/Test
我总是收到以下错误:
< HTTP/1.1 400 Bad Request
* Server nginx is not blacklisted
< Server: nginx
< Date: Fri, 29 Sep 2017 18:00:16 GMT
< Content-Type: text/html
< Content-Length: 224
< Connection: close
<
<html>
<head><title>400 The SSL certificate error</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The SSL certificate error</center>
<hr><center>nginx</center>
</body>
</html>
* Closing connection 0
* SSLv3, TLS alert, Client hello (1):
谁能给我解释一下怎么回事?
第二个问题:在ssl_certificate 中我放置了从有效 CA 购买的证书:是正确的还是应该放置使用 ca.crt 生成的证书来代替?
【问题讨论】:
-
步步为营。你想一次迈出这一步。
Step 1. Your SSL certificate works。所以删除ssl_verify_client on; ssl_client_certificate /etc/ssl/ca/certs/ca.crt;。使用curl -v https://api.example.com/Test看看您是否可以正常连接。第 2 步 - 添加客户端证书并使验证可选。添加ssl_verify_client optional;ssl_client_certificate /etc/ssl/ca/certs/ca.crt;。在location /添加`return 200“客户端证书状态 - $ssl_client_verify”。这将告诉您服务器是否能够验证证书 -
第 1 步:工作正常。第 2 步,
ssl_verify_client optional:400 错误请求,相同消息 -
更改
ssl_verify_client off然后尝试一下,nginx 日志说什么? -
它连接:我附加 curl 输出
-
/var/log/nginx/error.log 什么也没说 2017/09/29 19:52:43 [通知] 28279#0: 信号处理开始于 2017/09/29 19:53 :53 [通知] 28300#0: 信号处理开始 2017/09/29 19:54:29 [通知] 28312#0: 信号处理开始