HTTP升級到Nginx中的TLS我一直在研究如何將HTTP連接升級到TLS,並實現跨端代理的端到端隧道。我希望在這個隧道中使用客戶端證書,在幾跳之後在接收端進行處理。 我讀RFC 2817(HTTP升級到TLS),似乎這是可能的。我只是不知道如何使用Nginx作爲Nginx新手。根據RFC 2817
我想知道我是否在做一個完整的noob錯誤,或者如果這在Nginx中是完全可能的。
我Nginx的實例1以下配置的HTTP模塊:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location/{
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass https://10.0.3.4/;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
第二Nginx的實例具有以下配置具有相當多,除了一個區別proxy_pass https://10.0.3.5/index.html
最後一個相同的配置Nginx實例具有以下配置:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher '
'$ssl_client_cert '
'$ssl_client_raw_cert '
'HTTP UPGRADE: $http_upgrade '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log logs/access.log;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
access_log logs/access-ssl.log main;
ssl_certificate /root/certs/server.crt;
ssl_certificate_key /root/certs/server.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /root/certs/dhparams.pem;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
location/{
root html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
當我使用HTTPS訪問URL時,確實得到響應但沒有任何回合客戶證書打印在日誌中。當我只使用HTTP時,我得到了301響應。這是兩個電話我提出: $ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" https://10.0.3.3/
和
$ curl -k -i --cert /root/certs/client-cert.pem --key /root/certs/client-key.pem --header "Upgrade: TLS/1.2" --header "Connection: Upgrade" http://10.0.3.3/
非常感謝你的澄清。我打算使用在應用程序級別實現的此功能,並且我不打算將它用於瀏覽器。這個想法是讓一個應用程序進行調用,呈現自己的證書,並用請求的資源一直代理到一個服務。到達最終服務的跳數有多個,並且最終服務將根據原始發件人的證書對請求進行身份驗證和授權。 – Tempo
@Tempo:由於TLS是端到端加密,因此只有端點可以請求並驗證客戶端證書。這意味着無法通過客戶端證書或中間的某些軟件(nginx或其他)中的請求資源來選擇端點,並且仍然能夠將客戶端證書無損轉發到端點。 –
非常感謝您的評論,非常感謝。如果在這種情況下TLS(和HTTPS隧道/升級)不是一個選項,是否有任何其他經過驗證的解決方案可以用來實現所需的結果?除了從零開始實施自定義協議?即使對於專有協議,我甚至不知道如何開始實施它。作爲一個Nginx模塊呢? – Tempo