[要注意] nginx バーチャルホストで複数ポートかつSSL有効化したら平文通信できなくなった話

家のサーバーのnginxの設定をしていたら完全にドジってはまったのでそのメモ。
自分のサーバー環境は諸事情でリバースプロキシ経由でウェブサーバー本体に接続する構成に変更中でして、Nginxをリバースプロキシとして設定していました。
構成は以下の通り。

自分のサイトは、もともとそれぞれサブドメインを割り当てたバーチャルホストが複数稼働している環境だったため、nginx側もバーチャルホストに対応すべく下のような設定にしていました。

#省略...
server {
server_name .example.com;
listen 80;
listen 443 ssl;
ssl on;
ssl_certificate /ssl/to/path/example.com/fullchain.pem;
ssl_certificate_key /ssl/to/path/example.com/privkey.pem;
client_max_body_size 1g;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # クライアントの IP アドレス
proxy_set_header X-Forwarded-Host $host; # オリジナルのホスト名。クライアントが Host リクエストヘッダで渡す。
proxy_set_header X-Forwarded-Server $host; # プロキシサーバのホスト名
proxy_set_header X-Real-IP $remote_addr;
location / {
proxy_pass https://xxx.xxx.xxx.xxx;
}
}
server {
server_name .a.example.com;
listen 80;
listen 443 ssl;
ssl on;
ssl_certificate /ssl/to/path/a.example.com/fullchain.pem;
ssl_certificate_key /ssl/to/path/a.example.com/privkey.pem;
client_max_body_size 1g;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # クライアントの IP アドレス
proxy_set_header X-Forwarded-Host $host; # オリジナルのホスト名。クライアントが Host リクエストヘッダで渡す。
proxy_set_header X-Forwarded-Server $host; # プロキシサーバのホスト名
proxy_set_header X-Real-IP $remote_addr;
location / {
proxy_pass https://xxx.xxx.xxx.xxx;
}
}
#省略...

すると

BadRequestのエラーが。
いろいろ試してもエラーが解消されず頭を抱えていたのですが、調べていたら以下のサイトを発見。

nginx連載6回目: nginxの設定、その4 – TLS/SSLの設定 – インフラエンジニア way
https://heartbeats.jp/hbblog/2012/06/nginx06.html

>sslディレクティブをonに設定すると、SSLが有効になります。ただし、listenディレクティブでsslパラメータを指定したときには不要です。

>ssl on;

>listenディレクティブにsslパラメータを付けると、そのポートでSSLを有効にして待ち受けるようになります。そのポートに関して後述するsslディレクティブをonにしたのと同じ動作になるため、sslディレクティブの記述は不要になります。

>listen 443 ssl;

あっ、なるほど…!
ssl on;
の記述をしてしまうと
server{}
内で定義されている全ポートにsslが有効になるので、80番ポートでアクセスしてもssl通信と解釈されてしまい、エラーが出ていたようです。
443ポートだけsslにしたい場合は

listen 443 ssl;

とだけ指定しておけば443ポートだけsslを有効にできるようです。

てっきり
“ssl on;”
を入れないとsslが有効にならないものと勘違いしていました(苦笑

さっきの設定を修正すると以下のようになりました。

#省略...
server {
server_name .example.com;
listen 80;
listen 443 ssl; #これは残しておく
#ssl on; コメントアウト
ssl_certificate /ssl/to/path/example.com/fullchain.pem;
ssl_certificate_key /ssl/to/path/example.com/privkey.pem;
client_max_body_size 1g;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # クライアントの IP アドレス
proxy_set_header X-Forwarded-Host $host; # オリジナルのホスト名。クライアントが Host リクエストヘッダで渡す。
proxy_set_header X-Forwarded-Server $host; # プロキシサーバのホスト名
proxy_set_header X-Real-IP $remote_addr;
location / {
proxy_pass https://xxx.xxx.xxx.xxx;
}
}
server {
server_name .a.example.com;
listen 80;
listen 443 ssl; #これは残しておく
#ssl on; #コメントアウト
ssl_certificate /ssl/to/path/a.example.com/fullchain.pem;
ssl_certificate_key /ssl/to/path/a.example.com/privkey.pem;
client_max_body_size 1g;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # クライアントの IP アドレス
proxy_set_header X-Forwarded-Host $host; # オリジナルのホスト名。クライアントが Host リクエストヘッダで渡す。
proxy_set_header X-Forwarded-Server $host; # プロキシサーバのホスト名
proxy_set_header X-Real-IP $remote_addr;
location / {
proxy_pass https://xxx.xxx.xxx.xxx;
}
}
#省略...

これでnginxを再起動したところ、無事80番ポートの平文通信と443ポートのSSL通信両方ともできるようになりました。

分かってしまえばなんともくだらない間違いですが、大分焦りました。

もっと勉強せねば…


この記事は、以前筆者が書いた記事を一部変更したものです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG