Nginxリバースプロキシを複数のドメインでセットアップし、それぞれに異なるSSL証明書を使用するためのIPを設定したいと思います。私はKVM/Qemu VMにインストールされているOSとしてUbuntuを実行しています。
私はnginxを理解しているので、1つのIPを介して1つのドメイン(およびそれに属するサブドメイン)を提供できるはずです。しかし、実行できません...
それは私の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にリダイレクトされます。2番目のドメインの構成は非常に似ています。
/ etc/nginx/sites-enabled/anotherdomain
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を使用してWebサイトを取得しようとしました。このリクエスト:
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/
うーん、それで結構です...しかし、このリクエスト[同じドメイン(「Host:」ヘッダーを参照)ですが、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
...私が求めているウェブサイトが配信されます。そのため、SSLなしで間違ったIPにリクエストを送信しましたが、プロキシ経由でWebサイトを取得しました。それがまさに私が避けたかったことです!
あなたのアイデアをありがとう!
最初の構成は次のようになります。
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;
}
}
2番目の構成は次のようになります。
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;
}
}
これで問題が解決する場合は、構成を再定義できるようにお知らせください。