嘘つきDNSを立てる

ちょっと必要があって、嘘つきDNS proxyを立てる。
特定のDNSを名前引きサーバーに指定しておくと、よく知られたホストが違うIPアドレスに誘導される。
DNSポイゾニングとかでよく使われる方法。
今回は、複雑なのはいらないので、さくらクラウドのサーバーインスタンス上に、dnsmasqでさくっと構築する。
が、サクっとはいかなかった... orz


さくらクラウドUbuntuインスタンスを最小構成で立てる。

ubuntu@DNSProxy:~$ sudo apt-get update
ubuntu@DNSProxy:~$ dpkg -l | wc
    383    3727   48112

標準パッケージ数はいい感じ。
とりあえず名前から引いてみる。当たり前だけど普通に引ける。

ubuntu@DNSProxy:~$ dig www.google.com | grep '^www.google.com'
www.google.com.		85	IN	A	216.58.197.228
ubuntu@DNSProxy:~$ dig google-public-dns-a.google.com | grep '^google-public-dns-a.google.com'
google-public-dns-a.google.com.	86400 IN A	8.8.8.8

標準の名前引き関係の設定は、こうなっている。

ubuntu@DNSProxy:~$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 133.242.0.3
nameserver 133.242.0.4
search localdomain

ubuntu@DNSProxy:~$ cat /etc/hosts
127.0.0.1	localhost


# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters


dnsmasqを入れる。

ubuntu@DNSProxy:~$ sudo apt-get install dnsmasq
sudo: unable to resolve host DNSProxy
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  dbus dns-root-data dnsmasq-base libdbus-1-3 libnetfilter-conntrack3
Suggested packages:
  dbus-user-session | dbus-x11
The following NEW packages will be installed:
  dbus dns-root-data dnsmasq dnsmasq-base libdbus-1-3 libnetfilter-conntrack3
0 upgraded, 6 newly installed, 0 to remove and 52 not upgraded.
Need to get 665 kB of archives.
After this operation, 2,005 kB of additional disk space will be used.
(snip)

名前引きの設定は書き換わる。

ubuntu@DNSProxy:~$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1
search localdomain

DNS情報がなくなったので、当然名前で引けなくなっている。

ubuntu@DNSProxy:~$ dig www.google.com

; <<>> DiG 9.10.3-P4-Ubuntu <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 37343
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.google.com.			IN	A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Sep 29 20:19:12 JST 2016
;; MSG SIZE  rcvd: 32


hostsファイルに嘘の名前解決情報を登録する。
嘘つくものは、/etc/hostsに書いておくだけで良い。

ubuntu@DNSProxy:~$ sudo vi /etc/hosts
127.0.0.1       localhost DNSProxy
192.0.2.1 www.google.com
192.0.2.2 google-public-dns-a.google.com

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

dnsmasqはデフォルトでは、ポート53で動作している。
外のマシンから見ても開いているのがわかる。

$ nmap 153.127.196.129

Starting Nmap 6.40 ( http://nmap.org ) at 2016-09-30 16:13 JST
Nmap scan report for 153.127.196.129
Host is up (0.027s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
53/tcp open  domain

Nmap done: 1 IP address (1 host up) scanned in 0.49 seconds

しかし、起動しただけだと、外からは引けない。

$ dig @153.127.196.129 www.google.com

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.4 <<>> @153.127.196.129 www.google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

中からも引けなかった... orz

ubuntu@DNSProxy:~$ dig www.google.com

; <<>> DiG 9.10.3-P4-Ubuntu <<>> www.google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 49890
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.google.com.			IN	A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Sep 30 16:19:06 JST 2016
;; MSG SIZE  rcvd: 32

dnsmasqはhostsの即時反映ではなく、再起動は必要な感じ。
再起動すると引けた。

ubuntu@DNSProxy:~$ sudo systemctl restart dnsmasq
ubuntu@DNSProxy:~$ dig www.google.com | grep '^www.google.com'
www.google.com.		0	IN	A	192.0.2.1


dnsmasqの設定を行う。
デフォルトの設定ファイルは長いけれど、全てコメントアウトされていて何もない。
今回必要な設定はこのくらい。

port=53
resolv-file=/etc/resolv.conf
interface=eth0
listen-address=0.0.0.0

ただし、ubuntuの場合は、起動時に-rで/var/run/dnsmasq/resolv.confがハードコードされていてresolv-fileはここで書いても無効になる(これがあとでメンドクサイ部分)。
なので、この3つだけ設定する。

ubuntu@DNSProxy:~$ sudo vi /etc/dnsmasq.conf
port=53
interface=eth0
listen-address=0.0.0.0
ubuntu@DNSProxy:~$ sudo systemctl restart dnsmasq

外からでも引けるようになった。

[kinneko@myserver ~]$ dig @153.127.196.129 www.google.com | grep '^www.google.com'
www.google.com.		0	IN	A	192.0.2.1
MacBook:~ kinneko$ dig @153.127.196.129 www.google.com | grep '^www.google.com'
www.google.com.		0	IN	A	192.0.2.1


たま、DNSサーバーが指定されていない状態なので、書かれた以外のホスト名の解決ができない。
Ubuntuパッケージ的な条件で、参照先を書いたファイルがからっぽだからだ。

ubuntu@DNSProxy:~$ ls -l /var/run/dnsmasq/resolv.conf
-rw-r--r-- 1 root root 0 Sep 30 16:37 /var/run/dnsmasq/resolv.conf

このファイルは、resolvconfというプログラムがイベントドリブンで作っている。
普通の/etc/resolv.confは、手で書き換えても再起動で上書きされてしまう。
もはや、古きよき時代ではないってことね...


dnsmasqを導入する前には、resolv.confは、以下の2つのファイルを剛性して作られていた。

ubuntu@DNSProxy:~$ ls /etc/resolvconf/resolv.conf.d/
base  head
ubuntu@DNSProxy:~$ cat /etc/resolvconf/resolv.conf.d/head
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
ubuntu@DNSProxy:~$ cat /etc/resolvconf/resolv.conf.d/base
nameserver 133.242.0.3
nameserver 133.242.0.4
search localdomain

dnsmasqを導入後は、/etc/resolvconf/update.d/dnsmasqが/var/run/dnsmasq/resolv.confを生成している。
このスクリプトは、/etc/resolvconf/resolv.conf.d/baseは見ていないので、DNSサーバーがわからない。
そのため、/etc/network/interfacesでインターフェイスDNSをハードコードするという雑な対応になる。
すると、ネットワーク情報の更新時に連動してアップデートされるはず...
動作中にDNSが変更されることを考慮していないのはつらい。
ただ、幸いなことに、このマシンはデスクトップではないので、NetworkManagerは動いていないので、それほど複雑でもない。

ubuntu@DNSProxy:~$ sudo vi /etc/network/interfaces
dns-nameservers 133.242.0.3
dns-nameservers 133.242.0.4
ubuntu@DNSProxy:~$ sudo systemctl restart networking.service

ログにも出た。

Sep 30 17:02:00 DNSProxy dnsmasq[3445]: using nameserver 133.242.0.3#53

/var/run/dnsmasq/resolv.confにも反映されている。

ubuntu@DNSProxy:~$ cat /var/run/dnsmasq/resolv.conf
nameserver 133.242.0.3
nameserver 133.242.0.4

他のマシンからも、引けるようになった。

[kinneko@UDP01 ~]$ dig @153.127.196.129 www.hp.com | grep '^www.hp'
www.hp.com.		3586	IN	CNAME	www.hpgtm.nsatc.net.
www.hpgtm.nsatc.net.	106	IN	A	15.240.238.61
www.hpgtm.nsatc.net.	106	IN	A	15.201.49.153
MacBook:~ kinneko$  dig @153.127.196.129 www.hp.com | grep '^www.hp'
www.hp.com.		3540	IN	CNAME	www.hpgtm.nsatc.net.
www.hpgtm.nsatc.net.	60	IN	A	15.240.238.61
www.hpgtm.nsatc.net.	60	IN	A	15.201.49.153


今回はfirewallは動作していない状態でテストした。

ubuntu@DNSProxy:~$ sudo ufw status
sudo: unable to resolve host DNSProxy: Connection timed out
Status: inactive

WAN上で常時稼働するのであれば、ufwも適宜設定しておく必要がある。