Nginx代理到具有SSL客户端证书身份验证的后端


14

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

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

我想在服务器B上配置Nginx,该服务器将侦听8080(不加密,因为它全部是本地通信),并将proxy_pass传递到ServerA:443。

问题是如何注入客户证书?我没有找到可以做到这一点的proxy_xxxx函数。

我确实知道如何使socat与之等效,但是我的要求是使用nginx。


2
查看nginx代理模块中的指令,似乎无法使nginx服务器使用证书进行身份验证:nginx.org/en/docs/http/ngx_http_proxy_module.html Apache确实支持该功能。
NuTTyX

那就是我所担心的...是否有一个自定义模块或可以使之工作的东西?这种功能必须存在!
Bastien974

我找到了一个实用程序,可将配置文件从apache迁移到nginx(github.com/nhnc-nginx/apache2nginx),所以我下载了它,创建了一个虚拟的apache.conf并将其通过该工具,但是得到了这个结果:### Section 2: Unconverted directives ### # Flag Description # [S] Unsupported directives. # In conf file: dummy.conf # Line 32: SSLProxyMachineCertificateFile /path/to/cert (mod_ssl.c) # [S] SSLProxyMachineCertificateFile: No relevant directive in Nginx.
NuTTyX 2014年

Answers:


21

通过客户证书详细信息是否足够?

你可以加

proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

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


1
如此处所述,请注意,一旦读取后,您的后端是否可以从此标头替换\t\n
lucasvc

3
根据nginx的文档$ssl_client_cert不推荐使用该变量;该$ssl_client_escaped_cert变量应该被替代使用。
dubek '18

1
@dubek很好,在这种情况下,我将直接更新答案。
克里斯·斯特里钦斯基

我一直在尝试此解决方案,但是如果将证书验证设置为“开”,它似乎只能通过证书。我不想打开它,有没有办法在不设置验证的情况下使它工作?
juhako

5

显然,这是您要查找的内容: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;
    ...
}

1
错了 这会将客户端证书分配给要用于后端请求的代理。但询问者说,此通信仅在本地未加密,因此不进行客户端证书检查。jwilkins的答案很好。
Kenyakorn Ketsombut

@KenyakornKetsom但是我相信你误解了这个问题。服务器B没有加密(在8080上侦听),但必须与服务器A通信(在443上侦听,具有加密)。因此,B需要将客户端证书发送给A进行身份验证。您可以使用proxy_ssl_certificate完成此操作。jwilkins的答案将把提供给B的证书转发给A。两者都可以根据您的需要工作。
Nicolas Malbran 2015年

嗨,尼古拉斯。我试图说:如果服务器B未使用加密(在端口8080上),则它不会使用HTTPS / SSL之类的东西,或者您将其称为。客户端证书是SSL的一部分,因此服务器B无法完成此部分。B无法发送或接收任何客户端证书。
Kenyakorn Ketsombut 2015年

1
我得到nginx:[emerg]没有为证书“ certs / Roro_Client.pem”定义“ proxy_ssl_certificate_key” nginx:当我在1.8.0上尝试使用此配置文件时,/etc/nginx/nginx.conf测试失败
Wolfgang Fahl

4

这个问题似乎很大程度上取决于版本。在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不能立即使用。它可能仅是一个提示,而不能用作配置文件或依赖于另一个版本。

我正在使用启用了SSL和自签名客户端证书的基于apache2的后端服务器A进行测试。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:// frontend: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:// frontend:8080 / test / phpinfo.php可以正常工作

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

所以现在我们可以按要求进行工作了。

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


您可能需要注意有关ruby-forum.com/topic/6875137的重新谈判问题,该问题可能会破坏演出
Wolfgang Fahl,

1

关于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/client-side-certificate-authentication-in-ngi


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.