• 作成:
  • 更新:

自宅のルータが存在しないサイトにアクセスした時に証明書エラーを出すのを直す

自宅のネットワークでドメイン切れのwebサイトにアクセスすると証明書の警告が表示されます

以下のように存在しないwebサイトにアクセスすると, httpsにリダイレクトするように促されます.

% curl -I 'example.invalid'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.2
Date: Wed, 04 Jul 2018 05:05:44 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://example.invalid/
Expires: Fri, 03 Aug 2018 05:05:44 GMT
Cache-Control: max-age=2592000
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Cache-Control: no-cache

するとその先443のデフォルトサーバであるncaq.netの証明書を参照して, 「このサイト用の証明書ではない」という証明書の警告が出ます.

これはそこそこ面倒で, アクセスしたサイトのドメインが切れているのか, それとも本当に証明書のエラーが問題なのか, ひと目で把握できません.

ブラウザの警告でも一回クリックしないと証明書のエラー原因は出ないので尚更です.

何故こんなネットワークになっているのか

自宅のサーバがルータ兼ここのwebサーバになっているためです. 自宅サーバではルーティングをすると同時にnginxが動いており80と443の待受もしてます.

デフォルトサーバが暗黙的に設定されているため, 不明なアクセス→nginxのデフォルトサーバが待受→httpsにリダイレクト→証明書エラーとなります.

「いやルータとwebサーバは分けろよ」というのはその通りなのですが, 電気代やサーバ代の問題があります. うちのサーバは高校3年当時2万円ほどで組んで, バズった時のトラフィックもきちんと捌いていました.

設定の修正

これまで設定を雑に以下のようにしてきました.

    server {
        listen 80;
        location / {
            rewrite ^ https://$host$request_uri permanent;
        }
    }

これはホスト名を指定しなくても自動でhttpsに振り分けてくれるので便利なのですが, 今回のような問題が起きてしまいます.

自分のホストはちゃんと設定して, デフォルトサーバは何もしないようにしましょう.

    server {
    }
    server {
        server_name .ncaq.net;
        listen 80;
        location / {
            rewrite ^ https://$host$request_uri permanent;
        }
    }

nginx 1.12ではlisten default_serverとデフォルトサーバに書くことが出来ましたが, nginx 1.14ではこの文法は通りません. 空行にしましょう.

これで存在しないサイトにアクセスした時証明書エラーではなく404を表示してくれます.

いや, 本当は404を出すのもおかしくてサイトへ辿り着けないことを表示するべきなのですが, そろそろ昼休み終わってしまうのでそういう設定は無しです.

Is It Down Right Now? Website Down or Not? などのリンクを埋め込むと利便性高そうですね.

昔はこういう時自動でGoogle検索でホストを検索するように飛ばしていたのですが, 何らかの理由でやめてしまいました.