概要
表題の通り
2015/8/22)
iptablesで落としていたルールが NXDOMAINだったらDROPではなく
レコードがなかったらDROPであったため修正しました。
テスト環境
Private DNSサーバ | 管理ドメイン |
---|---|
192.168.7.129 | example.net |
テスト内容
No | 問い合わせ | Private DNSサーバへのRecode存在有無 | 外部権威DNSへのRecode存在有無 | 期待する結果 |
---|---|---|---|---|
1 | private.example.net | 有 | 無 | Private DNS が 192.168.7.129 を返す |
2 | www.example.net | 無 | 有 | 外部権威DNS が 93.184.216.34 を返す |
bindの設定
example.net を bind の view で 127.0.0.1 に forward し、そこを権威として設定する
named.conf
view local {
match-clients { 127.0.0.1;};
recursion no;
zone "example.net." {
type master;
file "zone/example.net.zone";
};
};
view public {
match-clients { any;};
recursion yes;
zone "." {
type hint;
file "conf/named.ca";
};
zone "example.net." {
type forward;
forwarders { 127.0.0.1; };
forward first ;
};
};
zone/example.net.zone
$TTL 5
@ IN SOA example.net. root.example.net. (
2015080101 ; Serial
3600 ; Refresh
300 ; Retry
3600000 ; Expire
3600 ; Minimum
)
@ IN NS ns.example.net.
@ IN A 192.168.7.129
ns IN A 192.168.7.129
private IN A 192.168.0.1
※ dnssec関連の設定は無効にすること
テスト
test1
$ dig @192.168.7.129 private.example.net
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27575
private.example.net. 5 IN A 192.168.0.1
成功!!
test2
$ dig @192.168.7.129 www.example.net
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 3048
失敗!!
forwarderからNXDOMAINが返って来ても、再帰問い合わせはしてくれない。
forward first はforward先からの応答が返ってこない場合に再帰問い合わせをするので
NXDOMAINのパケットがforwarderから返って来たら捨てることにする
iptablesの設定
iptablesに 127.0.0.1 からの応答クエリかつ、NXDOMAINのクエリだった場合、DROPするルール
(NOERRORは DROPしない)
/etc/sysconfig/iptables
# 応答クエリの判定
-A INPUT -p udp -s 127.0.0.1 --sport 53 -m string --hex-string "|8503|" --algo bm --from 30 --to 32 -m comment --comment "check dns reply" -j DROP
テスト
test1
# iptables -L -nxv | grep ALGO
0 0 NXDROP udp -- * * 127.0.0.1 0.0.0.0/0 udp spt:53 STRING match "|85|" ALGO name bm FROM 30 TO 31 /* check dns reply */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "|0000|" ALGO name bm FROM 34 TO 36 /* drop nxdomain query */
# dig @192.168.7.129 private.example.net
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64385
private.example.net. 5 IN A 192.168.0.1
# iptables -L -nxv | grep ALGO
1 125 NXDROP udp -- * * 127.0.0.1 0.0.0.0/0 udp spt:53 STRING match "|85|" ALGO name bm FROM 30 TO 31 /* check dns reply */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "|0000|" ALGO name bm FROM 34 TO 36 /* drop nxdomain query */
=> NXDOMAINではないので捨てていない
test2
# iptables -L -nxv | grep ALGO
0 0 NXDROP udp -- * * 127.0.0.1 0.0.0.0/0 udp spt:53 STRING match "|85|" ALGO name bm FROM 30 TO 31 /* check dns reply */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "|0000|" ALGO name bm FROM 34 TO 36 /* drop nxdomain query */
# dig @192.168.7.129 www.example.net
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2848
www.example.net. 5 IN A 93.184.216.34
成功!!
# iptables -L -nxv | grep ALGO
2 226 NXDROP udp -- * * 127.0.0.1 0.0.0.0/0 udp spt:53 STRING match "|85|" ALGO name bm FROM 30 TO 31 /* check dns reply */
2 226 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "|0000|" ALGO name bm FROM 34 TO 36 /* drop nxdomain query */
=> NXDOMAINだったので捨てている
結果
この手法では、cacheに載っていない問い合わせについて数秒応答にかかってしまう。
unboundだったら簡単にできるのでzone転送をしなくてもよい単独DNSであればunboundで素直に構築するのがいいと思います。