ISR800/900シリーズのEoSアナウンスにともない、IOS XEルータでの NAT on a stick (ヘアピン NATとも呼ばれます) の設定の問い合わせをいくつかいただくようになりました。下記サイトの情報を参考に IOS XEルータでのNAT on a stick の挙動を確認しましたのでその結果をまとめます。
結論、
- IOS XEルータでは loopbackインタフェースを nat インタフェースとして使用することが出来ません。
- VRF-Aware Software Infrastructure (VASI) および vrf の設定を利用することで、Classic IOSと同様のNAT on a stick (ヘアピン NAT)の設定を行うことが可能になります。
参考サイト
ネットワークチェンジニアとして
本記事ではトポロジ、IPアドレス等の情報はすべて、こちらの内容のものを引用させていただいております。深く感謝申し上げます。
概要 (参考サイトより)
“NAT on a stick”とは1つのI/Fでinside, outsideの両方の役割を果たすNATの設定方法の事です。”on a stick”という用語は、”1つの物理I/Fで何かタスクを実行する事”を指します。
一般的にNATを使用する場合は、insideとoutisdeは別のInterfaceになります。例えば、以下の構成が一例です。
+--------+
| R2 |
NAT outside+-+---+--+NAT inside
200.0.12.2/24│ │192.168.23.2/24
│ │
-----┬--------┴ ┴--------┬--------
│200.0.12.1/24 │192.168.23.3/24
+---+----+ +---+----+
| BB1 | | R3 |
+--------+ +--------+
“Nat on a stick”が有効であるのは、以下構成図のようにinsideとoutsideが共有せざるを得ない状況の場合です。”Nat on a stick”を使用する事によって、以下のような物理構成でもNATを実現し、Internetへのアクセスを提供する事ができます。
+--------+
| R2 |
+---+----+
│192.168.23.2/24 (primary)
│200.0.12.2/24 (secondary)
----┬----------┴----------┬--------
│200.0.12.1/24 │192.168.23.3/24
+---+----+ +---+----+
| BB1 | | R3 |
+--------+ +--------+
NAT on a stick 内部から外部へのアクセス
構成概要
上記の通り、IOS XEルータでは LoopbackインタフェースによるNATが動作しませんので、代替としてVASIおよびVRFを設定します。
動作確認を行う構成は以下の通りです。
vasileft1 10.2.2.2/24 (vrf red)
vasiright1 10.2.2.1/24
+--------+
| R2-vasi|
+---+----+
gi1│192.168.23.2/24 (primary)
│200.0.12.2/24 (secondary)
----┬----------┴------------┬--------
gi1│200.0.12.1/24 gi1│192.168.23.3/24
+---+----+ +---+----+
| BB1 | | R3 |
+--------+ +--------+
Lo0 200.1.1.1/24 Lo0 10.3.3.3/24
R2-vasiの設定で重要になる部分は下記になります
[R2-vasi]
vrf definition red
!
address-family ipv4
exit-address-family
!
interface GigabitEthernet1
ip address 200.0.12.2 255.255.255.0 secondary
ip address 192.168.23.2 255.255.255.0
ip nat inside
ip policy route-map RMAP_POLICE
!
interface vasileft1
vrf forwarding red
ip address 10.2.2.2 255.255.255.0
!
interface vasiright1
ip address 10.2.2.1 255.255.255.0
ip nat outside
!
ip route 200.0.2.0 255.255.255.0 GigabitEthernet1
!
ip route vrf red 0.0.0.0 0.0.0.0 10.2.2.1
!
ip nat pool NAT_POOL 200.0.2.100 200.0.2.199 prefix-length 24
ip nat inside source static 10.3.3.3 200.0.2.3
ip nat inside source list ACL_NAT_SOURCE pool NAT_POOL overload
!
ip access-list extended ACL_NAT_SOURCE
10 permit ip 192.168.0.0 0.0.255.255 any
20 permit ip 10.0.0.0 0.255.255.255 any
ip access-list extended ACL_POLICE
10 permit ip 192.168.0.0 0.0.255.255 any
20 permit ip 10.0.0.0 0.255.255.255 any
30 permit ip any 200.0.2.0 0.0.0.255
route-map RMAP_POLICE permit 10
match ip address ACL_POLICE
set ip next-hop 10.2.2.22 10.2.2.2
なお設定全文は下記ファイルです
BB1
Building configuration...
Current configuration : 3327 bytes
!
! Last configuration change at 08:55:14 UTC Thu Oct 16 2025
!
version 17.15
service timestamps debug datetime msec
service timestamps log datetime msec
platform qfp utilization monitor load 80
platform sslvpn use-pd
platform console serial
!
hostname BB1
!
boot-start-marker
boot-end-marker
!
!
no logging console
no aaa new-model
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
login on-success log
!
!
subscriber templating
!
!
!
crypto pki trustpoint SLA-TrustPoint
enrollment pkcs12
revocation-check crl
hash sha512
!
!
!
!
license udi pid C8000V sn 96TNB3G2XSV
memory free low-watermark processor 166409
diagnostic bootup level minimal
!
!
!
!
redundancy
!
!
!
!
!
!
!
!
!
!
interface Loopback0
ip address 200.1.1.1 255.255.255.0
!
interface GigabitEthernet1
ip address 200.0.12.1 255.255.255.0
negotiation auto
!
interface GigabitEthernet2
ip address dhcp
shutdown
negotiation auto
!
interface GigabitEthernet3
no ip address
shutdown
negotiation auto
!
interface GigabitEthernet4
no ip address
shutdown
negotiation auto
!
router bgp 100
bgp log-neighbor-changes
network 200.1.1.0
neighbor 200.0.12.2 remote-as 100
!
ip forward-protocol nd
!
no ip http server
ip http secure-server
ip ssh bulk-mode 131072
!
!
!
control-plane
!
!
line con 0
exec-timeout 0 0
stopbits 1
line aux 0
line vty 0 4
exec-timeout 0 0
login
transport input ssh
!
!
!
!
!
!
!
end
R2-vasi
Building configuration...
Current configuration : 6593 bytes
!
! Last configuration change at 08:55:18 UTC Thu Oct 16 2025
!
version 17.15
service timestamps debug datetime msec
service timestamps log datetime msec
platform qfp utilization monitor load 80
platform sslvpn use-pd
platform console serial
!
hostname R2-vasi
!
boot-start-marker
boot-end-marker
!
!
vrf definition red
!
address-family ipv4
exit-address-family
!
no logging console
no aaa new-model
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
login on-success log
!
!
subscriber templating
!
!
!
crypto pki trustpoint SLA-TrustPoint
enrollment pkcs12
revocation-check crl
hash sha512
!
crypto pki trustpoint TP-self-signed-2044398977
enrollment selfsigned
subject-name cn=IOS-Self-Signed-Certificate-2044398977
revocation-check none
rsakeypair TP-self-signed-2044398977
hash sha512
!
!
!
!
license udi pid C8000V sn 99T0KI7OKZR
memory free low-watermark processor 166409
diagnostic bootup level minimal
!
!
!
!
redundancy
!
!
!
!
!
!
!
!
!
!
interface GigabitEthernet1
ip address 200.0.12.2 255.255.255.0 secondary
ip address 192.168.23.2 255.255.255.0
ip nat inside
ip policy route-map RMAP_POLICE
negotiation auto
!
interface GigabitEthernet2
no ip address
shutdown
negotiation auto
!
interface GigabitEthernet3
no ip address
shutdown
negotiation auto
!
interface GigabitEthernet4
no ip address
shutdown
negotiation auto
!
interface vasileft1
vrf forwarding red
ip address 10.2.2.2 255.255.255.0
no keepalive
!
interface vasiright1
ip address 10.2.2.1 255.255.255.0
ip nat outside
no keepalive
!
router ospf 1
network 10.2.2.2 0.0.0.0 area 0
network 192.168.23.2 0.0.0.0 area 0
default-information originate always
!
router bgp 100
bgp log-neighbor-changes
network 200.0.2.0
neighbor 200.0.12.1 remote-as 100
!
ip forward-protocol nd
!
ip http server
ip http secure-server
ip route 200.0.2.0 255.255.255.0 GigabitEthernet1
ip route vrf red 0.0.0.0 0.0.0.0 10.2.2.1
ip nat pool NAT_POOL 200.0.2.100 200.0.2.199 prefix-length 24
ip nat inside source static 10.3.3.3 200.0.2.3
ip nat inside source list ACL_NAT_SOURCE pool NAT_POOL overload
ip ssh bulk-mode 131072
!
ip access-list extended ACL_NAT_SOURCE
10 permit ip 192.168.0.0 0.0.255.255 any
20 permit ip 10.0.0.0 0.255.255.255 any
ip access-list extended ACL_POLICE
10 permit ip 192.168.0.0 0.0.255.255 any
20 permit ip 10.0.0.0 0.255.255.255 any
30 permit ip any 200.0.2.0 0.0.0.255
route-map RMAP_POLICE permit 10
match ip address ACL_POLICE
set ip next-hop 10.2.2.22 10.2.2.2
!
!
!
control-plane
!
!
line con 0
exec-timeout 0 0
stopbits 1
line aux 0
line vty 0 4
exec-timeout 0 0
login
transport input ssh
!
!
!
!
!
!
!
end
R3
Building configuration...
Current configuration : 3314 bytes
!
! Last configuration change at 08:55:16 UTC Thu Oct 16 2025
!
version 17.15
service timestamps debug datetime msec
service timestamps log datetime msec
platform qfp utilization monitor load 80
platform sslvpn use-pd
platform console serial
!
hostname R3
!
boot-start-marker
boot-end-marker
!
!
no logging console
no aaa new-model
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
login on-success log
!
!
subscriber templating
!
!
!
crypto pki trustpoint SLA-TrustPoint
enrollment pkcs12
revocation-check crl
hash sha512
!
!
!
!
license udi pid C8000V sn 9FILV9YHV8N
memory free low-watermark processor 166409
diagnostic bootup level minimal
!
!
!
!
redundancy
!
!
!
!
!
!
!
!
!
!
interface Loopback0
ip address 10.3.3.3 255.255.255.0
!
interface GigabitEthernet1
ip address 192.168.23.3 255.255.255.0
negotiation auto
!
interface GigabitEthernet2
no ip address
shutdown
negotiation auto
!
interface GigabitEthernet3
no ip address
shutdown
negotiation auto
!
interface GigabitEthernet4
no ip address
shutdown
negotiation auto
!
router ospf 1
network 10.3.3.3 0.0.0.0 area 0
network 192.168.23.3 0.0.0.0 area 0
!
ip forward-protocol nd
!
no ip http server
ip http secure-server
ip ssh bulk-mode 131072
!
!
!
control-plane
!
!
line con 0
exec-timeout 0 0
stopbits 1
line aux 0
line vty 0 4
exec-timeout 0 0
login
transport input ssh
!
!
!
!
!
!
!
end
設定説明
NATを行うI/Fを以下のように定義します。この時、物理I/Fをinsideとし、vasiright1をoutsideとしています。
[R2-vasi]
interface GigabitEthernet1
ip address 200.0.12.2 255.255.255.0 secondary
ip address 192.168.23.2 255.255.255.0
ip nat inside
ip policy route-map RMAP_POLICE
interface vasiright1
ip address 10.2.2.1 255.255.255.0
ip nat outside
以下のようにNAT変換ルールを定義します。かなりトリッキーな設定ですが、以下の例はinside globalアドレスとして200.0.2.0/24を使用します。inside globalアドレスはR2に存在しないアドレス空間を使用して下さい。(なぜならば、仮に200.0.1.0/24のように存在するアドレスがinside globalとして割り当てると、戻りのパケットが想定通りにNATされません。200.0.1.0/24をinside interfaceで受信してもNATの変換対象とはならないからです。実際に200.0.1.0/24をinside globalとして設定してパケットを観察すると、NATの挙動を納得できると思います。)
[R2-vasi]
ip nat pool NAT_POOL 200.0.2.100 200.0.2.199 prefix-length 24
ip nat inside source list ACL_NAT_SOURCE pool NAT_POOL overload
!
ip access-list extended ACL_NAT_SOURCE
permit ip 192.168.0.0 0.0.255.255 any
permit ip 10.0.0.0 0.255.255.255 any
inside globalアドレスがどのI/Fに接続されているかルータに教えるため、以下のようなstatic routeを定義します。
[R2-vasi]
ip route 200.0.2.0 255.255.255.0 GigabitEthernet1
外部から内部へ・内部から外部への両方の通信に対して、以下のようなpolicy routingを定義します。inside I/Fからoutside I/Fへ転送するように見せかける事で、NATの制御対象になるようにします。
[R2-vasi]
interface GigabitEthernet1
ip policy route-map RMAP_POLICE
route-map RMAP_POLICE permit 10
match ip address ACL_POLICE
set ip next-hop 10.2.2.22 10.2.2.2
ip access-list extended ACL_POLICE
10 permit ip 192.168.0.0 0.0.255.255 any
20 permit ip 10.0.0.0 0.255.255.255 any
30 permit ip any 200.0.2.0 0.0.0.255
VASI Left (VRF red) に飛ばしたトラフィックを戻すために、VRF red で以下の設定を行います
[R2-vasi]
vrf definition red
!
address-family ipv4
exit-address-family
interface vasileft1
vrf forwarding red
ip address 10.2.2.2 255.255.255.0
ip route vrf red 0.0.0.0 0.0.0.0 10.2.2.1
動作確認
R3からR1へのpingによる疎通確認を行います。
[R3]
R3#ping 200.1.1.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 200.1.1.1, timeout is 2 seconds:
!!!!!
この時のNAT tableは以下の通りです。
[R2-vasi]
R2-vasi#show ip nat translations
Pro Inside global Inside local Outside local Outside global
--- 200.0.2.3 10.3.3.3 --- ---
icmp 200.0.2.100:29 192.168.23.3:29 200.1.1.1:29 200.1.1.1:29
Total number of translations: 2
NAT on a stick 外部から内部へのアクセス
設定説明
外部から内部へのアクセスを提供するためにはstatic NATを定義します。以下は10.3.3.3(R3)のinside globalアドレスとして200.0.2.3を割り当てる例です。
[R2-vasi]
ip nat inside source static 10.3.3.3 200.0.2.3
動作確認
BB1からR3へ接続可能である事を確認します。
[BB1]
BB1#ping 200.0.2.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 200.0.2.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/3 ms
CMLラボファイル
本検証は Cisco CML 2.9 を利用して確認しました。
CMLでのラボのXMLファイルはこちらです。
謝辞
本件の執筆にあたっては、「ネットワークチェンジニアとして」さんの以下の記事を参考に、トポロジ、IPアドレス等を基本的に踏襲して編集しました。あらためて感謝申し上げます。
https://changineer.info/network/cisco_ios/cisco_ios_ipservice/cisco_ios_ipservice_nat_on_a_stick.html

