Back to blog

Cisco / IOS  ·  Tutorial  ·  July 2026

Cisco IOS
Site-to-Site IPsec VPN

Two offices, one encrypted tunnel over the public internet — as if they shared a switch. We build it the modern way: an IKEv2 route-based tunnel (VTI) you can route over and monitor like any interface, not a legacy crypto-map you can't. With the NAT-exemption trap that breaks every first attempt.

Cisco IOS IPsec IKEv2 VPN VTI Site-to-Site CCNP

HQ · R1 10.1.0.0/16 Branch · R2 10.2.0.0/16 Internet (untrusted) Tunnel0 · IKEv2 + ESP-AES-256 · 169.254.0.0/30 Real traffic between 10.1.x and 10.2.x rides the encrypted tunnel — routed, not crypto-ACL'd.

A site-to-site VPN makes two branch LANs behave like one network across the open internet, with everything between the routers encrypted. IPsec does the crypto in two phases: IKE (we'll use the modern IKEv2) authenticates the peers and negotiates keys, then ESP encrypts the actual data. The old way to steer traffic into it was a crypto map with a "which traffic to encrypt" ACL bolted to the WAN interface — rigid, hard to route over, and painful to troubleshoot.

The modern way, and what this post builds, is a route-based VPN using a Virtual Tunnel Interface (VTI). The tunnel becomes a real Tunnel0 interface: you point a route at it, or even run OSPF over it, and anything the routing table sends that way is encrypted automatically. It behaves like the interface it is — you can see it in show ip interface brief, monitor it, and route dynamically. This is how site-to-site VPNs should be built on any modern IOS. The one thing that breaks every first attempt — NAT eating your VPN traffic — gets its own section.

Prerequisites

01

Phase 1 — The IKEv2 Handshake

First the two routers must agree how to protect the negotiation itself and prove who they are. Proposal (algorithms), policy, keyring (the shared secret), and a profile that ties peer identity to that key.

IOS (R1 · HQ) — IKEv2 proposal, policy, keyring, profile
# 1. What crypto do we offer to protect the IKE channel?
R1(config)# crypto ikev2 proposal PROP-1
R1(config-ikev2-proposal)# encryption aes-cbc-256
R1(config-ikev2-proposal)# integrity sha256
R1(config-ikev2-proposal)# group 14          # DH group 14 (2048-bit)
R1(config-ikev2-proposal)# exit
R1(config)# crypto ikev2 policy POL-1
R1(config-ikev2-policy)# proposal PROP-1
R1(config-ikev2-policy)# exit

# 2. The pre-shared key, tied to the PEER's public IP
R1(config)# crypto ikev2 keyring KR-1
R1(config-ikev2-keyring)# peer BRANCH
R1(config-ikev2-keyring-peer)# address 198.51.100.2
R1(config-ikev2-keyring-peer)# pre-shared-key S3cr3t-VPN-Key!
R1(config-ikev2-keyring-peer)# exit

# 3. The profile: match the peer, authenticate both ways with the keyring
R1(config)# crypto ikev2 profile IKEV2-PROF
R1(config-ikev2-profile)# match identity remote address 198.51.100.2 255.255.255.255
R1(config-ikev2-profile)# authentication local pre-share
R1(config-ikev2-profile)# authentication remote pre-share
R1(config-ikev2-profile)# keyring local KR-1
R1(config-ikev2-profile)# exit
⚠ Gotcha — Both Sides Must Agree, Exactly

IPsec is unforgiving of asymmetry. The proposal (encryption, integrity, DH group), the pre-shared key, and the identity addresses must match on both routers — mirror-imaged for the peer address, identical for the crypto. One mismatched parameter and Phase 1 never completes; show crypto ikev2 sa shows no SA and the logs report a proposal or authentication failure. When a tunnel won't come up, diff the two configs line by line before anything else — it's almost always a one-character key typo or a group/hash mismatch.

02

Phase 2 — The ESP Data Encryption

Now define how the actual data is encrypted (the transform set) and wrap it, plus the IKEv2 profile, into an IPsec profile that the tunnel interface will reference.

IOS (R1) — transform set + IPsec profile
# How the DATA is protected — AES-256 + SHA-256 HMAC, tunnel mode
R1(config)# crypto ipsec transform-set TS-1 esp-aes 256 esp-sha256-hmac
R1(cfg-crypto-trans)# mode tunnel
R1(cfg-crypto-trans)# exit

# Bundle transform set + IKEv2 profile into an IPsec profile.
# This is what the Tunnel interface will "protect" itself with.
R1(config)# crypto ipsec profile IPSEC-PROF
R1(ipsec-profile)# set transform-set TS-1
R1(ipsec-profile)# set ikev2-profile IKEV2-PROF
R1(ipsec-profile)# exit

03

The Tunnel Interface (VTI)

Here's where route-based beats crypto-map. The tunnel becomes a real interface with its own IP, a source and destination, and IPsec protection attached. Route traffic to it and it's encrypted — no crypto ACL.

IOS (R1) — the VTI, then route the remote LAN over it
R1(config)# interface Tunnel0
R1(config-if)# ip address 169.254.0.1 255.255.255.252   # tiny tunnel /30
R1(config-if)# tunnel source GigabitEthernet0/0        # our WAN interface
R1(config-if)# tunnel destination 198.51.100.2         # peer's public IP
R1(config-if)# tunnel mode ipsec ipv4
R1(config-if)# tunnel protection ipsec profile IPSEC-PROF
R1(config-if)# exit

# Steer the REMOTE LAN across the tunnel (static, or run OSPF over Tunnel0)
R1(config)# ip route 10.2.0.0 255.255.0.0 Tunnel0
R1(config)# end

# R2 is the mirror image: tunnel dest 203.0.113.1, ip 169.254.0.2,
# route 10.1.0.0/16 to Tunnel0, same crypto and matching key.
💡 Pro Tip — Route Over the Tunnel Like Any Link

Because Tunnel0 is a real interface, you're not limited to static routes. Run OSPF over it and the two sites exchange routes dynamically — add a third subnet at either end and it's reachable with zero VPN changes. You can also point an IP SLA probe down the tunnel and fail a backup tunnel over on loss, exactly like dual-WAN. This composability is the whole reason route-based VPNs replaced crypto maps: the tunnel plays by the same rules as every other interface you already know.

04

The NAT-Exemption Trap

The number-one reason a freshly built tunnel "comes up but nothing passes." Your edge already PATs the LAN to the internet — and it happily NATs your VPN-bound traffic too, mangling it before it reaches the tunnel. You must exempt site-to-site traffic from NAT.

IOS (R1) — deny VPN traffic from the NAT ACL
# The existing PAT rule from the NAT post uses ACL 1 for "who gets NATed".
# We must make it NAT internet-bound traffic but NOT site-to-site traffic.

R1(config)# ip access-list extended NAT-LIST
# DENY (exempt) traffic to the remote site — this must come FIRST
R1(config-ext-nacl)# deny   ip 10.1.0.0 0.0.255.255 10.2.0.0 0.0.255.255
# PERMIT everything else to be NATed to the internet
R1(config-ext-nacl)# permit ip 10.1.0.0 0.0.255.255 any
R1(config-ext-nacl)# exit

R1(config)# ip nat inside source list NAT-LIST interface GigabitEthernet0/0 overload
# Now traffic to 10.2.x skips NAT (goes into the tunnel untouched);
# everything else still PATs out to the internet normally.
⚠ Gotcha — Order Matters, and Clear Old Translations

The deny (exempt) line must sit above the permit … any — first-match wins (the ACL rules apply here too). If the permit is first, VPN traffic gets NATed and vanishes into the tunnel mangled. And if the tunnel was already up and NATing before you fixed this, stale translations linger: run clear ip nat translation * after the change or you'll swear it still doesn't work. This one gotcha accounts for most "the tunnel is up but I can't ping across it" tickets.

05

Verify the Tunnel Safe to Run

IPsec has two SAs to confirm — Phase 1 (IKEv2) and Phase 2 (IPsec) — plus the interface and encrypting-packet counters. Check them in that order; the break is always at a specific layer.

IOS — the tunnel health walk
# 1. Phase 1 up? Look for READY.
R1# show crypto ikev2 sa
 Tunnel-id  Local            Remote           fvrf/ivrf  Status
 1          203.0.113.1/500  198.51.100.2/500 none/none  READY

# 2. Phase 2 up and actually encrypting? pkts encaps/decaps should climb.
R1# show crypto ipsec sa | include pkts|peer|ident
   local  ident (addr/mask): (10.1.0.0/255.255.0.0)
   remote ident (addr/mask): (10.2.0.0/255.255.0.0)
   #pkts encaps: 4021, #pkts decaps: 3998

# 3. Tunnel interface up/up?
R1# show ip interface brief | include Tunnel
Tunnel0   169.254.0.1   YES  manual  up   up

# 4. End-to-end, sourced from the LAN (not the router's WAN IP!)
R1# ping 10.2.0.1 source 10.1.0.1
SymptomWhere to look
No IKEv2 SA / not READYPhase 1 mismatch — proposal, key, or identity address. debug crypto ikev2.
IKEv2 READY but no IPsec SATransform-set mismatch, or Tunnel0 misconfigured.
SAs up, encaps climbs, decaps 0Return traffic issue — the FAR side isn't sending back (its route or NAT).
SAs up, no pkts at allNAT eating the traffic (section 04), or no route pointing at Tunnel0.

06

MikroTik ↔ Cisco — Same Tunnel, Different Menus

RouterOS IPsec has the same two-phase structure; the terminology lines up once you see the mapping.

MikroTik / RouterOSCisco IOS
/ip ipsec profile (phase 1)crypto ikev2 proposal + policy
/ip ipsec peer + identitycrypto ikev2 profile + keyring
/ip ipsec proposal (phase 2)crypto ipsec transform-set
/ip ipsec policy (or IPsec on the interface)crypto ipsec profile on Tunnel0 (VTI)
Src-NAT rule with accept above masqueradeNAT exemption: deny line above permit
/ip ipsec active-peersshow crypto ikev2 sa
💡 Legacy Note — Crypto Maps Still Exist

You'll meet older configs (and some peer devices, including certain firewalls) that only speak policy-based IPsec: a crypto map with a "match this traffic" ACL applied to the WAN interface, no tunnel interface. It works, but you can't route dynamically over it, monitoring is awkward, and troubleshooting is worse. When you inherit one, it's usually worth migrating to a VTI — unless the far end is a policy-based-only device, in which case you match its style. For anything greenfield and Cisco-to-Cisco, route-based VTI as shown here is the default.

Takeaways

  1. IPsec is two phases: IKEv2 authenticates the peers and keys the channel; ESP encrypts the data. Both sides must agree on the crypto exactly — one mismatched parameter and nothing comes up.
  2. Build route-based (VTI), not crypto-map. The tunnel becomes a real Tunnel0 interface you route over, monitor, and run OSPF across — no "interesting traffic" ACL.
  3. Four crypto objects, in order: IKEv2 proposal/policy → keyring (the PSK, tied to the peer IP) → IKEv2 profile → IPsec transform-set → IPsec profile → attach to the tunnel.
  4. Exempt VPN traffic from NAT. Your edge PAT will mangle site-to-site traffic unless a deny line — placed above the permit — excludes remote-LAN destinations. This breaks nearly every first attempt.
  5. Non-overlapping subnets are mandatory. Two sites both on 192.168.1.0/24 can't be bridged by a routed VPN. Plan the address space before the tunnel.
  6. Verify layer by layer: IKEv2 SA READY → IPsec SA with climbing encaps/decaps → Tunnel0 up/up → a LAN-sourced ping. The failure is always at one identifiable layer.
  7. It composes with the rest of the series. Route with OSPF, fail a backup tunnel over with IP SLA, filter it with a zone-pair — because a VTI is just another interface.

Linking two sites — office and warehouse, HQ and villa — in Crete?

NOCTIS builds encrypted site-to-site links on Cisco and MikroTik that route dynamically and fail over cleanly — no mangled NAT, no black-box crypto maps. Documented, monitored, and tested end to end.

Book a Discovery Call →