2026年6月5日

2026年6月5日

マルチテナント用サブドメインをDNS設定する方法:個別レコード・独自ドメイン接続・削除時の注意

マルチテナントのDNSは、ワイルドカードレコードで全テナントを一括で受ける方法のほかに、テナントごとに個別のレコードを作る方法や、顧客の独自ドメインをCNAMEで自社サービスへ向けてもらう方法があります。テナントごとに向き先を変えたい、独自ドメインを受け付けたい、という要件が出た時点で、DNSの設計と運用の考え方が変わります。この記事では、個別レコードの使いどころ、DNS APIによる自動化、独自ドメイン接続の手順と所有確認、そしてテナント削除時に起きやすいサブドメイン乗っ取りの防ぎ方を説明します。ワイルドカードレコードを使った基本の設定手順は、別記事「マルチテナント用サブドメインのDNS設定手順」にまとめています。

ワイルドカードか、個別レコードか

ワイルドカード *.app.example.com は設定が1件で済み、テナント追加時にDNSを操作しなくてよいのが利点です。一方、次のような要件があるときは、テナントごとの個別レコードが向いています。

  • テナントごとに収容サーバーやリージョンを分けたい: 大口テナントだけ専用環境に置く、地域ごとに別のクラスターへ振り分ける、といった運用です。
  • 存在しないテナント名を名前解決させたくない: ワイルドカードはどんな名前にも応答するため、入力ミスや第三者が勝手に作った名前もサーバーに届きます。
  • 段階的な移行をしたい: 新基盤へテナントを1件ずつ移すとき、レコード単位で向き先を切り替えられます。

両方を組み合わせることもできます。ワイルドカードを既定の向き先にしておき、例外のテナントだけ個別レコードで上書きする形です。DNSでは個別に登録した名前がワイルドカードより優先されるため、この使い分けが成り立ちます。

個別レコードはAPIで自動作成する

個別レコード方式を手作業で運用すると、テナント数が増えるにつれて作成漏れや削除漏れが起きやすくなります。テナントの作成・削除の処理にDNS APIの呼び出しを組み込むのが現実的です。

AWS Route 53 の場合は、変更内容をJSONで渡します。UPSERT は「無ければ作成、あれば更新」の意味です。

{
  "Comment": "tenant1 を追加",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "tenant1.app.example.com",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [{ "Value": "cluster-a.example.net" }]
      }
    }
  ]
}
aws route53 change-resource-record-sets \
  --hosted-zone-id YOUR_ZONE_ID \
  --change-batch file://change.json

Cloudflare の場合はREST APIでレコードを作成します。APIトークンはコードに直接書かず、環境変数などから読み込みます。

curl -X POST "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records" \
  -H "Authorization: Bearer ${CF_API_TOKEN}" \
  -H "Content-Type: application/json" \
  --data '{"type":"CNAME","name":"tenant1.app.example.com","content":"cluster-a.example.net","ttl":300,"proxied":false}'

自動化するときの注意点は次のとおりです。

  • APIトークンは対象ゾーンのDNS編集だけに絞る: アプリケーションサーバーが侵害されたときに、ほかのゾーンやアカウント設定まで変更されるのを防ぎます。
  • 作成と削除を対にする: テナント削除の処理でレコード削除が失敗した場合に備え、DNSの一覧とテナント管理DBを定期的に突き合わせるバッチを用意しておくと安心です。
  • テナント名の文字を検証する: DNSのラベルは英数字とハイフンで、1ラベル63文字までです。利用者が入力した名前をそのままAPIに渡さず、許可する文字と長さを検査します。

顧客の独自ドメインを接続する

shop.customer.jp のような顧客のドメインでサービスを使ってもらう場合、DNSを設定するのは顧客側です。自社は「どこへ向ければよいか」と「本当にそのドメインの持ち主か」を確認する仕組みを用意します。

接続先のホスト名を用意する

顧客には、IPアドレスではなく自社が管理するホスト名(例: custom.app.example.com)へのCNAMEを案内します。IPアドレスを直接案内すると、サーバー移転のたびに全顧客へ設定変更を依頼することになります。CNAMEであれば、自社側の custom.app.example.com を書き換えるだけで済みます。

; 顧客側のDNSに設定してもらう例
shop.customer.jp.   3600  IN  CNAME  custom.app.example.com.

ドメインの頂点(apex)を使いたいと言われたら

customer.jp そのもの(頂点)にはCNAMEを置けません。この場合は、顧客のDNS事業者が提供するALIAS系の機能(CNAMEフラットニングなど)を使ってもらうか、www.customer.jp を正式なURLにして頂点からリダイレクトしてもらう方法を案内します。固定IPアドレスでAレコードを設定してもらう方法もありますが、先ほどの理由から移転時の負担が大きくなります。

所有確認のTXTレコード

CNAMEの向き先が自社になっているだけでは、そのドメインの持ち主が申請したとは限りません。テナントごとにランダムなトークンを発行し、TXTレコードで所有を確認する仕組みがよく使われます。

_verify.shop.customer.jp.   300  IN  TXT  "app-verify=ランダムなトークン"

サービス側では、確認ボタンが押されたときにTXTレコードを引き、トークンが一致した場合だけ独自ドメインを有効にします。確認に使った後も、定期的にCNAMEが自社を向いているかを再確認しておくと、顧客がDNSを別サービスへ切り替えたことに気づけます。SSL証明書の発行は所有確認が済んでからにします。

テナント削除時に起きるサブドメイン乗っ取り

DNS運用で見落とされやすいのが、削除後に残るレコードです。たとえば tenant9.app.example.com がクラウドのストレージやPaaSのホスト名へCNAMEで向いたままで、向き先のリソースだけ削除された状態を考えます。第三者が同じ名前のリソースを作成できると、自社のサブドメインで任意の内容を配信される恐れがあります。これがサブドメイン乗っ取り(subdomain takeover)と呼ばれる問題です。

防ぎ方は次のとおりです。

  • 削除の順番を守る: 先にDNSレコードを消し、その後に向き先のリソースを削除します。
  • 棚卸しを定期的に行う: ゾーン内のCNAMEを一覧にし、向き先が応答しない、あるいは事業者の「存在しないリソース」のページが返るものを洗い出します。
  • 独自ドメイン側も監視する: 顧客が自社を指すCNAMEを残したまま解約した場合、そのホスト名は自社サービスへ届き続けます。未登録のホスト名には応答しない、証明書も発行しない、という扱いをアプリ側で徹底します。

確認方法

レコードを作成・変更したら、権威DNSサーバーに直接問い合わせて結果を確認します。

dig NS app.example.com +short
dig @ns1.example-dns.com tenant1.app.example.com CNAME +short
dig _verify.shop.customer.jp TXT +short

API経由で作ったレコードは、管理画面上の表示と実際の応答が一致しているかもあわせて確認します。DNS事業者の管理画面やAPIの仕様は変更されることがあるため、作業時点の公式ドキュメントを参照してください(2026年10月現在)。

まとめ

  • ワイルドカードは手軽ですが、テナントごとの振り分けや不要な名前を解決させない運用には個別レコードが向いています。両者の併用もできます。
  • 個別レコードはDNS APIでテナントの作成・削除処理に組み込み、権限を絞ったトークンを使い、DBとの突き合わせを定期的に行います。
  • 独自ドメインは自社管理のホスト名へのCNAMEで受け、TXTレコードで所有を確認してから有効化と証明書発行を行います。
  • 削除時はDNSレコードを先に消し、残ったCNAMEを棚卸しして、サブドメイン乗っ取りを防ぎます。ゾーンを変更する前には現在の設定をエクスポートして控えておきます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲