ひとつの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を使って自前で作りました。
秘密鍵ファイル作成
openssl genrsa 2048 > selfcert.key
CSRファイル作成
openssl req -new -key selfcert.key > selfcert.csr
証明書ファイル作成
openssl x509 -days 3650 -req -signkey selfcert.key < selfcert.csr > selfcert.crt
これをnginx.confに指定した所定の場所に保存すればOKです。