Nginx Mutual Auth 消费 Rest API

Nginx Mutual Auth for consuming Rest API

我想保护我正在编写的一组 Web API。在订阅到期之前,必须向订阅者授予对这些 API 的访问权限; API 由远程 Web 服务使用。所以我认为 Mutual SSL 是最好的 这样做的方法。

我正在尝试设置我自己的 CA 以向客户颁发 x509 证书。

这是我第一次这样做;所以,自然地,没有任何效果。

这就是我想要得到的最终结果:我使用 Nginx 作为反向代理来部署我的 API;如果客户端向 Nginx 发送有效证书,则反向代理接受连接并转发请求;否则连接关闭。每当新客户签署订阅时,我都会生成一个新证书并将其发送到 him/her.

所以我遵循了 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 生成的证书?

如前所述,当您在 Nginx 中没有获得太多日志时,您应该添加

debug_connection <IP>;

它将生成更多日志。其中显示

2017/09/29 20:27:55 [info] 28783#0: *72 client SSL certificate verify error: (3:unable to get certificate CRL) while reading client request headers

当您没有为 ssl_client_certificate 链中的每个证书提供 CRL 时,会发生此错误。

以下是显示相同问题的类似帖子

https://serverfault.com/questions/501912/nginx-proxy-ssl-clr-400-bad-request-error

Nginx unable to get certificate CRL

您需要指定指令 ssl_crl 并为其提供 CRL 文件

  ssl_crl /etc/ssl/certs/crl/ca.crl;

此外,您应该验证 ssl_certificate 是指您的 CA 为您的服务器创建的证书:

ssl_certificate /etc/ssl/ca/certs/server.pem;       #signed by your CA

ssl_certificate_key /etc/ssl/ca/private/server.key; #PK used to generate 
                                                    #server.pem

ssl_client_certificate /etc/ssl/ca/certs/ca.crt;

ssl_crl /etc/ssl/ca/crl/ca.crl;                     #CRL of the
                                                    #ssl_client_certificate and
                                                    #its chain