社内サービスのTLS証明書運用、正しいやり方教えます
TLS certificates for internal services done right
TLS certificates for internal services done right
社内向けのサービスでTLS証明書をどう管理するか、迷ったことはありませんか?ここでは、セキュアかつ効率的な社内向けTLS証明書運用のベストプラクティスを解説します。運用コストを最小化しつつ、証明書の更新作業を自動化・簡略化するための実践的なアプローチを紹介します。
外部に公開するプロキシ経由ですべてトンネリングさせるのが「正しい内部サービスのTLS証明書運用」だなんて、到底思えないな。
自分はパブリックドメインでacmeのdns-01チャレンジを使ってるよ。これなら他のものをパブリックインターネットに晒すことなく、好きなように証明書を取得できるからね。あとはTailscaleを使っているから、DNS設定でTailscaleのIPアドレスを向けるようにしている。もしパブリックなDNSサーバーで公開したくないなら、内部DNSサーバーにだけ登録すればいいよ。
自分のおすすめの手順は、DNS-01認証を使って、内部サービス向けにはパブリックにアクセス可能な「A」や「AAAA」レコードを一切作らないことだね。もっと極端な例を挙げると、https://crt.sh/?id=27555237869 (サイトが落ちてたらごめん) のような場合、このドメイン名はパブリックにもプライベートなDNSにも単独で存在したことがないんだ。WPA3-Enterpriseネットワーク専用で、Wi-FiクライアントがRADIUSサーバーの証明書に期待するCNとしてのみ使われていて、DNSで解決されることはない。パブリックDNSには「_acme-challenge」のTXTレコードしか存在しないよ。
「正しいやり方」と「スプリットホライズンDNS」という言葉が並んでると、なんだかムズムズするな。内部サービスでACME証明書を取得するなら、素直にDNS認証を使うのが一番だよ。長期的にはその方がずっと頭を抱えずに済む。スプリットホライズンDNS(それによって発生する、パブリックレコードをプライベートDNSにもミラーリングしなきゃいけないという面倒な作業)からは、自分の経験上、脱却を目指すべきものだね。
個人的にはスプリットホライズンDNSは嫌いだな。自分は「BeyondCorp」モデルの方が好き。VPNに頼るより、信頼できるデバイスにmTLS証明書を入れる方がずっといい。これまで「賢い」DNS設定がトラブルを引き起こさないのを見たことがないしね。具体的には、Grafanaをスマホで気軽に見たいんだけど、スマホでスプリットホライズンDNSや企業VPNを使うのは、控えめに言っても苦痛だよ。HA-Proxyでもできるだろうけど、自分は https://github.com/ThomasHabets/sni-router を使ってる。
ここでの本当の回答は、HTTPSクライアントが自己署名(または内部CA署名)の証明書を信頼するように設定するのが、現状ほど難しくあるべきではないってことだと思う。プログラミング言語ごとにOSの信頼ストアを見に行くんじゃなくて、独自の証明書置き場を想定しているのが本当にイライラする。
これは正気じゃないね。自宅ネットワークで少数の内部サービスを動かしているだけとか、エンドポイントを制御できない環境なら、素直にDNS認証を使えばいい。それが存在理由なんだから。でも、自分で管理しているホストなら、確実にIDを付与してローカルCAに参加させるべきだよ。他の多くの理由から、いずれ必要になるはずだから。
うーん、自分はホームネットワークのホスト名が漏洩しても全く気にならないな。だって「router」「laptop」「tv」「nas」みたいなありふれた名前ばかりだし。だからCloudflareのパブリックゾーンをそのまま使ってるよ。パブリックゾーンに内部IP(nas.example.com = 10.1.2.3 とか)を書いて、Let's Encrypt用にDNS01チャレンジを使ってるだけ。誰でも自分のホストのIPを解決できちゃうけど、そこにアクセスするには当然WireGuard VPNに入ってないと無理だしね。これのおかげで、1.1.1.1や8.8.8.8、nextDNSみたいなパブリックDNSサーバーをいつでも使える。決して「正しいやり方」じゃないけど、手間はほとんどかからないし、複雑なメッシュ構成なんかと違ってこれまで一度も失敗したことがないよ。
スプリットホライズンDNSをやる気にはなれないな。自分なら .internal か .home.arpa を使って、step-caとbindを通信させるよ。Kubernetesならstep-issuerを使ってもいいし、DNS-01戦略でいきたいならrfc2136でもいい。内部CAのルート証明書をあちこちに配布して、自宅のインフラをcrt.shのログから除外しておく。*.mydomain.comのワイルドカード証明書を使えば楽なのは分かってるけど、それだと結局パブリックログに残っちゃうからね。
あるいは……・スプリットDNSを使わない。特殊な内部ドメインや開発用ドメインも使わない。パブリックIPを内部ネットワークにルーティング/NATするのはインフラ側に任せる。・HTTP-01チャレンジを使わない。DNS-01を使う。・独自の内部CAを運用しない。Let's Encryptを使う。名前の漏洩(CTログ)が気になるならワイルドカード証明書を使う。SSL終端には中央集権的なリバースプロキシ/ロードバランサーを使う。