使用 SSL 客户端证书身份验证的 Nginx 代理到后端

使用 SSL 客户端证书身份验证的 Nginx 代理到后端

我有两台服务器,都装有 nginx。服务器 A 正在监听 443,并配置为使用客户端 SSL 证书进行身份验证。

服务器B有一个内部进程需要通过nginx与服务器A进行通信。

我想在服务器 B 上配置 Nginx,使其监听 8080(不加密,因为都是本地通信)并将 proxy_pass 到 ServerA:443。

问题是如何注入客户端证书?我没有找到任何可以执行此操作的 proxy_xxxx 函数。

我确实知道如何使用 socat 做出类似的效果,但我的要求是使用 nginx。

答案1

传递客户端证书详细信息就足够了吗?

你可以加

proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

到您的配置,然后证书信息就可以通过 X-SSL-Cert 标头提供给服务器 B。

答案2

这个问题似乎很大程度上取决于版本。在 Ubuntu 14.04 LTS 上,默认的 nginx 是过时的 1.4。首先,您需要安装基于 PPA 的版本

https://leftshift.io/upgrading-nginx-to-the-latest-version-on-ubuntu-servers

演示如何使用:

sudo add-apt-repository ppa:nginx/stable
sudo aptitude safe-upgrade

你应该得到:

nginx -v
nginx version: nginx/1.8.0

来自@xatr0z 答案的配置https://serverfault.com/a/636455/162693指向 http://www.senginx.org/en/index.php/Proxy_HTTPS_Client_Certificate 不起作用:

不可行的提案

backend {
    server some-ip:443;
}

server {
    listen 80;


    location / {
        proxy_ssl_certificate        certs/client.crt;
        proxy_ssl_certificate_key    certs/client.key;


        proxy_pass https://backend;
    }
}

1.8.0 无法开箱即用。它可能仅用作提示,不能用作配置文件,或者依赖于其他版本。

我正在使用基于 apache2 的后端服务器 A 进行测试,该服务器启用了 SSL 和自签名客户端证书。Apache 配置 SSLOptions 设置为:

SSLOptions +ExportCertData +FakeBasicAuth + StdEnvVars

这使得调试情况变得更容易,因为后端的 phpinfo() 脚本将显示服务器和客户端信息。

为了验证这一点我使用了:

https://backend/test/phpinfo

在浏览器中安装 SSL 证书后,我获得如下部分:服务器证书的 SSL_SERVER_S_DN_CN 和客户端证书的 SSL_CLIENT_S_DN_CN。

第一次启动我使用(填写括号中的部分)在前端服务器 B 上配置 nginx:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    #proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    #proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

取消注释 SSL 客户端证书特定部分只是为了检查反向代理本身是否有效。

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

现在http://前端:8080/test/phpinfo.php作品

显示服务器证书的 SSL_SERVER_S_DN_CN 和客户端证书的 SSL_CLIENT_S_DN_CN尚未显示

现在取消注释后:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

并检查/重启

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

http://前端:8080/test/phpinfo.php作品和

显示服务器证书的 SSL_SERVER_S_DN_CN 和客户端证书的 SSL_CLIENT_S_DN_CN被展示

所以现在我们已按要求开展工作。

请注意错误https://trac.nginx.org/nginx/ticket/872#ticket

答案3

显然,这就是您正在寻找的: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate 自 1.7.8 版起可用。

location / {
    ...
    proxy_pass     the_other_nginx;
    proxy_ssl_certificate  the_certificate.pem;
    ...
}

答案4

有一篇关于 nginx 和 SSL 客户端证书的相当不错的文章;它使用带有 FastCGI 的 PHP 作为示例,但我认为您可以将其适应反向代理设置:

server {
    listen        443;
    ssl on;
    server_name example.com;

    ssl_certificate      /etc/nginx/certs/server.crt;
    ssl_certificate_key  /etc/nginx/certs/server.key;
    ssl_client_certificate /etc/nginx/certs/ca.crt;
    ssl_verify_client optional;

    location / {
        root           /var/www/example.com/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME /var/www/example.com/lib/Request.class.php;
        fastcgi_param  VERIFIED $ssl_client_verify;
        fastcgi_param  DN $ssl_client_s_dn;
        include        fastcgi_params;
    }
}

来源http://nategood.com/客户端-side-certificate-authentication-in-ngi

相关内容