あるデバッグの記録 — connection refused
はじめに
数か月前あたりから、僕の Google Chrome で原因不明の connection refused が頻繁に発生するようになった。特定のウェブページが開かないことがあるのに、他の端末から開くと正常に表示される。変だなとは思いつつも、サーバー側の設定の問題かもしれないし、そこまで大きな困り事でもなかったので、そのまま使い続けていた。
カスタムドメインの設定
その後、ついでに .dev ドメインを購入したときに、奇妙なことが起きた。CNAME を設定し、SSL が有効になったことも確認したのに、Chrome でいくらリロードしても CONNECTION_REFUSED が表示され続ける。一般的にこの問題にはいくつか原因が考えられる。1つはサーバー側でポートが開いていないこと、もう1つはファイアウォールの設定だ。この2つの設定を確認してみたが、どちらも問題なかった。念のため、dig xxx.dev +nostats +nocomments +nocmd を使って CNAME が正しく設定されているか確認してみたが、完全に問題なしだった。
次に SSL の問題を疑い、SSL checker を使って SSL が正しく設定されているかチェックした。こちらも正常だった。
まあ、設定が反映されるまで少し時間がかかるのかもしれないと思い、10分ほど待ってからもう一度試したが、やはりダメだった。Chrome には相変わらず真っ白な CONENCTION_REFUSED が表示される。そこでスマホからアクセスしてみると、正常にページが開けた。
この時点で、パソコン内の何らかの設定に問題があるのではないかと疑い始め、関連する設定を調べ始めた。まずは curl blog.kalan.dev を試してみた。するとエラーが出た:
curl: (7) Failed to connect to blog.kalan.dev port 80: Connection refused
うーん、Chrome の結果と curl の結果が同じなので、PC 自体の設定に問題があるという確信がさらに強まった。次に何が起きているのかを調べるため、wget を使ってみた。
wget https://blog.kalan.dev
--2019-03-18 23:11:46-- https://blog.kalan.dev/
正在查找主機 blog.kalan.dev (blog.kalan.dev)... 127.0.0.1, 0.0.0.1
正在連接 blog.kalan.dev (blog.kalan.dev)|127.0.0.1|:443... 失敗: Connection refused。
正在連接 blog.kalan.dev (blog.kalan.dev)|0.0.0.1|:443... 失敗: No route to host。
ちょっと待ってくれ、ホストの検索で 127.0.0.1 が返ってきた?ということは、僕はこのドメインを hosts に追加したのだろうか?記憶にはまったくなかったが、一縷の望みを抱いて /etc/hosts と /private/etc/hosts の2つのファイルを確認してみた。
結果は変わらず、ローカルの hosts にはドメインを設定していなかった。しかし、少なくとも原因の方向性は見えてきた。何らかの設定によって blog.kalan.dev が 127.0.0.1 に向いてしまっているのだ。ここに至っても、原因として何が考えられるのか全く見当がつかなかった。だが、あれこれ手当たり次第に試しているうちに奇妙なことに気づいた。あらゆる xxx.dev で同じ現象が起きているのに、他のドメインではそんな問題が起きていないのだ。
そのとき、ふとあることを思い出した。およそ4年前、僕が Ruby on Rails を学ぶために powder をダウンロードしたことだ。簡単に言うと、ウェブサイトにアクセスした際、自動的にサーバーを立ち上げてくれるツールで、これがめちゃくちゃ便利だった。だから当時喜んでインストールしたのだった。
しかし、公式ドキュメントをよく見てみると、セクション3.1にこう書かれていた:
The
POW_DOMAINSenvironment variable specifies a comma-separated list of top-level domains for which Pow will serve DNS queries and HTTP requests. The default value for this list are the twotest,devdomains, meaning Pow will configure your system to resolve*.testand*.devto 127.0.0.1 and serve apps in~/.powunder the.testand.devdomains.
ああああ、お前の仕業だったのか!IP を乗っ取られていたのだ。127.0.0.1 を向いていて、PC 自体で 443 ポートを開いていないため、CONNECTION_REFUSED が発生していたわけだ。これまで開けなかったウェブページたちも、もしかしたら .dev ドメインだったのかもしれない。
いくつかメモとして残しておこう:
CONNECTION_REFUSEDが発生したときは、直接wgetを使ってホストの接続先が正しいか確認する- または
curl --ipv4 -v “your.site.com”でホストへの接続を確認する
関連記事
- 測定が目標になるとき:窓税からPull Request数まで かつて僕は小さなツールを自作し、四半期で自分がどれだけPRに貢献したか、レビューコメントをどれだけ残したか、チケットをどれだけ消化したかを集計して、上司にアウトプットを証明しようとしたことがある。上司は淡々と、評価はアウトプットだけで見るものではないと言った。数年後、僕はようやく理解した――測定が目標になるとき、それはもはや良い測定ではなくなるのだ。英国の窓税、ハノイのネズミ駆除の報奨金から、現代のPR数による開発者評価に至るまで、そのメカニズムはまったく同じだ。
- Cloudflare Images を画像ストレージ・変換ソリューションとして使う ウェブページに画像を1枚置くのはフロントエンドにとって最も簡単なことだが、リサイズや各種フォーマットの生成、さらにはトラフィックの負荷に耐えることまで完璧にやろうとすると、実際には一つの包括的なソリューションが必要になる。僕はその後、すべて Cloudflare Images に任せるようになり、オリジナル画像1枚だけを渡すようにしている。
- もう AWS Access Key を使うのはやめよう Access Key は AWS において見落とされがちなセキュリティリスクだ。OIDC と IAM Role を組み合わせることで、GitHub Actions にシークレットを一切保持させることなく、安全に AWS リソースを操作できるようにする。
- データベース主キー:AUTO_INCREMENT、UUID、そしてUUIDv7 バックエンド開発で度々直面する主キーの決定。auto incrementを使うべきか、それともUUIDか?衝突への懸念は?UUIDv7とcreated_at + インデックスの性能差はどれほどか?実際に2,000万件のデータで検証したベンチマークと設計上の意思決定を解説する。