IKEv2 Road Warrior — NAT Workaround
IKEv2 Road Warrior — NAT Workaround
Section titled “IKEv2 Road Warrior — NAT Workaround”Overview
Section titled “Overview”When multiple IKEv2 road-warrior clients connect from behind the same NAT device
(corporate firewall, shared home router, mobile carrier NAT), they all appear to
the RouterOS server as originating from a single public IP address. The standard
generate-policy=yes setting keys dynamic IPsec policies on the remote IP alone,
so the second client’s policy collides with and replaces the first client’s SA —
the first client is silently disconnected.
Root cause: IKEv2 road-warrior policy collision when multiple clients share a public IP.
Solution: generate-policy=port-strict keys each dynamic policy on both the
remote IP and its UDP source port (the NAT-T port on UDP/4500). Because each
NATed client gets a distinct port mapping, policies no longer collide.
Additional problem: send-initial-contact=yes (the default) causes a reconnecting
client to send a delete-notification that instructs the responder to clear all
existing SAs for that identity — knocking out other clients sharing the same
pre-shared key. Setting send-initial-contact=no disables this behaviour.
This topology is supported on RouterOS 6.45 and later. RouterOS 7.x is recommended for full IKEv2 mode-config stability.
How it Works
Section titled “How it Works”Client A (NAT 203.0.113.1:4501) ──┐ ├── RouterOS server 203.0.113.50Client B (NAT 203.0.113.1:4502) ──┘ port-strict: A policy ≠ B policyNAT-T wraps ESP in UDP/4500. The server tracks each client by
(remote-ip, remote-port) rather than remote-ip alone.
Prerequisites
Section titled “Prerequisites”| Requirement | Notes |
|---|---|
| RouterOS 6.45+ (7.x recommended) | generate-policy=port-strict requires 6.45+ |
| Public IP on the server WAN interface | Clients connect to this IP |
| UDP 500 and UDP 4500 reachable on server | Must not be blocked upstream |
| IP pool for VPN clients | e.g. 10.10.10.0/24 not overlapping LAN |
| Pre-shared key or CA infrastructure | PSK shown here; see See Also for certificates |
WAN interface list | The masquerade rule uses out-interface-list=WAN; create it with /interface list add name=WAN and add your WAN interface: /interface list member add list=WAN interface=<your-wan> |
Configuration
Section titled “Configuration”1. IP Pool for VPN Clients
Section titled “1. IP Pool for VPN Clients”/ip pooladd name=ike2-rw-pool ranges=10.10.10.2-10.10.10.2542. IPsec Mode-Config (Address Assignment)
Section titled “2. IPsec Mode-Config (Address Assignment)”Mode-config pushes a virtual IP, DNS, and split routes to the client:
/ip ipsec mode-configadd name=ike2-rw-cfg \ address-pool=ike2-rw-pool \ address-prefix-length=32 \ split-include=192.168.88.0/24 \ system-dns=no \ static-dns=192.168.88.1split-include— routes pushed to the client (omit to route all traffic through the tunnel)address-prefix-length=32— client receives a /32 virtual IPstatic-dns— DNS server pushed to the client
3. IPsec Policy Group and Template
Section titled “3. IPsec Policy Group and Template”/ip ipsec policy groupadd name=ike2-rw-group
/ip ipsec policyadd group=ike2-rw-group \ template=yes \ src-address=0.0.0.0/0 \ dst-address=0.0.0.0/0 \ proposal=ike2-rw-proposal \ level=uniqueNote:
ike2-rw-proposalis created in Step 4. If running these commands interactively, create the proposal first (Step 4), then return to create the policy template, or run Steps 3–4 as a batch.
level=unique— requires a unique SA per source address; this is the documented setting for NAT / multiple clients behind the same public IP. Without it, two clients sharing a NAT IP may share an SA instead of getting independent ones.
The template policy is instantiated per-client when generate-policy=port-strict
creates dynamic entries.
4. IPsec Proposal
Section titled “4. IPsec Proposal”/ip ipsec proposaladd name=ike2-rw-proposal \ auth-algorithms=sha256 \ enc-algorithms=aes-256-cbc,aes-128-cbc \ pfs-group=modp2048 \ lifetime=1h5. IPsec Profile (Phase 1)
Section titled “5. IPsec Profile (Phase 1)”nat-traversal=yes is essential — it enables NAT detection and UDP/4500
encapsulation:
/ip ipsec profileadd name=ike2-rw-profile \ hash-algorithm=sha256 \ enc-algorithm=aes-256,aes-128 \ dh-group=modp2048 \ nat-traversal=yes \ dpd-interval=30s \ dpd-maximum-failures=56. IPsec Peer
Section titled “6. IPsec Peer”/ip ipsec peeradd name=ike2-rw-peer \ address=0.0.0.0/0 \ exchange-mode=ike2 \ profile=ike2-rw-profile \ passive=yes \ send-initial-contact=nopassive=yes — server waits for incoming connections; address=0.0.0.0/0 —
accepts from any source IP. send-initial-contact=no prevents a reconnecting
client from sending a delete-notification that would clear other clients’ SAs.
7. IPsec Identity — the Key Settings
Section titled “7. IPsec Identity — the Key Settings”/ip ipsec identityadd peer=ike2-rw-peer \ auth-method=pre-shared-key \ secret=ChangeThisToAStrongSecret \ generate-policy=port-strict \ mode-config=ike2-rw-cfg \ policy-template-group=ike2-rw-group| Parameter | Value | Why |
|---|---|---|
generate-policy=port-strict | port-strict | Policies keyed on IP + port — prevents collision |
mode-config | ike2-rw-cfg | Assigns virtual IP to each client |
policy-template-group | ike2-rw-group | Links dynamic policies to the template |
PSK identity limitation: With a shared PSK, all clients present the same identity to the server.
port-strictseparates their policies by port, but RouterOS cannot assign different mode-configs or ACLs to individual clients — every client gets the same pool and split routes. For per-user access control, use certificate or EAP authentication instead (see See Also).
8. Firewall Rules (Input Chain)
Section titled “8. Firewall Rules (Input Chain)”Place before any default-drop rule:
/ip firewall filteradd chain=input protocol=udp dst-port=500 action=accept \ comment="IKEv2 IKE"add chain=input protocol=udp dst-port=4500 action=accept \ comment="IKEv2 NAT-T"add chain=input protocol=ipsec-esp action=accept \ comment="IPsec ESP (non-NATed clients)"UDP 4500 carries NAT-T encapsulated ESP — this is the critical rule for NATed clients. UDP 500 handles the initial handshake before NAT is detected.
9. NAT Bypass Rule
Section titled “9. NAT Bypass Rule”Prevents the server’s masquerade rule from rewriting VPN-encrypted packets:
/ip firewall natadd chain=srcnat action=accept ipsec-policy=out,ipsec \ comment="IPsec bypass — must be before masquerade"Note:
place-before=0is only valid when at least one NAT rule already exists; on an empty table it raises an error. Add this rule first (or omitplace-before), then add the masquerade rule after it. Confirm ordering with/ip firewall nat print.
If VPN clients need internet access routed through the server, first ensure the
WAN interface list exists and includes your WAN interface, then add the
masquerade rule after the bypass:
/interface list add name=WAN/interface list member add list=WAN interface=ether1
/ip firewall natadd chain=srcnat src-address=10.10.10.0/24 \ out-interface-list=WAN action=masquerade \ comment="VPN client internet access"Replace ether1 with your actual WAN interface name.
Verification
Section titled “Verification”Check Active Peers
Section titled “Check Active Peers”/ip ipsec active-peers printMultiple clients behind the same NAT should show the same remote IP but different ports:
# STATE REMOTE-ADDRESS REMOTE-PORT ... 0 established 203.0.113.1 4501 1 established 203.0.113.1 4502Check Installed SAs
Section titled “Check Installed SAs”/ip ipsec installed-sa printEach client should have its own SA pair (enc + auth for each direction). The
src-address and dst-address fields in dynamic policies confirm port-strict
is working:
/ip ipsec policy print where dynamic=yesCheck Mode-Config Assignments
Section titled “Check Mode-Config Assignments”/ip ipsec mode-config printEach connected client appears with its assigned virtual IP under
remote-address.
Monitor Policy Hit Counters
Section titled “Monitor Policy Hit Counters”/ip ipsec policy print detailByte/packet counters on dynamic policies increment as traffic flows.
Trigger a Test Ping
Section titled “Trigger a Test Ping”From a connected client, ping the server LAN address or a host behind it:
ping 192.168.88.1If the ping succeeds, the tunnel is up and policy matching is working.
Troubleshooting
Section titled “Troubleshooting”Second client disconnects first client on connect
Section titled “Second client disconnects first client on connect”Cause: send-initial-contact=yes on the peer (default). The second
client sends a delete-SA notification for the shared identity.
Fix: Set send-initial-contact=no on the peer:
/ip ipsec peer set [find name=ike2-rw-peer] send-initial-contact=noClients connect but cannot reach LAN
Section titled “Clients connect but cannot reach LAN”Cause 1: No NAT bypass rule. The masquerade rule rewrites the source of returning traffic, breaking the IPsec policy check on the return path.
Fix: Confirm the bypass rule is present and placed before masquerade:
/ip firewall nat printCause 2: IPsec policy template dst-address does not include the LAN subnet.
Fix: Edit the template policy to match traffic destined for the LAN:
/ip ipsec policy set [find template=yes] dst-address=192.168.88.0/24NAT-T not activating (ESP blocked mid-path)
Section titled “NAT-T not activating (ESP blocked mid-path)”Symptom: active-peers print shows remote-port=500 or peers disappear
after Phase 1.
Cause: An ISP or intermediate NAT device blocks IP protocol 50 (raw ESP).
Fix: nat-traversal=yes in the profile is required. Verify it is active:
/ip ipsec profile print where name=ike2-rw-profileOnce NAT-T activates, all ESP is wrapped in UDP/4500. The established counter
in active-peers print detail should increment.
Dynamic policies not created
Section titled “Dynamic policies not created”Symptom: policy print dynamic shows no entries after client connects.
Cause: generate-policy is not port-strict or the identity is not matched.
Check:
/ip ipsec identity print detail/log print where topics~"ipsec"Ensure generate-policy=port-strict appears on the identity. IKEv2 debug logs
reveal whether Phase 2 negotiation reaches the policy-generation step.
Client roams (IP changes) and tunnel breaks
Section titled “Client roams (IP changes) and tunnel breaks”Cause: IKEv2 does not natively support MOBIKE on all RouterOS versions.
Workaround: Configure a short DPD interval so the server detects the dead peer quickly and clears the SA, allowing the client to reconnect:
/ip ipsec profile set ike2-rw-profile dpd-interval=30s dpd-maximum-failures=3FastTrack bypasses IPsec policy — tunnel up but traffic does not flow
Section titled “FastTrack bypasses IPsec policy — tunnel up but traffic does not flow”Symptom: VPN clients connect successfully (active-peers print shows
established), but traffic does not pass through the tunnel or arrives
unencrypted on the server.
Cause: RouterOS FastTrack (/ip firewall filter action=fasttrack-connection)
fast-forwards established connections at the hardware/driver level, bypassing the
IPsec policy lookup. Packets that should be encrypted are forwarded in the clear.
Fix: Add accept rules for IPsec-matched traffic before the FastTrack rule in the forward chain:
/ip firewall filteradd chain=forward action=accept ipsec-policy=in,ipsec place-before=0 \ comment="IPsec inbound — skip FastTrack"add chain=forward action=accept ipsec-policy=out,ipsec place-before=1 \ comment="IPsec outbound — skip FastTrack"Verify the rule order — the accept rules must appear before any
action=fasttrack-connection rule:
/ip firewall filter printLog IKEv2 Negotiation
Section titled “Log IKEv2 Negotiation”/system logging add topics=ipsec action=memory/log print where topics~"ipsec"Remove the log rule when done:
/system logging remove [find topics~"ipsec"]See Also
Section titled “See Also”- Multiple L2TP/IPsec Road Warriors Behind NAT — L2TP-based road warrior with tunnel-mode IPsec
- RouterOS Wiki: IPsec
- RouterOS Wiki: IKEv2 EAP — certificate/EAP authentication alternative to PSK