2012-08-07 111 views
5

我想通過nginx代理請求頭'HTTP_X_SSL_CLIENT_S_DN'。如何代理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 proxy],標頭'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; 
} 

任何幫助適用。

回答

2

我有與nginx相同的問題作爲代理從請求中刪除X_REQUESTED_WITH字段。默認情況下,nginx將下劃線標題標記爲無效,並忽略無效標題。

您可以使用nginx指令來允許使用underscores_in_headers on;的標頭中的下劃線,或者不要忽略與ignore_invalid_headers off;無效的標頭。

在我的具體情況中,我使用python請求作爲客戶端,將django作爲服務器,將nginx作爲代理,並解決了我將X_REQUESTED_WITH重命名爲X-REQUESTED-WITH的問題。 (Django的自動添加'HTTP_'爲x-頭名的開始使得可用的頭在request.META.之前)

import requests 
headers = {'X-REQUESTED-WITH':'XMLHttpRequest'} 
r = requests.post(url, data=payload, headers=headers) 
+0

謝謝eli_mach。您的建議有嘗試的價值。我會嘗試你的建議,但我已經失去了我的測試環境。 – superdaigo 2012-10-19 14:30:07

+0

我也使用django。 – superdaigo 2012-10-19 14:35:43

5

首先,確保你已經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 
    

我有一個簡單屈web應用程序的轉儲的HTTP環境和我看到以下內容:

「HTTP_X_SSL_CLIENT_SERIAL」=> 「01」, 「HTTP_X_SSL_CLIENT_VERIFY」=> 「SUCCESS」, 「HTTP_X_SSL_CLIENT_S_DN」=>「/ C =美國/ ST =馬里蘭州/ L =安納波利斯/ O = Fort Kickass/CN =喬納森莫頓/[email protected]