Nginxで443ポートにデフォルトサーバーを指定する

ひとつのVPSに複数のドメインを設定してマルチサイトで運用する。よくある話だと思います。ウチもそう。

で、80ポートなり443ポートなりにやってきたアクセスの要求ドメイン名に従って、それぞれのサイトに振り分けます。

デフォルトサーバーの指定

この時、想定外のドメイン名でアクセスしてきたらどうなるか?あるいはIPアドレス直打ちでやってきたらどうなるか?nginx.confには振り分け先が書いていないので、とりあえず先頭に指定してあるserverブロックに振り分けちゃうというのがnginxのデフォルト動作です。

なので場合によっては最初に指定したドメインへのアクセスのうち、何パーセントかは本来のアクセスじゃないっていうね。

そこで指定ドメイン以外のアクセスを全てエラー処理してしまう設定がこちら。

# default server setting
##########################################
server {
   listen       80  default_server;
   listen       443 ssl default_server;
   server_name  _;
   ssl_certificate         /usr/local/etc/ssl/selfcert.crt;
   ssl_certificate_key     /usr/local/etc/ssl/selfcert.key;
   return 444;
}

serverブロック内でlistenしているポート番号の後ろにdefault_serverを付けると、未知のドメインにやってきたアクセスを全てそのserverブロックで処理します。なおserverブロックには必ずserver_nameを指定しなくてはならないので、_を指定しておきます。(ここに実在のドメインを指定しても構わないけど)

そうしてここで受けたアクセスに対してエラーコードを返す処理return 444などを入れておくと、本来望まないアクセスを全てエラーで弾くことができるというわけ。

443ポートは証明書が必要

ここでずっと悩んでいたのがこれ。しばらく解が見つからなくて、80ポートへの不要なアクセスは適切に弾くことができていたけれど、443ポートへのものは弾けずに受け付けてた。

443ポートはhttpsを受け付けるようにしているので、ssl_certificateとssl_certificate_keyの設定がないとエラーになってしまって、本来受け付けるべき仮想ドメインのserverブロックも全滅してしまいます。

自己署名証明書を作る

このとき、証明書自体は自己署名証明書でもいいかなということで、opensslを使って自前で作りました。

  1. 秘密鍵ファイル作成
    openssl genrsa 2048 > selfcert.key
    
  2. CSRファイル作成
    openssl req -new -key selfcert.key > selfcert.csr
    
  3. 証明書ファイル作成
    openssl x509 -days 3650 -req -signkey selfcert.key < selfcert.csr > selfcert.crt
    

これをnginx.confに指定した所定の場所に保存すればOKです。