0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cisco IOS XE と Kea/Unbound で IPv6-mostly VLAN の NAT64/DNS64 を作ったときのメモ

0
Posted at

概要

VLAN 2069 を IPv6-mostly / NAT64 評価用セグメントとして作ったときの作業メモです。

構成としては、Catalyst 側で VLAN/SVI を作り、Kea で DHCPv4 option 108
IPv6-Only Preferred を返し、Unbound の DNS64 専用 instance で合成 AAAA を返し、
Cisco IOS XE ルータで Stateful NAT64 PAT を行います。

最終的に、IPv4 address を持たない Linux コンテナから以下が成功しました。

curl -6 -v https://www.yahoo.co.jp/
...
Connected to www.yahoo.co.jp (2001:db8:24:4ff:64:0:...) port 443
< HTTP/2 200

この記事では、成功構成だけでなく、途中ではまった点も残します。

前提

今回の評価 VLAN は以下です。

VLAN: 2069
IPv4 gateway: 192.168.69.1/24
IPv6 gateway: 2001:DB8:24:409::1/64
DNS64 prefix: 2001:DB8:24:4FF:64::/96

DNS64 listener は通常 resolver と分離しました。

dns1 DNS64: 2001:DB8:24:404::64:16
dns2 DNS64: 2001:DB8:24:404::64:17

NAT64/PLAT は cr1 の Cisco IOS XE ルータで実施します。

全体像

役割は以下です。

client on VLAN2069
  |
  | IPv6 only / IPv6-mostly
  v
sw1 Vlan2069
  - 192.168.69.1/24
  - 2001:DB8:24:409::1/64
  - RA RDNSS: DNS64 listener
  - DHCPv4 relay to Kea
  |
  v
dns1/dns2
  - Kea DHCPv4 option 108
  - Unbound DNS64 dedicated instance
  |
  v
cr1
  - Stateful NAT64 PAT

Step 1: VLAN/SVI

sw1Vlan2069 を作りました。

ポイントは、完全な IPv6-only ではなく、DHCPv4 option 108 を評価するために
IPv4 gateway も持たせることです。DHCPv4 relay では SVI の IPv4 address が
giaddr になるためです。

設定イメージ:

interface Vlan2069
 description ### NAT64 / CLAT evaluation ###
 ip address 192.168.69.1 255.255.255.0
 ip helper-address 192.168.64.16
 ip helper-address 192.168.64.17
 ipv6 address 2001:DB8:24:409::1/64
 ipv6 enable
 ipv6 nd ra dns server 2001:DB8:24:404::64:16
 ipv6 nd ra dns server 2001:DB8:24:404::64:17
 ip router isis IOSLAB
 ipv6 router isis IOSLAB
 isis circuit-type level-2-only

SVI は L2 側に VLAN 2069 の up/up port がないと line protocol down になるので、
access port または trunk allowed VLAN の確認も gate にしました。

Step 2: Kea DHCPv4 option 108

Kea には 192.168.69.0/24 を追加しましたが、原則として IPv4 pool は持たせません。

狙いは RFC 8925 の IPv6-Only Preferred option を返し、対応端末には IPv4 を
持たせないことです。

Kea の設定イメージ:

- id: 13
  subnet: 192.168.69.0/24
  valid-lifetime: 1800
  option-data:
    - name: routers
      data: 192.168.69.1
    - name: domain-name-servers
      data: 192.168.64.16, 192.168.64.17
    - name: domain-name
      data: example.com
    - name: v6-only-preferred
      data: 1800

はまった点として、Kea では option 108 は標準 option として扱われます。
そのため、custom option-def として再定義すると target Kea で拒否されます。

つまり、v6-only-preferred は option-data に書くだけでよく、独自 option-def は
追加しません。

Step 3: DNS64 専用 Unbound

既存 resolver に DNS64 を直接有効化すると、既存セグメントにも DNS64 が効く可能性が
あります。そのため、DNS64 用の Unbound を別 instance として起動しました。

dns1 の例:

server:
  interface: 2001:DB8:24:404::64:16
  port: 53
  pidfile: "/var/run/unbound-dns64.pid"
  directory: "/var/unbound-dns64"

  access-control: 2001:DB8:24:409::/64 allow
  access-control: 0.0.0.0/0 refuse
  access-control: ::0/0 refuse

  module-config: "dns64 validator iterator"
  dns64-prefix: 2001:db8:24:4ff:64::/96

最初、DNS64 専用 listener を loopback に bind する案も考えましたが、既存 Unbound と
衝突するためやめました。DNS64 instance は専用 IPv6 address のみに bind します。

FreeBSD 側では、DNS64 用 address を追加で持たせました。

dns1: 2001:db8:24:404::64:16/128
dns2: 2001:db8:24:404::64:17/128

確認:

dig @2001:db8:24:404::64:16 -t AAAA ipv4only.arpa

ipv4only.arpa. 600 IN AAAA 2001:db8:24:4ff:64:0:c000:aa
ipv4only.arpa. 600 IN AAAA 2001:db8:24:4ff:64:0:c000:ab

この時点で DNS64 は OK です。

Step 4: cr1 Stateful NAT64

最終的に必要だった基本構成はこれです。

ipv6 access-list ACL_NAT64_VLAN2069_V6
 permit ipv6 2001:DB8:24:409::/64 any

nat64 prefix stateful 2001:DB8:24:4FF:64::/96
nat64 v4 pool NAT64_POOL_VLAN2069 203.0.113.174 203.0.113.174
nat64 v6v4 list ACL_NAT64_VLAN2069_V6 pool NAT64_POOL_VLAN2069 overload

NAT64 を通す WAN/LAN interface には nat64 enable を入れました。

interface TenGigabitEthernet0/0/8
 nat64 enable

interface TenGigabitEthernet0/0/9
 nat64 enable

環境によって必要 interface は異なりますが、少なくとも入口側の inside/transit
interface で NAT64 drop が増えるかを見るのが重要でした。

はまった点 1: Well-Known Prefix は Stateful NAT64 prefix に使えない

最初は DNS64 の慣例で 64:ff9b::/96 を使おうとしました。

nat64 prefix stateful 64:FF9B::/96

しかし IOS XE では以下で拒否されました。

%NAT64: Cannot use the well-known prefix 64:FF9B::/96 for a stateful prefix

そのため、Network-Specific Prefix として以下を使いました。

2001:DB8:24:4FF:64::/96

DNS64 の dns64-prefix と cr1 の nat64 prefix stateful は必ず一致させます。

はまった点 2: nat64 route 0.0.0.0/0 は不要だった

途中で nat64 route が必要だと思い、以下を試しました。

nat64 route 0.0.0.0/0 TenGigabitEthernet0/0/9

しかし、NAT64 pool と route が重なるため、IOS XE が拒否しました。

%NAT64-3-EINVAL: The range 203.0.113.174-203.0.113.174 cannot overlap with the NAT64 route 0.0.0.0/0

結論として、今回の Stateful NAT64 PAT では nat64 route は不要でした。

show nat64 routes が空でも、通常の IPv4 routing table に従って NAT64 後の IPv4
packet が転送されます。

確認時の状態:

show nat64 routes

IPv4 Prefix        Adj. Address    Enabled  VRF      Output IF
   Global IPv6 Prefix

それでも curl は成功し、translation も作成されました。

Total active translations: 6
Sessions created: 7
Packets translated (IPv6 -> IPv4) Stateful: 176
Packets translated (IPv4 -> IPv6) Stateful: 320

はまった点 3: NAT64 pool に使える public IPv4

最も時間がかかったのは NAT64 pool address です。

203.0.113.169 は不可

.169 は既存の Loopback1 / Tunnel0 / NAT44 PAT で使っていました。

そのため NAT64 pool にすると即座に拒否されます。

%NAT64-3-EINVAL: The range 203.0.113.169-203.0.113.169 cannot contain an interface address
(found overlap with address on interface Loopback1)

IOS XE の Stateful NAT64 pool には、ルータ自身の interface address は使えません。

203.0.113.168 は設定できるが動かない

.168 は設定としては入りました。

nat64 v4 pool NAT64_POOL_VLAN2069 203.0.113.168 203.0.113.168

しかし curl は失敗し、translation は作られませんでした。

Total active translations: 0
Sessions created: 0

QFP 側では以下が増えました。

NAT64_DROP_SC_ADDR_PORT_FAIL
NAT64_DROP_SC_ADDR_NOT_AVAIL

つまり、設定はできても dataplane では変換元 address として使えませんでした。

203.0.113.175 も設定できるが動かない

cr1 上で 203.0.113.168/29 として interface 設定しているわけではありません。
また、ISP 側はこの public block 内の先頭/末尾相当の address も /32 として通せる
ことを過去に確認していました。

そのため、.175 も NAT64 pool として試しました。

nat64 v4 pool NAT64_POOL_VLAN2069 203.0.113.175 203.0.113.175

これも設定としては入りましたが、実通信は失敗しました。

curl: (7) Failed to connect to www.yahoo.co.jp port 443

cr1 側では translation は作られず、QFP drop は .168 と同じ傾向でした。

Total active translations: 0
NAT64_DROP_SC_ADDR_PORT_FAIL
NAT64_DROP_SC_ADDR_NOT_AVAIL

203.0.113.174 は動いた

既存 static NAT で使っていた .174 を一時的に外し、NAT64 pool にすると成功しました。

no ip nat inside source static 172.24.101.50 203.0.113.174
no ip route 203.0.113.174 255.255.255.255 Null0 name SDWAN_VSMART_NAT_ALIAS

nat64 v4 pool NAT64_POOL_VLAN2069 203.0.113.174 203.0.113.174
nat64 v6v4 list ACL_NAT64_VLAN2069_V6 pool NAT64_POOL_VLAN2069 overload

成功時の translation:

tcp 198.51.100.124:443
    [2001:db8:24:4ff:64:0:c633:647c]:443
    203.0.113.174:36178
    [2001:db8:24:409:be24:11ff:fe67:88f3]:36178

この結果から、少なくとも今回の cr1 / IOS XE Stateful NAT64 では .168.175
NAT64 pool として使えず、.174 は使えました。

当初は /29 の network/broadcast 相当 address だから使えないのではないか、と
疑いました。しかし、この環境では ISP 側が public block 内の先頭/末尾相当 address も
/32 として通せることを過去に確認しています。そのため、.168 / .175 の失敗を
単純に ISP 側の /29 制約とは説明できません。

追加で cr1 を確認したところ、interface address や route として
203.0.113.168/29 は存在しませんでした。

show ip route 203.0.113.168 255.255.255.248
% Subnet not in table

show ip route 203.0.113.168
% Subnet not in table

show ip route 203.0.113.175
% Subnet not in table

一方で、hairpin / ZBFW 用の ACL には public block 全体を表す
203.0.113.168 0.0.0.7 が使われていました。

ip access-list extended NAT_HAIRPIN_PUBLIC_V4
 20 permit ip 192.168.0.0 0.0.255.255 203.0.113.168 0.0.0.7
 30 permit ip 172.16.0.0 0.15.255.255 203.0.113.168 0.0.0.7
 40 permit ip 10.0.0.0 0.255.255.255 203.0.113.168 0.0.0.7
 100 permit ip any 203.0.113.168 0.0.0.7

route-map NAT_HAIRPIN_TO_VASI permit 10
 match ip address NAT_HAIRPIN_PUBLIC_V4
 set ip next-hop 10.255.255.2

この ACL が NAT64 pool address の失敗に直接関係しているかは、今回の確認だけでは
断定できません。確実に言えるのは、IOS XE の NAT64 dataplane が .168 / .175
address/port を割り当てられず、.174 では割り当てられた、という点までです。

検証コマンド

クライアント側:

ip addr
ip route
ip -6 route
cat /etc/resolv.conf
dig -t AAAA ipv4only.arpa
dig -t AAAA www.yahoo.co.jp
curl -6 -v https://www.yahoo.co.jp/

IPv4 を持っていないこと:

inet6 2001:db8:24:409:be24:11ff:fe67:88f3/64 scope global dynamic

DNS64 合成:

www.yahoo.co.jp.  CNAME edge12.g.yimg.jp.
edge12.g.yimg.jp. AAAA 2001:db8:24:4ff:64:0:...

cr1 側:

show nat64 statistics
show nat64 translations
show nat64 pool
show nat64 aliases
show platform hardware qfp active feature nat64 datapath statistics
show logging | include NAT64|nat64|EINVAL

特に見るべきところ:

Total active translations
Sessions created
Packets translated (IPv6 -> IPv4) Stateful
Packets translated (IPv4 -> IPv6) Stateful
NAT64_DROP_SC_ADDR_PORT_FAIL
NAT64_DROP_SC_ADDR_NOT_AVAIL

最終的な理解

今回の IOS XE Stateful NAT64 PAT では、以下が重要でした。

  • Stateful NAT64 prefix に 64:ff9b::/96 は使えない。
  • DNS64 と NAT64 の prefix は一致させる。
  • nat64 route 0.0.0.0/0 は不要。
  • show nat64 routes が空でも Stateful NAT64 PAT は動作する。
  • NAT64 pool は interface address と重複できない。
  • 設定として入る IPv4 address でも、dataplane で ADDR_NOT_AVAIL になり得る。
  • .168 / .175 は設定できたが実通信不可。
  • .174 は既存 static NAT を一時的に外すと NAT64 pool として動作した。
  • .168 / .175 の失敗理由は /29 の network/broadcast とは断定しない。
  • cr1 の interface/route に 203.0.113.168/29 は見えなかった。
  • ただし hairpin / ZBFW ACL では 203.0.113.168 0.0.0.7 として public block
    全体を扱っていた。

まとめ

DNS64 までは比較的素直でしたが、IOS XE の Stateful NAT64 は pool address の扱いで
かなりはまりました。

今回一番大きな学びは、nat64 route ではなく、まず Stateful NAT64 PAT の基本構成を
素直に入れること、そして pool address が dataplane で本当に使えるかを
show nat64 translations と QFP drop counter で見ることです。

curl の失敗だけを見ると経路問題に見えますが、実際には NAT64 pool address の
割り当て失敗でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?