0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Goで理解するDNSサーバー

Last updated at Posted at 2026-01-19

要約

  • DNSサーバーはドメイン名から複数のレコードを問い合わせることができる
    • IPアドレス(A)
    • 配送先のメールサーバー(MX)
    • 権威DNSサーバー(NS)等
  • DNSサーバーではUDPとTCPプロトコルを使用する
    • UDP:通常の問い合わせのメッセージに使用する(軽量、低遅延)
    • TCP:問い合わせのメッセージ量が大きく応答しきれない場合や、権威DNSサーバー間のゾーン転送に使用する

背景

業務でメール送信サービスの設定をいじっていた際にDNSについて見ました。
今回はDNSについて概要を理解したいと思います。

DNS(Domain Name System)とは

サーバーのドメインをipアドレスにマッピングする機能です。
他にはドメインから配送先のメールサーバーにマッピングしてくれます。
DNSによってドメインから問い合わせることを名前解決(Name Resolution)と言います。

試しにdigコマンドでexample.comのipアドレスを取得します。
digコマンドを使うことでDNSサーバーにドメインのIPアドレスを問い合わせることができます(DNSクライアントという)。

dig example.com
~~~略~~~~~~~~~~~~
;; QUESTION SECTION:
;example.com.			IN	A

;; ANSWER SECTION:
example.com.		139	IN	A	104.18.26.120
example.com.		139	IN	A	104.18.27.120

ANSWER SECTIONというのが問い合わせしたドメインに対する回答です。
以下二つのIPアドレスが返ってきました。

  • 104.18.26.120
  • 104.18.27.120

今回の例だと1ドメインで複数IPという対応になっていました。

image.png

GoでDNSサーバーを実装する

こちらのライブラリを使って実装します。

以下が今回実装したものです。

コードの説明

TCPとUDPプロトコルでサーバーを立ち上げます。

DNSの問い合わせ応答は、軽量・低遅延で高速にやり取りするため、従来は主にUDPが使われてきました。
古典的なDNSでは、UDPで受け取れる応答サイズは512バイトが上限でした。
ただしEDNS0(DNSメッセージサイズの制限を緩和するための拡張機能)があるため現在は512バイト超も一般的になりました。
それでも大きすぎるとTC(Truncated)フラグが立ってTCPで再問い合わせになります(いわゆるTCPフォールバック)
なお、ゾーン転送は設計上TCPが使われます。

権威DNSサーバーとは
自分の管理する範囲内のIPアドレスとドメイン名の対応表(ゾーンファイル)を持っていて、問い合わせに対してはその対応表をもとに返事をするDNSサーバのこと

ゾーン転送とは
ゾーンファイルの中身を他のDNSサーバに伝えること

世界に13系統で存在する DNSルートサーバー(a〜m) の情報をすべて格納しています。実際のサーバーはanycastにより世界中に分散配置されています。

再帰的な名前解決を実装する際に使われます。ドメイン名を解決するとき、まずルートサーバーに問い合わせを行い、そこから順にTLDサーバー → 権威サーバーへと辿ります。

名前解決の処理を実装しています。
処理の概要は以下です。
example.com を解決する場合:

  1. ルートサーバー(198.41.0.4)に問い合わせ

    • DNSレコードからcomドメインの権威サーバーについてのレコードを見つける
    • a.gtld-servers.net (192.5.6.30)を取得する
  2. TLD(トップレベルドメイン)サーバー(192.5.6.30)に問い合わせ

    • DNSレコードからexample.comドメインの権威サーバーについてのレコードを見つける
    • ns1.example.com (93.184.216.34) を取得する
  3. 権威サーバー(93.184.216.34)に問い合わせ

    • example.comドメインのipアドレスは93.184.216.34
  4. キャッシュに保存して返却

TLD(トップレベルドメイン)とは
ドメイン名において、ドットで区切られた文字列の一番右の部分(ラベル)のこと

手動で登録するDNSレコードを管理するための処理です。

DNSによる名前解決の結果をメモリにキャッシュします。
同じドメインへの繰り返しクエリを高速化します。

DNSサーバー立ち上げから動作確認まで

DNSサーバーのIPアドレスをlocalhost(127.0.0.1)に設定します。

スクリーンショット 2026-01-19 20.36.59.png

buildしたファイルを実行します。

sudo ./dns-server

example.comについてdigコマンドで実行します。

 dig @localhost example.com

サーバーのログを見ると以下が確認できます。

2026/01/18 14:41:33 Query: A example.com.
2026/01/18 14:41:34 Result: example.com. -> 104.18.27.120, 104.18.26.120

ドメインから配送先のメールサーバーのドメインを問い合わせる

digコマンドを使うと以下のように問い合わせることができます。
MXというのはMail eXhangeの略です。

dig MX gmail.com

~~~~~略~~~~~~~~
;; QUESTION SECTION:
;gmail.com.			IN	MX

;; ANSWER SECTION:
gmail.com.		1314	IN	MX	20 alt2.gmail-smtp-in.l.google.com.
gmail.com.		1314	IN	MX	5 gmail-smtp-in.l.google.com.
gmail.com.		1314	IN	MX	40 alt4.gmail-smtp-in.l.google.com.
gmail.com.		1314	IN	MX	30 alt3.gmail-smtp-in.l.google.com.
gmail.com.		1314	IN	MX	10 alt1.gmail-smtp-in.l.google.com.

今回作成したDNSサーバーにも問い合わせると以下のようになりました。

Query: MX gmail.com.
2026/01/19 20:56:38 Result: gmail.com. -> 20 alt2.gmail-smtp-in.l.google.com., 30 alt3.gmail-smtp-in.l.google.com., 10 alt1.gmail-smtp-in.l.google.com., 5 gmail-smtp-in.l.google.com., 40 alt4.gmail-smtp-in.l.google.com.

まとめ

  • DNSサーバーはドメイン名から複数のレコードを問い合わせることができる
    • IPアドレス(A)
    • 配送先のメールサーバー(MX)
    • 権威DNSサーバー(NS)等
  • DNSサーバーではUDPとTCPプロトコルを使用する
    • UDP:通常の問い合わせのメッセージに使用する(軽量、低遅延)
    • TCP:問い合わせのメッセージ量が大きく応答しきれない場合や、権威DNSサーバー間のゾーン転送に使用する

参考

最後に

  • DNS、UDP、TCPプロコルについて概要を掴めました
  • UDP、TCPの使い分けについても理解できました
  • 深掘りが足りてないところを深ぼりたいです
  • 逆引きについても勉強したいです
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?