Runbook: Configure IPsec
1 · Prerequisites
Confirm every item is in place before any state change.
- IPsec concept — IKE, ESP, transport vs tunnel mode, the IPsec suite
- IKEv2 — Internet Key Exchange v2, RFC 7296, MOBIKE, EAP authentication
- ESP proposals — ciphers, integrity, DH/PFS groups, configuration
- Route-based VTI — Virtual Tunnel Interface, route-based IPsec, ip xfrm
- NAT-T — NAT traversal for IPsec, UDP 4500 encapsulation
- IPsec troubleshooting — IKE debug, ESP debug, MTU, PFS mismatch
- VPN MTU — tunnel MTU, MSS clamping, fragmentation
- commit-confirm — the rollback safety net for remote changes
2 · Pre-checks
Read-only diagnostic commands. If any of these don't match expected output, stop and investigate further.
- · The two ends have an AGREED parameter sheet before anyone touches a router: IKE version, encryption, hash, PRF, DH group and lifetime on the IKE side; encryption, hash, PFS, mode and lifetime on the ESP side; and the identities each end will present. The VyOS documentation lists exactly these as the values that must match, and both ends configuring independently from intent is how "no proposal chosen" happens.
- · Which end initiates is decided and written down. One peer gets
connection-type initiate, the otherconnection-type none. The VyOS documentation recommends that pairing explicitly, and warns thatinitiateon its own never restarts the connection after a disconnection — so the initiating end also needs dead-peer-detection orclose-action. - · Whether this router already terminates other IPsec peers is established with
show vpn ipsec connections. If it does, this is NOT an additive change — see the two global options below. - ·
set vpn ipsec interfaceis checked against the current configuration. When it is absent, IPsec policies apply to ALL interfaces; adding it for the first time RESTRICTS them to the interfaces you name, for every peer on the router and not just the new one. - ·
set vpn ipsec options disable-route-autoinstallis checked. For route-based (VTI) peers it is required, because a VTI negotiates 0.0.0.0/0 selectors and strongSwan would otherwise install a default route via the VTI peer address. Setting it on a router that already has policy-based peers relying on auto-installed routes will remove those routes. - · The path is confirmed open in both directions before any tunnel configuration exists: UDP 500 (IKE), UDP 4500 (NAT-T) and IP protocol 50 (ESP) between the two public addresses, in the firewall on BOTH ends and in anything between them.
- · Whether either end sits behind NAT is established. If so, ESP cannot traverse it and the tunnel depends on UDP 4500 encapsulation being permitted end to end. Where a middlebox blocks plain ESP without NAT being detected,
force-udp-encapsulationon the peer is the documented lever. - · The PSK or certificate material is handled as a credential: generated out of band, never pasted into a ticket, and understood to be readable by anyone who can read the running configuration, any configuration backup taken afterwards, or the operational command
show vpn ike secrets. - · The pre-change configuration is saved to a file you can load back:
save /config/pre-change-TICKET.conf, and out-of-band console access is confirmed by using it.
3 · Procedure
Execute each step in order. Verify the expected output of a step before moving to the next.
- 1Confirm the path first, before configuring anything: from each end, prove UDP 500 and UDP 4500 reach the other public address and that the firewall permits ESP. A blocked port here makes every later proposal question unanswerable.
- 2Capture the pre-change state:
show vpn ipsec connections,show vpn ike sa,show vpn ipsec sa,show system commit, thensave /config/pre-change-TICKET.conf. - 3Bind the daemon to the WAN interface if it is not already bound:
set vpn ipsec interface eth0. Treat this as narrowing IPsec policy installation for every peer on the router, not just the new one. - 4Define the IKE group from the agreed sheet:
key-exchange ikev2,proposal N encryption/hash/dh-group/prf,lifetime,close-action, anddead-peer-detection actionplusinterval. Note thatdead-peer-detection timeoutis IKEv1 only — on IKEv2 the retransmission schedule decides when a peer is declared down. - 5Define the ESP group from the agreed sheet:
proposal N encryption/hash,pfs,mode tunnel,lifetime. - 6Install the pre-shared key under
set vpn ipsec authentication psk NAME, with anidfor each end that matches the identity that end will actually present, and thesecret. - 7Define the peer:
authentication mode pre-shared-secret,local-idandremote-idmatching the psk ids,ike-group,default-esp-group,local-address,remote-address, and the agreedconnection-type. - 8For route-based: create the VTI with
set interfaces vti vti0 address, bind it withset vpn ipsec site-to-site peer PEER vti bind vti0, and setset vpn ipsec options disable-route-autoinstall. For policy-based instead:tunnel 0 local prefixandtunnel 0 remote prefix. - 9Set the tunnel MTU and MSS clamp on the VTI before you hand it to users:
set interfaces vti vti0 mtu 1400andset interfaces vti vti0 ip adjust-mss clamp-mss-to-pmtu. A VTI defaults to MTU 1500, which is the exact condition that produces a tunnel that pings and cannot carry a file. - 10Run
compare, read the diff against the agreed sheet, and apply withcommit-confirm 10rather than a bare commit. - 11Verify in order: IKE SA established, child SA present with bytes in BOTH directions, VTI up, route present via the VTI, then a large do-not-fragment ping across the tunnel.
- 12Only after all five verifications pass,
confirm, thensave, then add the static or dynamic routing that puts real traffic on the tunnel.
4 · Verification
Confirm the procedure actually fixed the problem.
- ✓
show vpn ike sashows the IKE SA up, and the NEGOTIATED values in its Encrypt, Hash and D-H Group columns are read from the output and compared against the agreed sheet — not assumed from what was typed. A tunnel can come up on a weaker proposal than intended. - ✓
show vpn ipsec sashows a child SA for the peer with non-zero counters in BOTH halves of its Bytes In/Out column. Bytes in one direction only means the return path is broken — routing or firewall on the far end — and the tunnel is not usable even though it reads as up. - ✓The child SA carries the name this deployment should produce:
PEER-vtifor a VTI binding,PEER-tunnel-Nfor each policy-based tunnel. A peer that shows atunnel-0child when you built a VTI means the wrong branch of step 4 was committed. - ✓
show vpn ipsec connectionsagrees with the configured peer and mode. For a VTI peer the Local TS and Remote TS columns read 0.0.0.0/0 (and ::/0) — that is correct and expected, not a misconfiguration. - ✓
show interfaces vti vti0shows the interface up with its configured address (route-based deployments only). - ✓The remote prefix appears in the routing table via the VTI or the expected next hop, and the route is the one the traffic will actually take.
- ✓A large do-not-fragment ping across the tunnel succeeds —
ping 10.100.100.2 size 1372 do-not-fragment count 3. A default-size ping proves only that the SA exists; the do-not-fragment ping is what proves the MTU and MSS work is correct. - ✓One real application flow is tested end to end, from a host behind one side to a host behind the other, not from router to router.
- ✓
show log ipseccontains no repeating negotiation errors after the tunnel settles. - ✓Existing tunnels on this router are re-checked with
show vpn ipsec connectionsand are still established — proof the global options did not disturb them.
5 · Rollback
If verification fails, undo the procedure in reverse order.
- ↶Not yet committed:
discard. Nothing has been applied and no daemon has been reloaded. - ↶Committed under
commit-confirm Nand the tunnel is wrong: do nothing and let the window expire. The router reverts on its own. This matters more than usual here because a bad IPsec commit can disturb tunnels other than the one you were building. - ↶Committed and confirmed:
load /config/pre-change-TICKET.confthencommit. This restores the whole IPsec subtree, including the two global options, in one step. - ↶To remove only the new peer, leaving everything else in place:
delete vpn ipsec site-to-site peer PEERand, for route-based,delete interfaces vti vti0, thencommit. - ↶Do NOT revert with
rollback N. The VyOS documentation states rollback applies the revision and triggers a system reboot; on a router terminating other tunnels that is an outage for all of them, not a revert of one. - ↶If
set vpn ipsec interfaceordisable-route-autoinstallwas added and other peers exist, the rollback must remove those too — they are the parts of this change that reach beyond the new tunnel. - ↶After any rollback, re-verify the OTHER tunnels, not just that the new one is gone. The pre-change capture of
show vpn ipsec connectionsis the comparison.
6 · Escalation
When the runbook isn't enough, contact:
- · Escalate to the peer-side owner as soon as the local evidence is complete and points outward: IKE reaching UDP 500 but no response, or a child SA with bytes leaving and none returning. Both are far-end conditions and no amount of local reconfiguration fixes them.
- · Escalate to network engineering if adding this peer requires changing
set vpn ipsec interfaceordisable-route-autoinstallon a router that already carries production tunnels — that is a change to the shared IPsec configuration and needs its own window and its own blast-radius review. - · Escalate to the security owner before deploying a proposal containing 3DES, DES, MD5, SHA-1, or DH group 1, 2 or 5, even when the far end demands it. Interoperating with weak crypto is a documented exception with an owner, not an operator decision made at 02:00 to make a tunnel come up.
- · Escalate immediately if a pre-shared key has been sent through a ticket, chat or email. Treat it as disclosed, rotate it, and record the disclosure — a PSK is a symmetric credential and copies of it do not expire.
- · Hold rather than proceed when the two ends have no agreed parameter sheet. Configuring from intent and negotiating by trial is how a window is spent producing "no proposal chosen" repeatedly. Record the hold with an owner and a date, and hand the window back.
An IPsec tunnel is not one thing that works or does not. It is five separate agreements plus a network path, and every one of them fails with the same sentence from the person who reported it: the tunnel is down.
- The path — UDP 500, UDP 4500 and IP protocol 50 reaching the far end.
- The IKE proposal — encryption, hash, PRF, DH group, IKE version.
- Authentication — the secret, and the identities it is filed under.
- The ESP proposal — encryption, hash, PFS, mode.
- The traffic selectors or VTI binding, and the routing that feeds them.
The whole procedure is ordered so each is proven separately, cheapest first. Confirming the path takes two minutes and invalidates half the possible causes; aligning proposals against a peer whose firewall was dropping UDP 500 the entire time takes an evening.
When this runbook applies
Use it to bring up a new site-to-site IPsec peer on a VyOS 1.5 router, or to rebuild one whose configuration has been removed.
Do not use it for:
- A tunnel that was working and has stopped. That is a diagnosis. The parameters have not changed, so re-entering them proves nothing; go to the IPsec troubleshooting runbook and find what did change.
- Remote-access (road-warrior) IPsec. Different subtree
(
vpn ipsec remote-access), different authentication model, an address pool and a client population to think about. - A crypto change on an existing tunnel. Rekeying a live peer to a new proposal is a coordinated two-ended change and drops traffic when the ends disagree even briefly.
Two things to confirm on your image before you paste anything
VyOS moves IPsec nodes between releases, and this course’s Part XLII lessons were written against an older generation. Two differences bite immediately.
| Subject | What 1.5 accepts | Why it matters |
|---|---|---|
| IKE version | ike-group NAME key-exchange ikev2 | With key-exchange unset, VyOS initiates IKEv2 but responds to either version — so an unset value is not the same as a chosen one |
| Pre-shared key | vpn ipsec authentication psk NAME id ... secret ... | The key is a separate node keyed by identity, not a value under the peer |
| ESP PFS | esp-group NAME pfs enable (or pfs dh-group14) | enable inherits the IKE group’s DH group; there is no dh-group node under an ESP proposal |
| Tunnel interface | interfaces vti vtiN | The interface name is constrained to vtiN; anything else is rejected at commit |
| Connection role | connection-type initiate on one end, none on the other | The third accepted value differs by release — confirm it with completion rather than copying it from anywhere, including here |
Confirm each node with command completion on your image before pasting. On a configuration-tree OS a wrong node name is a rejected commit, which is the cheap failure. A node that exists and means something slightly different is the expensive one.
Step 0: prove the path before you configure anything
monitor traffic interface eth0 filter 'udp port 500 or udp port 4500 or proto esp'Run this BEFORE any tunnel configuration exists, while the far end is asked
to initiate. monitor traffic is VyOS’s wrapper around tcpdump, so the
output is tcpdump’s; press Ctrl-C to stop it.
Three outcomes, three different next actions:
- Nothing at all, in either direction. Neither end is trying, or something upstream is dropping it. Check the local firewall permits the peer address on UDP 500/4500 and ESP, and ask the far end to confirm the same. Nothing else is worth doing yet.
- Outbound packets only. Your side is initiating and nothing is coming back. This is a far-end or path condition. Escalate outward with the capture rather than changing local proposals.
- Traffic both ways. The path is fine and the problem, when it comes, is a parameter problem. Proceed.
Step 1: the two global options that are not about your tunnel
Adding a peer looks additive. Two nodes in this procedure are not, and both are easy to type without noticing.
set vpn ipsec interface eth0
set vpn ipsec options disable-route-autoinstallset vpn ipsec interface restricts outbound IPsec policies to the
interfaces you name. The VyOS documentation is explicit about the default:
when no interface is specified, IPsec policies apply to all interfaces. So
this is not “switch IPsec on for eth0” — it is “switch IPsec off everywhere
except eth0”. On a router whose existing peers terminate on a second WAN, a
pppoe interface or a VRF-bound link, adding this line for your new peer is
what removes theirs.
disable-route-autoinstall stops strongSwan installing its own routes for
negotiated traffic selectors. Route-based (VTI) deployments require it, and
the reason is specific rather than general: a VTI negotiates its selectors as
0.0.0.0/0, and forwarding decisions are made on netfilter marks rather than
on those selectors. Left enabled, strongSwan reads 0.0.0.0/0 as “route
everything” and installs a default route via the VTI peer address. But it is
a global switch: on a router that already has policy-based peers quietly
depending on auto-installed routes to their remote prefixes, turning it on
removes their routing while leaving their tunnels up.
Step 2: proposals, from an agreed sheet
Both ends must offer at least one identical combination. The failure when
they do not is NO_PROPOSAL_CHOSEN in the log, and the notify itself does
not say which parameter disagrees — which is why the sheet is agreed before
the window rather than discovered during it.
configure
set vpn ipsec ike-group IKE-GROUP key-exchange 'ikev2'
set vpn ipsec ike-group IKE-GROUP lifetime '28800'
set vpn ipsec ike-group IKE-GROUP proposal 10 encryption 'aes256'
set vpn ipsec ike-group IKE-GROUP proposal 10 hash 'sha256'
set vpn ipsec ike-group IKE-GROUP proposal 10 prf 'prfsha256'
set vpn ipsec ike-group IKE-GROUP proposal 10 dh-group '14'
set vpn ipsec ike-group IKE-GROUP close-action 'start'
set vpn ipsec ike-group IKE-GROUP dead-peer-detection action 'restart'
set vpn ipsec ike-group IKE-GROUP dead-peer-detection interval '30'
set vpn ipsec esp-group ESP-GROUP mode 'tunnel'
set vpn ipsec esp-group ESP-GROUP lifetime '3600'
set vpn ipsec esp-group ESP-GROUP pfs 'enable'
set vpn ipsec esp-group ESP-GROUP proposal 10 encryption 'aes256'
set vpn ipsec esp-group ESP-GROUP proposal 10 hash 'sha256'prf is on the agreed-parameters list and is easy to leave out. It defaults
in a way that usually matches, and when it does not, the failure is an
ordinary proposal mismatch with one more column to compare.
pfs enable inherits the DH group from the IKE group rather than naming one.
That is convenient and it is also a trap on a two-vendor tunnel: the far end
almost certainly names a PFS group explicitly, and “inherit” only matches if
the IKE group you inherit from is the group they named. Where the sheet says
group 14, pfs dh-group14 says so in the configuration and survives someone
later editing the IKE group.
Step 3: authentication, and the identity trap
On 1.5 the pre-shared key does not live under the peer. It lives in its own node, filed under the identities the two ends present:
set vpn ipsec authentication psk PSK-SITE-B id '198.51.100.1'
set vpn ipsec authentication psk PSK-SITE-B id '203.0.113.1'
set vpn ipsec authentication psk PSK-SITE-B secret 'REPLACE-WITH-A-GENERATED-SECRET'
set vpn ipsec site-to-site peer PEER-SITE-B authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer PEER-SITE-B authentication local-id '198.51.100.1'
set vpn ipsec site-to-site peer PEER-SITE-B authentication remote-id '203.0.113.1'The id values on the psk node are how the daemon decides which secret
applies to an incoming negotiation — the VyOS documentation states plainly
that the peer selects its key according to the local-id / remote-id pair. If
those ids do not match the identities the two ends actually present, the
correct secret is never selected, and the log reads
tried 1 shared key ... but MAC mismatched followed by AUTHENTICATION_FAILED
— which is the same evidence you would get from two genuinely different keys.
Two ends with the same PSK typed correctly and mismatched ids fail exactly
like two ends with different PSKs.
Where the secret contains characters the CLI would rather not carry, VyOS
accepts a base64 form: encode it, then set both
secret 'BASE64VALUE' and secret-type base64 on the psk node. That is an
encoding, not protection.
Step 4: peer, VTI and MTU
set vpn ipsec site-to-site peer PEER-SITE-B ike-group 'IKE-GROUP'
set vpn ipsec site-to-site peer PEER-SITE-B default-esp-group 'ESP-GROUP'
set vpn ipsec site-to-site peer PEER-SITE-B local-address '198.51.100.1'
set vpn ipsec site-to-site peer PEER-SITE-B remote-address '203.0.113.1'
set vpn ipsec site-to-site peer PEER-SITE-B connection-type 'initiate'
set vpn ipsec site-to-site peer PEER-SITE-B vti bind 'vti0'
set interfaces vti vti0 address '10.100.100.1/30'
set interfaces vti vti0 description 'IPsec to Site B'
set interfaces vti vti0 mtu '1400'
set interfaces vti vti0 ip adjust-mss 'clamp-mss-to-pmtu'
set protocols static route 192.0.2.0/24 next-hop 10.100.100.2
compareconnection-type is a two-ended decision. One peer is initiate; the other
is none, meaning the connection is loaded and waits to be initiated from
the far side. That is the pairing the VyOS documentation recommends for
site-to-site, and it goes with the DPD and close-action split from step 2.
For a policy-based tunnel instead of a VTI, the VTI binding and the static route are replaced by traffic selectors on the peer:
set vpn ipsec site-to-site peer PEER-SITE-B tunnel 0 local prefix '198.51.100.0/24'
set vpn ipsec site-to-site peer PEER-SITE-B tunnel 0 remote prefix '192.0.2.0/24'
Route-based is the better default: adding a destination later is a route, not a renegotiation, and a routing protocol can run over the VTI. Choose policy-based when the far end can only do policy-based — and note that the VyOS documentation advises against running both styles to the same peer.
Step 5: apply with a timer, verify in order
commit-confirm 10
run show vpn ike sa
run show vpn ipsec sa
run show vpn ipsec connections
run show interfaces vti vti0
# only when every check below has passed:
confirm
saveVerify in this order, and stop at the first one that fails.
IKE SA up — and on the proposal you meant. show vpn ike sa prints the
negotiated values in columns: State, IKEVer, Encrypt, Hash, D-H Group,
NAT-T, and the two timers A-Time (how long it has been established) and
L-Time (how long until rekey). Read Encrypt, Hash and D-H Group out of the
output rather than assuming them. Two ends offering several proposals can
settle on the weakest one they share, and the tunnel comes up looking
healthy.
Child SA with bytes in both directions. This is the check that catches
the most and gets skipped the most. show vpn ipsec sa gives one row per
child SA with a Bytes In/Out and a Packets In/Out column. A child SA present
with bytes outbound and zero inbound is not a working tunnel — it means your
side is encrypting and sending and nothing is coming back. The cause is on
the far end or in the path, and it is invisible if you only look at whether
an SA exists.
The child SA has the name this build should produce.
show vpn ipsec sa
show vpn ipsec connectionsConnection State Uptime Bytes In/Out Packets In/Out Remote address
----------------- ------- ------- ------------- --------------- --------------
PEER-SITE-B-vti up 4m11s 18K/17K 142/139 203.0.113.1
Connection State Type Remote address Local TS Remote TS
----------------- ------- ------ --------------- ---------- ----------
PEER-SITE-B up IKEv2 203.0.113.1 - -
PEER-SITE-B-vti up IPsec 203.0.113.1 0.0.0.0/0 0.0.0.0/0Illustrative output
A VTI binding produces a child SA named PEER-vti. Each policy-based tunnel
produces PEER-tunnel-N. If you built a VTI and the table shows
PEER-SITE-B-tunnel-0, a tunnel 0 node survived from an earlier attempt
and the peer is running policy-based whatever the VTI configuration says.
The 0.0.0.0/0 in the Local TS and Remote TS columns is the VTI signature
from step 4, not a fault.
VTI up, route present, and the route is the one traffic will take.
show interfaces vti vti0 for the interface, show ip route 192.0.2.0/24
for the route.
A large do-not-fragment ping crosses. The check that proves step 4.
ping 10.100.100.2 size 1372 do-not-fragment count 3
ping 10.100.100.2 count 3size is the ICMP payload, not the packet: 1372 plus 20 bytes of IP header
and 8 of ICMP header is 1400, the VTI MTU set in step 4. Run the small case
afterwards so that a failure above means “too big” rather than “no path at
all”.
Finish by testing one real application flow from a host behind one side to a host behind the other. Router-to-router across the VTI proves the tunnel; only host-to-host proves the routing, the firewall and the MSS clamp together.
What each step costs if it is wrong
| Step | Cost of getting it wrong |
|---|---|
| Skipping the step-0 path check | An evening spent aligning proposals that were always compatible, against a firewall rule nobody looked at. |
set vpn ipsec interface on a shared router | Restricts IPsec policy installation to that interface for every existing peer, during a window booked for one new one. |
disable-route-autoinstall with policy-based peers present | Removes routing those peers depend on. The tunnels stay up; the traffic stops. |
Omitting disable-route-autoinstall on a VTI build | strongSwan installs a default route via the VTI peer address, from the tunnel’s own 0.0.0.0/0 selectors. |
Both ends connection-type initiate | Duplicate child SAs, periodic renegotiation, a tunnel that “flaps for no reason”. |
connection-type initiate with no DPD and no close-action | The tunnel comes up once and never comes back after the first drop. |
dead-peer-detection timeout in an IKEv2 group | A failover expectation sized from a value that is not in effect. |
| PSK id not matching the presented identity | Authentication failure that looks like a wrong secret, with the correct secret configured on both ends. |
| Leaving the VTI at its default MTU 1500 | Ping works, applications hang. Diagnosed as an application fault, often for days. |
| Reading VTI selectors as a fault | Time spent “fixing” 0.0.0.0/0, which is the correct value for a VTI. |
| Verifying on “SA exists” instead of bidirectional bytes | A one-way tunnel signed off as working. |
rollback N used as the undo | Reboot — and every other tunnel on the router goes with it. |
Escalation and the option to hold
Escalate outward as soon as local evidence points outward. A capture showing IKE leaving and nothing returning, or a child SA with bytes in one direction, is complete evidence of a far-end condition; continuing to change local parameters against it just adds variables to someone else’s problem.
Hold rather than proceed when there is no agreed parameter sheet. Two ends
configuring from intent and negotiating by trial will spend the window
producing NO_PROPOSAL_CHOSEN, and the result at the end of it is a tunnel
whose actual crypto nobody chose. Record the hold with an owner and a date.
References
- VyOS documentation — IPsec site-to-site VPN (peer tree, connection types, op-mode commands, worked route-based example)
- VyOS documentation — IPsec general information (ike-group, esp-group, log, options, IKEv2 retransmission)
- VyOS documentation — VTI interfaces, and why route autoinstall must be disabled
- VyOS documentation — troubleshooting site-to-site IPsec (op-mode output shapes and charon log lines)
- VyOS documentation — CLI, commit-confirm, compare, load and rollback
- RFC 7296 — Internet Key Exchange Protocol Version 2 (IKEv2)
- RFC 3948 — UDP Encapsulation of IPsec ESP Packets (NAT-T)