ネームサーバを公開しました。
ネームサーバって何?
名前解決と言われる仕組みのなかで、名前から 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
というのが1度しか働いてくれません。
プロセスは起動したままで、いったい何でサボっているんでしょうか?
苦肉の策としてタイムアウトを1秒にして終了させます。
終了したら実行を繰り返し行います。
なので1度利用したら次に利用できるのは1秒後です。
早速試してみよう♪
$ 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 で同じことをやりたかったが、できませんでした。
できるよっていうお方がおられたらコメントお願いします。