ネームサーバを公開しました

## ネームサーバを公開しました。

### ネームサーバって何？

名前解決と言われる仕組みのなかで、名前から IP アドレスを教えてくれるサービスのことです。

どういうことができるかやってみましょう。

```
$ dig github.io

; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> github.io
.
.
;; ANSWER SECTION:
github.io.              300     IN      A       185.199.109.153
github.io.              300     IN      A       185.199.110.153
github.io.              300     IN      A       185.199.111.153
github.io.              300     IN      A       185.199.108.153

;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
```

ANSWER として 4 つの IP アドレスを教えてくれました。
ネームサーバは `127.0.0.53` になっています。

ん？ `127.0.0.53` って何者なんだろうか？

ネームサーバといえば bind9 などいろいろな知識を必要として、
それなりの設定をしないといけないはずだが、そんなもの起動していません。

どうやら systemd-resolved というのがやってくれているようです。

そこで、この `127.0.0.53` を公開したいと思います。

### 環境

```
Ubuntu 22.04.1 LTS
AMD64(x86-64)
```

### SSH でフォワードしてみよう！

ネームサーバのポート番号は 53 番ポートなので 0.0.0.0:53 にポートフォワードします。

```
$ ssh -L 0.0.0.0:53:127.0.0.53:53 -o "StrictHostKeyChecking no" -o "RequestTTY force" 127.0.0.1
```

はい、できました。

#### 早速試してみよう♪

```
$ dig github.io @127.0.0.1
;; communications error to 127.0.0.1#53: connection refused
```

エラーになりました。

### UDP もフォワードしてみよう！

```
$ {
  [[ -e /tmp/pipe-udp ]] && unlink /tmp/pipe-udp
  mkfifo /tmp/pipe-udp
  while true
  do
    nc -w 1 -ul 0.0.0.0 53 < /tmp/pipe-udp | nc -u 127.0.0.53 53 > /tmp/pipe-udp
  done
}
```

はい、できました。

`nc -ul 0.0.0.0 53` というのが１度しか働いてくれません。
プロセスは起動したままで、いったい何でサボっているんでしょうか？
苦肉の策としてタイムアウトを１秒にして終了させます。
終了したら実行を繰り返し行います。
なので１度利用したら次に利用できるのは１秒後です。

#### 早速試してみよう♪

```
$ dig github.io @127.0.0.1

; <<>> DiG 9.16.1-Ubuntu <<>> github.io @127.0.0.1
・
・
;; ANSWER SECTION:
github.io.		14	IN	A	185.199.108.153
github.io.		14	IN	A	185.199.109.153
github.io.		14	IN	A	185.199.111.153
github.io.		14	IN	A	185.199.110.153

;; SERVER: 127.0.0.1#53(127.0.0.1)
```

はい、できました。
ファイアウォールで 53 番ポートを公開すれば他の PC から利用できるようになります。

### ホストを登録してみよう

hosts にホストを追加します。

```
$ echo "127.0.0.1 kubernetes hoge huga hige hage debu" | sudo tee -a /etc/hosts
```

#### 早速試してみよう♪

```
$ dig hige @127.0.0.1

; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> hige @127.0.0.1
・
・
;; ANSWER SECTION:
hige.			0	IN	A	127.0.0.1

;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
```

おぉ〜♪

```
$ dig hage @127.0.0.1

; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> hige @127.0.0.1
・
・
;; ANSWER SECTION:
hage.			0	IN	A	127.0.0.1

;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
```

おぉ〜♪

こんな便利なことができるのか！
今まで苦労して bind9 を設定してたのが馬鹿馬鹿しいな。

### 成果物

bash のスクリプトで実装

```
#!/usr/bin/env bash
set -u

tcpForward() {
  /etc/init.d/ssh start
  ssh -L 0.0.0.0:53:127.0.0.53:53 -o "StrictHostKeyChecking no" -o "RequestTTY force" 127.0.0.1
}

udpForward() {
  [[ -e /tmp/pipe-udp ]] && unlink /tmp/pipe-udp
  mkfifo /tmp/pipe-udp
  while true
  do
    nc -w 1 -ul 0.0.0.0 53 < /tmp/pipe-udp | nc -u 127.0.0.53 53 > /tmp/pipe-udp
  done
}

tcpForward &
udpForward &
wait
```

実行方法

```
# forwardDNS というファイル名で保存して実行権限を付与
$ chmod +x forwardDNS

# root 権限で forwardDNS を実行
$ sudo ./forwardDNS
```

### まとめ

ネームサーバは UDP の 53 番ポートを公開する必要がある。
必要なら TCP の 53 番ポートも公開する。（サイズが大きいとき）
SSH のポートフォワードは TCP しかできない。
root 権限で実行する必要がある。

こんなに簡単にできました。

なんでこんなことしたかったかといいますと、
bind9 のようなネームサーバを立ち上げて
いろいろ設定したり管理したりするのは、
そこまでの本格的な性能は求めておらず、
systemd-resolved の機能を公開すれば済むと、
そういう発想から生まれました。

/etc/hosts の設定を変更すれば即時に反映される
という簡単な手順で管理できるのがいいですね。

iptables で同じことをやりたかったが、できませんでした。
できるよっていうお方がおられたらコメントお願いします。