このすみ技術ろぐ

とあるWebエンジニアが、技術や趣味について書くブログです。

はてなブログの独自ドメインは、名前解決やHTTPS化をどのような技術で実現しているのか

私が今書いているブログは、はてなブログの独自ドメインを採用しています。 本ブログのドメインは、『www.konosumi.net』です。

何気なく使っているはてなブログの独自ドメインですが、内部的な仕組みが少し気になったので、調査ついでに概要をまとめてみました。

サブドメインにCNAMEを設定する

はてなブログの独自ドメインでは、ユーザーが自由に独自ドメインを決めることができます。 このドメインは、はてなブログ側が発行するわけではなく、自分自身でドメインサービスを契約して取得します。

『お名前.com』を使っている人が多そうですが、ブログで使いたいドメインに対してCNAMEを設定できれば良いので、特に契約するドメインサービスに制限はありません。

本題のCNAMEですが、はてなブログのヘルプを参照すると、サブドメインに対して『hatenablog.com.』を設定すれば良いことがわかります。

サブドメインを利用する
ドメイン取得後、ご利用のドメイン登録事業者の設定画面で、ブログを運用するサブドメインの参照先として hatenablog.com. を設定したCNAMEレコードを作成します。
引用:はてなブログのヘルプより

help.hatenablog.com

CNAMEとは何か

CNAMEは雑に解説すると、ドメインに対するエイリアスのようなものです。 特定のホスト名を、別のドメイン名に転送する時などに利用します。

CNAMEレコード【 Canonical Name record 】
CNAMEレコードとは、DNSで定義されるそのドメインについての情報の種類の一つで、あるドメイン名やホスト名の別名を定義するもの。 別名は「エイリアス」(alias)と呼ばれる。
http://e-words.jp/w/CNAME%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89.html より

Canonicalという言葉は、SEOにおけるURLの正規化で使う、canonicalタグでもおなじみです。 つまり、CNAMEが実現していることは、ドメインの正規化とも解釈できます。

本ブログも、『www.konosumi.net』に『hatenablog.com.』をCNAMEに設定しています。 そのため、独自ドメインに対する名前解決(IPアドレスの解決)は、最終的にはてなブログ側で行われることがわかります。

ネイキッドドメインを独自ドメインとして利用する

はてなブログの独自ドメイン設定の解説には、『ネイキッドドメイン(wwwなどのホスト名がつかないドメイン)を利用する場合』という記載があります。

ネイキットドメインとは何か

ネイキッドドメインとは、言ってしまえばサブのつかないドメインのことです。 『example.com』を例に挙げると、『www.example.com』や『test.example.com』はサブドメインで、『example.com』がネイキットドメインとなります。

ネイキットドメインはCNAMEが設定できない

ただしネイキットドメインには、欠点があります。 それはDNSの制限によって、CNAMEを設定できないサービスが多いという点です。

理由を探していたところ、Salesforceのヘルプドキュメントにたどり着きました。 詳しい解説があるので、ご一読をオススメします。

ネイキッドドメイン
ネイキッドドメインは、正規名レコード (CNAME) にできないドメインネームサーバ (DNS) 名です。 たとえば、www サブドメインのない hello.com などがこれに該当します。
〜中略〜
ネイキッドドメインでは CNAME レコードを設定できません。これは DNS の制限であり、Salesforce の制限ではありません。
〜中略〜
この制限を回避するために、いくつかの DNS ベンダーはネイキッドドメイン用の CNAME 動作を実装して、標準の CNAME 動作を模倣しています。
https://help.salesforce.com/articleView?id=domain_mgmt_naked_domains.htm&type=5 より

ここに書いてあるCNAME動作を模倣する例として、AWS Route 53などが挙げられます。 Route 53では、ドメイン名そのものへのCNAME設定(ただし、AWSのサービスに限る)が可能です。

なお、Route 53におけるネイキットドメインのCNAME設定は、Nedia様のブログ記事が参考になります。

www.nedia.ne.jp

Aレコードを使ってIPアドレスを紐付ける

ネイキットドメインではこれらの制約があるため、はてなブログ公式のヘルプでも、CNAMEではなくAレコードを使ってIPアドレスを紐付ける事例が紹介されています。

ネイキッドドメイン(wwwなどのホスト名がつかないドメイン)を利用する
ドメイン取得後、ご利用のドメイン登録事業者の設定画面で、ブログを運用する参照先としてAレコードを作成します。

  • 設定欄:設定する内容
  • 「ホスト名」や「サブドメイン」:空欄
  • 「TYPE」や「種別」:A
  • 「VALUE」や「値」や「内容」:13.230.115.161と13.115.18.61

https://help.hatenablog.com/entry/customdomain より

どちらの方法でもはてなブログの独自ドメインは実現できますが、エイリアスを使ったサブドメインのCNAMEのほうが素直です。

独自ドメインHTTPS化における証明書の発行

はてなブログの独自ドメインは、Let's Encryptで証明書が発行されています。 実際に私のブログで確認したところ、Let's Encryptが使われていました。

f:id:konosumi:20200706040153p:plain

なお以前のはてなブログでは、独自ドメインでHTTPSを使うことができませんでした。 当初はもっと早くリリースされる予定だったのですが、延期を経て、最終的に2018年6月より対応が開始されています。

staff.hatenablog.com

多種多様な独自ドメインによるHTTPSアクセスを、高速に捌くための工夫

『大規模なユーザーコンテンツのHTTPS化 Let's Encryptも活用した「はてなブログ」のこだわり』という記事を通じて、独自ドメインをHTTPS化するための取り組みや、実装上の創意工夫を垣間見ることができます。

geek-out.jp

DynamoDBで証明書を保存し、memcachedでキャッシュする

発行された証明書はAWS DynamoDBのデータストアに保存されますが、memcachedを使って、DynamoDBへのアクセスを減らす工夫が施されています。

一般的なWebサービスでも、RDBの負荷を減らすためにキャッシュを使うといった構成はよくありますが、これを証明書の返却で採用している点は興味深いです。

Nginxの拡張モジュール「ngx_mruby」のフックポイントを活用して、リクエストが来たら証明書を動的に読み込むようにしました。
〜中略〜
証明書配信用に開発したゲートウェイにmrubyからリクエストがあると、まずmemcachedに問い合わせを行います。そこに証明書があればそれを返して終わり。 なければ、マスターデータベースとなるAmazon DynamoDBにリクエストして証明書を取得し、mrubyに返答しつつmemcachedのキャッシュに書き込む形です。
https://geek-out.jp/column/entry/2018/10/02/110000/ より

ngx_mrubyとGo

また証明書読み込みの舞台裏では、cache gatewayへアクセスするngx_mrubyと、cache gateway上でGo言語が稼働しています。 ここで登場するmrubyとは軽量Rubyのことで、組み込みシステムなどのシビアな環境でも、実力を発揮できる軽さが特徴です。

AWSのStep FunctionsやLambdaを組み合わせた実装

独自ドメインHTTPS化対応のもうひとつの主役が、AWSのStep FunctionsとLambdaです。 これには、はてなのブログチームが公開している詳しい解説スライドがありますので、ぜひご参照ください。

主な登場人物はAWSで、独自ドメインのHTTPS化対応は、複数のAWSサービスが連携することで成り立っていることがわかります。

speakerdeck.com

適材適所の技術選定

はてなブログの本体側は、とくに変更がなければ現在もプログラミング言語はPerlだと思われます。

developer.hatenastaff.com

一方で、独自ドメインのHTTPS化ではmrubyとGoが採用されています。 プログラミング言語を先に決めるのではなく、利用するサービスや求める要件から逆算して決めている点に、私は注目しました。

ゲートウェイをはじめとする一連のサービスは、はてなブログで主に使っているPerlではなく、Goで書いています。
Let`s Encryptとの連携には、AWSのStep FunctionsやLambdaを活用することを決めていたため、Lambdaがサポートするランタイムの中から、静的に型を付けることができ、コンパイラの力を借りることができるもの……と考えていくと、ほぼ全会一致でGoに決まりました。Perlが好きな人には、意外とGoは書きやすいと思います。
https://geek-out.jp/column/entry/2018/10/02/110000/ より

適材適所でプログラミング言語を選定することは、技術選定の基本になるため、とても興味深いです。 記事を読む限り、福本さんはGoを書くのが今回が初めてだったらしい。

まとめ

はてなブログでは、多種多様な独自ドメインのHTTPS化に対応するため、さまざまな工夫がされていることがわかりました。

  • CNAMEを使った独自ドメインの名前解決
  • ネイキットドメインのAレコードを使う事例
  • Let's Encryptでの証明書発行
  • キャッシュとデータストアの二段構え
  • ngx_mrubyとGoの採用
  • ...etc

技術的にも興味深かったので、もしWeb関連のエンジニアの方あれば、『はてなブログHTTPS化対応』を読んでみてはいかがでしょうか?

geek-out.jp