7

我想通过 nginx 代理请求标头“HTTP_X_SSL_CLIENT_S_DN”。

这是我们的服务器网络结构。

[front server:443] <---> [nginx proxy:8004] <---> [application server:8008]
(client cert auth)

当我尝试了两台服务器([前端服务器]和[应用程序服务器])时,它工作正常。标头“HTTP_X_SSL_CLIENT_S_DN”已传递给应用程序服务器。

然后添加服务器 [nginx 代理],标头“HTTP_X_SSL_CLIENT_S_DN”没有传递给应用程序服务器。

我的 nginx 配置如下。

server {
    listen   8004;
    index index.html;

    location / {
        proxy_pass_header Server;
        proxy_pass_header X-Scheme;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://app-server/;

# TODO: to proxy 'HTTP_X_SSL_CLIENT_S_DN'
# failed settings
#        proxy_pass_request_headers on; # not worked (default: on)
#        proxy_pass_header X-SSL-Client-S-DN; # none
#        proxy_pass_header X_SSL_CLIENT_S_DN; # none
#        proxy_pass_header HTTP_X_SSL_CLIENT_S_DN; # none
#        proxy_pass_header HTTP-X-SSL-CLIENT-S-DN; # none
#        proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn; # none
#        proxy_set_header X_SSL_Client_S_DN $x_ssl_client_s_dn; # none
#        proxy_set_header X-SSL-Client-S-DN $http_ssl_client_s_dn; # none
#        proxy_set_header X-SSL-Client-S-DN $http_x_ssl_client_s_dn; # none
    }
}

upstream app-server {
    server 127.0.0.1:8008;
}

应用任何帮助。

4

2 回答 2

7

首先,确保您已配置 nginx.conf 以验证客户端证书!我遇到了与您描述的完全相同的问题。

server {
  # ...
  ssl_client_certificate /srv/ssl/self.crt;
  ssl_verify_depth     1;
  ssl_verify_client    on;
  # ...
  location @app { # I'm using nginx+unicorn, don't blindly copy this!  :)
    # ...
    proxy_set_header X-SSL-Client-Serial $ssl_client_serial;
    proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
    proxy_set_header X-SSL-Client-S-DN   $ssl_client_s_dn;
    # ...
}

要对此进行测试,您将需要一个单独的客户端密钥和一个已使用根授权证书签名的证书。在以下命令中,客户端凭据以“me”开头,而我的根权限凭据以“self”开头。

  1. 为客户端生成私钥。

    openssl genrsa -out me.key 1024
    
  2. 请求自我 CA 签名。

    openssl req -new -key me.key -out me.csr
    
  3. 使用自 CA 对请求进行签名以创建证书。

    openssl x509 -req -days 365 -in me.csr -CA self.crt -CAkey self.key -set_serial 01 -out me.crt
    
  4. 试试你的新密钥。

    curl -v -s -k --key me.key --cert me.crt https://fort-awesome-o
    
  5. 额外积分:生成可以导入浏览器的证书。

    openssl pkcs12 -export -in me.crt -inkey me.key -certfile self.crt -out me.p12
    

我有一个转储 HTTP 环境的简单 Sinatra Web 应用程序,我看到以下内容:

"HTTP_X_SSL_CLIENT_SERIAL"=>"01", "HTTP_X_SSL_CLIENT_VERIFY"=>"SUCCESS", "HTTP_X_SSL_CLIENT_S_DN"=>"/C=US/ST=马里兰/L=安纳波利斯/O=基卡斯堡/CN=乔纳森·莫顿/emailAddress=jon @jonmorton.com"

于 2013-03-06T23:41:58.357 回答
2

我对 nginx 有同样的问题,因为代理X_REQUESTED_WITH从请求中删除了该字段。默认情况下,nginx 将带有下划线的标头标记为无效并忽略无效标头。

您可以使用 nginx 指令来允许标头中使用下划线underscores_in_headers on;或不忽略带有ignore_invalid_headers off;.

在我的具体案例中,我使用 python 请求作为客户端,django 作为服务器,nginx 作为代理,并解决了我重命名X_REQUESTED_WITHX-REQUESTED-WITH. (Django'HTTP_'在使标头可用之前自动添加到 x-header 名称的开头request.META.

import requests
headers = {'X-REQUESTED-WITH':'XMLHttpRequest'}
r = requests.post(url, data=payload, headers=headers)
于 2012-10-19T13:42:27.997 回答