我想設定具有多個網域和每個 IP 的 nginx 反向代理,以使用不同的 SSL 憑證。我運行 Ubuntu 作為安裝在 KVM/Qemu 虛擬機器上的作業系統。
據我了解 nginx,它應該能夠透過一個 IP 為一個網域(以及屬於它的子網域)提供服務。但我無法讓它運行...
這是我的 nginx 設定:
/etc/nginx/sites-enabled/my_first_domain
server {
listen x.x.x.84:80; # this is a public ip
server_name firstdomain.com;
access_log /var/log/nginx/access.log proxy; # I made my own logformat
error_log /var/log/nginx/error.log;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
location / {
rewrite ^/(.*) https://firstdomain/$1; # redirect to https
}
}
server {
listen x.x.x.84:443 ssl; # this is a public ip
server_name firstdomain.com;
ssl_certificate /etc/nginx/ssl/combined.firstdomain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.firstdomain.com.key;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://x.x.x.85; # this is a public ip, too
proxy_redirect off;
}
}
我認為這個配置非常簡單。在連接埠 80 上的每個請求都應重定向到連接埠 443。
/etc/nginx/sites-enabled/另一個域
server {
listen x.x.x.87:80; # this is a public ip
server_name anotherdomain.org;
access_log /var/log/nginx/access.log proxy; # I made my own logformat
error_log /var/log/nginx/error.log;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
location / {
rewrite ^/(.*) https://anotherdomain.org/$1; # redirect to https
}
}
server {
listen x.x.x.87:443 ssl; # this is a public ip
server_name anotherdomain.org;
ssl_certificate /etc/nginx/ssl/combined.anotherdomain.org.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.anotherdomain.org.key;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://x.x.x.89; # this is a public ip, too
proxy_redirect off;
}
}
我的 netstat -tulpen 片段:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
...
tcp 0 0 x.x.x.84:80 0.0.0.0:* LISTEN 0 8724 1187/nginx
tcp 0 0 x.x.x.87:80 0.0.0.0:* LISTEN 0 8723 1187/nginx
tcp 0 0 x.x.x.84:443 0.0.0.0:* LISTEN 0 8726 1187/nginx
tcp 0 0 x.x.x.87:443 0.0.0.0:* LISTEN 0 8725 1187/nginx
...
實際上,我認為這應該足以在同一台伺服器上使用 SSL 託管多個網域。但 nginx 為每個請求提供相同的憑證。結果是 SSL 錯誤。
還有另一個意想不到的行為。在調試時,我嘗試使用 telnet 作為客戶端來獲取網站。這個請求:
user@host:~$ telnet x.x.x.84 80
Trying x.x.x.84...
Connected to x.x.x.84.
Escape character is '^]'.
GET / HTTP/1.1
Host: firstdomain.com
屬於這個回覆:
HTTP/1.1 302 Moved Temporarily
...
Location: https://firstdomain.com/
嗯,沒關係...但是這個請求[相同的域(請參閱“主機:”-標頭),但 IP 現在不是]:
user@host:~$ telnet x.x.x.87 80
Trying x.x.x.87...
Connected to x.x.x.87.
Escape character is '^]'.
GET / HTTP/1.1
Host: firstdomain.com
....導致交付我所要求的網站。因此,儘管我將請求發送到了錯誤的 IP 並且沒有使用 SSL,但我還是透過代理商取得了該網站。這正是我想要阻止的!
謝謝你的想法!
答案1
您的第一個配置應該如下所示。
server {
listen x.x.x.84:80;
server_name firstdomain.com;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
return https://$server_name$request_uri;
}
server {
listen x.x.x.84:443 ssl;
server_name firstdomain.com;
root ????;
ssl_certificate /etc/nginx/ssl/combined.firstdomain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.firstdomain.com.key;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
location / {
# Do not proxy everything to the backend, deliver static files
# right away!
try_files $uri @proxy;
}
location @proxy {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
# The backend MUST be SSL enabled as well!
proxy_pass https://x.x.x.85;
}
}
您的第二個配置應該如下所示。
server {
listen x.x.x.87:80;
server_name anotherdomain.org;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
return https://$server_name$request_uri;
}
server {
listen x.x.x.87:443 ssl;
server_name anotherdomain.org;
root ????;
ssl_certificate /etc/nginx/ssl/combined.anotherdomain.org.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.anotherdomain.org.key;
access_log /var/log/nginx/access.log proxy;
error_log /var/log/nginx/error.log;
location / {
# Do not proxy everything to the backend, deliver static files
# right away!
try_files $uri @proxy;
}
location @proxy {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Host $host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
# The backend MUST be SSL enabled as well!
proxy_pass https://x.x.x.85;
}
}
請告訴我這是否有幫助,以便我們可以進一步重新定義配置。