Cisco1812JでNATしている時にDNSの特定のレスポンスのパケットが落ちる件

環境

  • 1812J(IOS15.1)がゲートウェイ&NAT箱として機能している.
  • NAT下(inside)にDNSサーバがある
  • static natとroute-mapでtcp/udp53の通信はDialer2 IF経由でDNSサーバに到達するようになっている.
  • 外部(outside)からインターネットを経由してDNSサーバにリクエストをIPv4で送っている.

症状

IPv4の通信でNAT下(inside)のDNSサーバに名前解決(A)やゾーン転送(AXFR)の問い合わせを行ったときに,レスポンス(dst addressは問い合わせ元,src portはtcp/udp53)に問い合わせ元のIPv4アドレスが含まれていた場合にパケットが1812J内部で落ちる.

セカンダリへのゾーン転送が失敗する原因を調べていてたどり着いた.

以下はAXFRを要求したときの1812Jでのパケットダンプ.

http://www.yuyarin.net/screenshot/20110623040840.png

右が正常な通信.レスポンスとして送られるゾーン情報に問い合わせ元(セカンダリ)のアドレスのAレコードが載っていない場合は,VlanIFからDialerIFへパケットが送られている.

左が異常な通信.レスポンスとして送られるゾーン情報に問い合わせ元(セカンダリ)のアドレスのAレコードが載っている場合は,VlanIFに届いたパケットがどこにも行かずに破棄されている模様.

コメント

とりあえず送信元アドレスのバイナリ表現が含まれたパケットをTCPの適当なポートでやりとりするプログラムを試してみたが,これは問題なく通信できた.なのでDNSの通信固有の問題なのか...

ペイロードを見て落としているとしか思えない挙動.ルータで結構複雑なことをやっているので問題の切り分けが難しい.

NATに守られているので特にファイアウォールのような設定,とりわけペイロードまで除くような設定は入れたいないのだが,いったい何が原因なんだろう...

ip cef や ip domain-name などは調べてみたけど問題なさそう.

分析

NATに失敗しているみたい.

ns2.yuyarin.net(49.212.49.25) から ns.yuyarin.net(221.189.114.163) を引いたもの(成功)とns2.yuyarin.netを引いたもの(失敗).NATの変換テーブルはどちらでも一見正常に作成されている.

DNSパケットをNATに通すときにペイロード書き換えが行われているらしい

// succeeded
Jun 28 01:21:34.189: NAT: o: udp (49.212.49.25, 36960) -> (221.189.114.163, 53) [235]    
Jun 28 01:21:34.189: NAT (UDP-DNS): Before Translation
Jun 28 01:21:34.189: NAT: Translation of UDP DNS src 49.212.49.25, dst 221.189.114.163
Jun 28 01:21:34.189: NAT: Dns type of Query
Jun 28 01:21:34.189:    : dns len=20, id=36929, aa=0, tc=0, rd=1, ra=0
Jun 28 01:21:34.189:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:34.189:    : ancount=0, nscount=0, arcount=0
Jun 28 01:21:34.189: NAT (UDP-DNS): After Translation
Jun 28 01:21:34.189: NAT: Translation of UDP DNS src 49.212.49.25, dst 221.189.114.163
Jun 28 01:21:34.189: NAT: Dns type of Query
Jun 28 01:21:34.189:    : dns len=20, id=36929, aa=0, tc=0, rd=1, ra=0
Jun 28 01:21:34.189:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:34.189:    : ancount=0, nscount=0, arcount=0
Jun 28 01:21:34.189: NAT: s=49.212.49.25, d=221.189.114.163->192.168.0.4 [235]
Jun 28 01:21:34.189: NAT: i: udp (192.168.0.4, 53) -> (49.212.49.25, 36960) [14138]    
Jun 28 01:21:34.189: NAT (UDP-DNS): Before Translation
Jun 28 01:21:34.189: NAT: Translation of UDP DNS src 192.168.0.4, dst 49.212.49.25
Jun 28 01:21:34.189: NAT: Dns type of Response
Jun 28 01:21:34.189:    : dns len=78, id=36929, aa=1, tc=0, rd=1, ra=0
Jun 28 01:21:34.189:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:34.189:    : ancount=1, nscount=1, arcount=1
Jun 28 01:21:34.189:      query name is ns.yuyarin.net, qtype=1, class=1
Jun 28 01:21:34.189: Answer section:
Jun 28 01:21:34.189:    Name='ns.yuyarin.net'
Jun 28 01:21:34.193:    RR type=1, class=1, ttl=300, data length=4
Jun 28 01:21:34.193:      IP=221.189.114.163
Jun 28 01:21:34.193: Authority section:
Jun 28 01:21:34.193:    Name='yuyarin.net'
Jun 28 01:21:34.193:    RR type=2, class=1, ttl=300, data length=2
Jun 28 01:21:34.193:      NS='ns.yuyarin.net'
Jun 28 01:21:34.193: Additional record section:
Jun 28 01:21:34.193:    Name='ns.yuyarin.net'
Jun 28 01:21:34.193:    RR type=28, class=1, ttl=300, data length=16
Jun 28 01:21:34.193:      IPv6=0x75F627E
Jun 28 01:21:34.193: NAT (UDP-DNS): After Translation
Jun 28 01:21:34.193: NAT: Translation of UDP DNS src 192.168.0.4, dst 49.212.49.25
Jun 28 01:21:34.193: NAT: Dns type of Response
Jun 28 01:21:34.193:    : dns len=78, id=36929, aa=1, tc=0, rd=1, ra=0
Jun 28 01:21:34.193:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:34.193:    : ancount=1, nscount=1, arcount=1
Jun 28 01:21:34.193:      query name is ns.yuyarin.net, qtype=1, class=1
Jun 28 01:21:34.193: Answer section:
Jun 28 01:21:34.193:    Name='ns.yuyarin.net'
Jun 28 01:21:34.193:    RR type=1, class=1, ttl=300, data length=4
Jun 28 01:21:34.193:      IP=221.189.114.163
Jun 28 01:21:34.193: Authority section:
Jun 28 01:21:34.193:    Name='yuyarin.net'
Jun 28 01:21:34.193:    RR type=2, class=1, ttl=300, data length=2
Jun 28 01:21:34.193:      NS='ns.yuyarin.net'
Jun 28 01:21:34.193: Additional record section:
Jun 28 01:21:34.193:    Name='ns.yuyarin.net'
Jun 28 01:21:34.193:    RR type=28, class=1, ttl=300, data length=16
Jun 28 01:21:34.193:      IPv6=0x75F627E
Jun 28 01:21:34.193: NAT: s=192.168.0.4->221.189.114.163, d=49.212.49.25 [14138]

// failed
Jun 28 01:21:38.594: NAT: o: udp (49.212.49.25, 57410) -> (221.189.114.163, 53) [247]    
Jun 28 01:21:38.594: NAT (UDP-DNS): Before Translation
Jun 28 01:21:38.594: NAT: Translation of UDP DNS src 49.212.49.25, dst 221.189.114.163
Jun 28 01:21:38.594: NAT: Dns type of Query
Jun 28 01:21:38.594:    : dns len=21, id=38605, aa=0, tc=0, rd=1, ra=0
Jun 28 01:21:38.594:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:38.594:    : ancount=0, nscount=0, arcount=0
Jun 28 01:21:38.594: NAT (UDP-DNS): After Translation
Jun 28 01:21:38.594: NAT: Translation of UDP DNS src 49.212.49.25, dst 221.189.114.163
Jun 28 01:21:38.594: NAT: Dns type of Query
Jun 28 01:21:38.594:    : dns len=21, id=38605, aa=0, tc=0, rd=1, ra=0
Jun 28 01:21:38.594:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:38.594:    : ancount=0, nscount=0, arcount=0
Jun 28 01:21:38.594: NAT: s=49.212.49.25, d=221.189.114.163->192.168.0.4 [247]
Jun 28 01:21:38.594: NAT: i: udp (192.168.0.4, 53) -> (49.212.49.25, 57410) [30793]    
Jun 28 01:21:38.594: NAT (UDP-DNS): Before Translation
Jun 28 01:21:38.598: NAT: Translation of UDP DNS src 192.168.0.4, dst 49.212.49.25
Jun 28 01:21:38.598: NAT: Dns type of Response
Jun 28 01:21:38.598:    : dns len=98, id=38605, aa=1, tc=0, rd=1, ra=0
Jun 28 01:21:38.598:    : opcode=0, rcode=0, qdcount=1
Jun 28 01:21:38.598:    : ancount=1, nscount=1, arcount=2
Jun 28 01:21:38.598:      query name is ns2.yuyarin.net, qtype=1, class=1
Jun 28 01:21:38.598: Answer section:
Jun 28 01:21:38.598:    Name='ns2.yuyarin.net'
Jun 28 01:21:38.598:    RR type=1, class=1, ttl=300, data length=4
Jun 28 01:21:38.598:      IP=49.212.49.25
Jun 28 01:21:38.598: Authority section:
Jun 28 01:21:38.598:    Name='yuyarin.net'
Jun 28 01:21:38.598:    RR type=2, class=1, ttl=300, data length=5
Jun 28 01:21:38.598:      NS='ns.yuyarin.net'
Jun 28 01:21:38.598: Additional record section:
Jun 28 01:21:38.598:    Name='ns.yuyarin.net'
Jun 28 01:21:38.598:    RR type=1, class=1, ttl=300, data length=4
Jun 28 01:21:38.598:      IP=221.189.114.163
Jun 28 01:21:38.598:    Name='ns.yuyarin.net'
Jun 28 01:21:38.598:    RR type=28, class=1, ttl=300, data length=16
Jun 28 01:21:38.598:      IPv6=0x7924E72
Jun 28 01:21:38.598:  mapping pointer available mapping:0
Jun 28 01:21:38.598: NAT: translation failed (A), dropping packet s=192.168.0.4 d=49.212.49.25
c1812j#show ip nat translations
Pro Inside global         Inside local          Outside local         Outside global
udp 221.189.114.163:53    192.168.0.4:53        49.212.49.25:39068    49.212.49.25:39068 (ns
udp 221.189.114.163:53    192.168.0.4:53        49.212.49.25:52767    49.212.49.25:52767 (ns2

解決策

no-payload optionでペイロード書き換えを行わないようにする.interfaceを指定する記述では no-payloadは使えないのでglobalアドレスを直書きする.

Before
ip nat inside source static udp 192.168.0.4 53 interface Dialer2 53
ip nat inside source static tcp 192.168.0.4 53 interface Dialer2 53
after
ip nat inside source static tcp 192.168.0.4 53 221.189.114.163 53 extendable no-payload
ip nat inside source static udp 192.168.0.4 53 221.189.114.163 53 extendable no-payload