stardust.box は、これまで GitHub Pages で出していました。今回、自分で借りた VPS に引っ越して、このブログ(blog.stardust.box)もそこから配るようにしました。Hello World に書いた「借り物の場所ではなく、自分のサーバーに」の中身です。
作業そのものは 1 日で終わりましたが、DNS の古い値に 2 回つまずきました。(;´Д`)
やったこと
ブラウザ ──(DNS)──> my.box で管理している stardust.box │ └──(HTTPS)──> VPS(Debian・nginx・Let's Encrypt) ├─ blog.stardust.box … このブログ(Astro でビルドしたもの) └─ stardust.box・www … いまはブログへ一時的に移す(302)- VPS に nginx を入れ、サイトごとに設定のファイルを 1 つずつ置いた
- 手元でブログをビルドし、
rsyncで VPS に送った - DNS(
.boxドメインの管理画面)に、blogの A・AAAA レコードを足した certbotで Let’s Encrypt の証明書を取った(http://からhttps://への移動も certbot が入れてくれる)- GitHub Pages を指していたレコードを消し、
stardust.boxとwwwを VPS に向けた - GitHub のリポジトリを消した(中身は手元の Git サーバーに控えがある)
つまずき 1: 証明書が取れない
stardust.box の DNS を VPS に向けた直後に certbot を実行したら、失敗しました。
Domain: stardust.boxType: unauthorizedDetail: 185.199.111.153: Invalid response from http://stardust.box/.well-known/acme-challenge/...: 404185.199.x.x は GitHub Pages の IP です。Let’s Encrypt が確かめに行った先が、まだ古いほう(GitHub)だったわけです。DNS の答えは、TTL(覚えておく時間。今回は 3600 秒)のあいだ、あちこちに残ります。
ここで何度もやり直すのは危ないです。Let’s Encrypt には、確かめの失敗は 1 時間に 5 回までという制限があります。なので、公開の DNS(Cloudflare と Google)が新しい値を返すまで、1 分ごとに確かめる小さなスクリプトを回して待ちました。
# Cloudflare と Google の DNS が、どちらも VPS の IP を返すまで待つ(考え方だけ)while not all(answer(server, name) == {VPS_IP} for server in SERVERS for name in NAMES): time.sleep(60)今回は 2 分ほどで変わり、2 回目で取れました。証明書は、DNS が変わったのを確かめてから取る。
つまずき 2: ブラウザだけ昔のページが出る
コマンド(curl)で確かめると、ちゃんと新しいサーバーにつながります。なのに、ブラウザで stardust.box を開くと昔のページが出る。( ゚д゚)
ブラウザの開発者ツールで、ページがどう届いたかを見ると、手がかりがありました。
performance.getEntriesByType('navigation')[0].nextHopProtocol // => "h2"キャッシュ(手元の控え)ではなく、ネットワークから HTTP/2 で届いていました。私の nginx はまだ HTTP/2 を有効にしていないので、相手は GitHub のサーバーです。
ブラウザは、速くするために、一度つないだサーバーとの通信をしばらく使い回します。DNS の答えも、ブラウザの中に少し覚えています。DNS を変えても、その古い通信が生きているあいだは、昔のサーバーにつながり続けるわけです。
Chromium 系のブラウザ(Brave など)なら、次の 2 つで消せます。
brave://net-internals/#dnsで「Clear host cache」brave://net-internals/#socketsで「Flush socket pools」
GitHub のリポジトリを消したあとにもう一度起きたときは、GitHub の「Site not found」の 404 が出ました。同じやり方で直りました。
気をつけたこと
- 302 にした:
stardust.boxは、いずれ自己紹介のサイトにする予定です。なので、ブログへの移動は 301(ずっと移動)ではなく 302(一時的な移動)にしました。301 はブラウザや検索エンジンが長く覚えてしまうので、あとで差し替えにくくなります - 知らない名前の来訪は断る: IP アドレスで直接来たり、知らない名前で来たりした人には、何も返さずに接続を閉じるようにしました。これをしないと、設定のファイル名の順で最初のサイトが出てしまいます
server { listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; ssl_reject_handshake on; # 証明書も出さずに TLS を断る(nginx 1.19.4 から) return 444; # nginx 独自の「何も返さずに閉じる」}- 送る前に検査する: ブログを送るスクリプト(Python)は、ビルドしたものに、サーバーの IP や手元のパスなどの内部の情報が入っていないかを調べてから送ります。公開のサイトなので、うっかりを機械で止めます
まとめ
- DNS を変えたら、答えが変わったのを確かめてから次へ進む(証明書は特に。失敗には回数の制限がある)
- 「コマンドでは直っているのにブラウザだけ古い」ときは、ブラウザの中の DNS の控えと、つながったままの通信を疑う
- 一時的な移動は 302
自分のサーバーにすると、こういうところまで全部自分で見ることになります。でも、そのぶん中で何が起きているかが分かって楽しい。インターネットの片隅から、少しずつ取り戻していきます。((*´∀`))