EdgeRouter Site Build Standard (IPsec IKEv2 + BGP to Cato)
Overview
| Item | Value |
|---|---|
| Applies to | Ubiquiti EdgeRouter sites (EdgeOS 3.0.1): Gembrook, Cockatoo, Gembrook West, Mater Christi (Emerald deferred) |
| Design | Route-based IPsec IKEv2 VTIs to Cato Melbourne (primary) and Sydney (secondary) PoPs, eBGP to Cato ASN 64515 |
| Status | Settled 26 Oct 2026 — fleet standard, proven at four sites |
| Owner | Mitch Fraser |
This page is the build standard for connecting an EdgeRouter site to Cato. It records the settled design, the one-time strongSwan change the EdgeRouters need, the EdgeOS configuration template, the two-WAN-path variant, verification and recovery, and — because it cost a site outage — what not to do. Per-site values live on the site pages in this book.
Fleet standard (summary)
Cato side (site IPsec page)
- Site type IPsec IKEv2. Connection type Responder Only (the ER initiates). Destination type IPv4 (Melbourne 113.30.140.95 primary, Sydney 202.75.244.10 secondary).
- Authentication identifier = the Cato-generated FQDN shown on the site's IPsec page,
<catoSiteId>.23991.catonetworks.com, on both tunnel rows. For a two-path site the WAN2 row uses<catoSiteId>.23991.2.catonetworks.com. (IPv4 = site WAN IP also works and is mandatory if Bidirectional is ever used.) - Init message parameters set explicitly: AES-CBC-256 / SHA-256 / PRF SHA-256 / DH14. Auth parameters AES-CBC-256 / SHA-256 / DH14. (Only matter for Bidirectional, harmless otherwise. "Automatic" makes the ER answer NO_PROPOSAL_CHOSEN.)
- Private IPs per the schema (site even / Cato odd). One BGP neighbour per tunnel: Cato ASN 64515, Peer ASN 6500<site>, Hold 90 / Keepalive 30, Advertise All routes.
- Last-mile bandwidth set to the real plan speeds; a fresh PSK per tunnel. Never paste a PSK into chat or a ticket — treat it as burned and regenerate.
EdgeOS side
- One-time drop-in
/etc/strongswan.d/zz-pbr-cato.confwithcharon { ignore_acquire_ts = yes }(see root cause). Survives reboot, not firmware upgrade. - Standard route-based VTI peers keyed by PoP IP,
connection-type initiate,authentication id @<fqdn>(the@forces an FQDN identity),remote-id <PoP IP>,ikev2-reauth no. - VTIs vti<site>00 / vti<site>01, /31 addresses, MTU 1400, OSPF passive, MSS clamp 1350 on vti.
- BGP: export only the site's own prefixes (secondary prepends ASN twice), import allowlist 10.41.0.0/16 le 24 + 10.254.254.0/24 le 32 with local-pref 200 (primary) / 100 (secondary), administrative distance 115, keepalive 30 / hold 90, soft-reconfiguration inbound.
Root cause: why ER-initiated tunnels would not re-establish on their own (proven 26 Oct 2026)
Symptom: a manual ipsec up always worked, but after any drop (or reboot) the tunnels never came back by themselves, with Cato in Responder Only mode. Cato logged nothing useful; the ER log showed Cato replying N(TS_UNACCEPT) to IKE_AUTH.
- EdgeOS writes VTI peers to strongSwan as
auto=route(a trap policy). Every automatic attempt is therefore acquire-triggered — by the BGP SYN or the UDP 10001 discovery broadcast heading into the VTI. - strongSwan prepends the triggering packet's selector to the traffic selectors of an acquire-triggered initiation, after the log line "proposing traffic selectors" (so the log misleadingly shows only 0.0.0.0/0). On the wire the automatic IKE_AUTH was 416 bytes versus 384 for a manual one: two extra 16-byte selectors, e.g. [10.254.6.60/32 tcp, 0.0.0.0/0] ⇔ [10.254.6.61/32 tcp/179, 0.0.0.0/0]. This is the documented
charon.ignore_acquire_tsbehaviour (default no; pfSense ships it as yes). - Cato's responder does not narrow per RFC 7296 §2.9 — it rejects any proposal carrying multiple traffic selectors. Cato KB "IPsec Tunnel Fails to Establish with TS_UNACCEPTABLE When Meraki VPN Health Check Is Enabled" states Cato "rejects the SA with a TS_UNACCEPTABLE notification when it receives multiple Traffic Selectors" and that Support can "apply a backend configuration". Cato's best practice note recommends "Initiate connection by Cato" for IKEv2 sites for this reason.
- Why the PA-440s never hit this: PAN-OS proposes only its configured proxy-ID (0/0 ⇔ 0/0).
- Eliminated by test: stale Cato state, simultaneous dual-PoP negotiation, crypto/DH choice, firewall/NAT, BGP configuration. The Cato per-site option "IKEv2 Send Single TS per payload" was tested and does not help — it governs how Cato encodes its own Network Ranges, not what it accepts.
- Fix: the
ignore_acquire_ts = yesdrop-in makes every ER attempt look exactly like a manualipsec up. Proven at Gembrook 16:26: afteripsec down, the ER's own trap-triggered attempt sent a single-selector IKE_AUTH and established in about 1 second with Cato unable to initiate; both BGP neighbours returned unattended.
Alternative that also works: Bidirectional (fallback only)
Cato site Bidirectional, destination/identifier = the site WAN IPv4 on both rows, Init parameters explicit; ER peers connection-type respond with authentication id <WAN IP>. Cato then initiates every 60 s while down. EdgeOS still writes auto=route so the ER keeps trying in the background (harmless). Not the standard because Cato cannot initiate through NAT — which rules it out for every PTP/fibre path that NATs through a hub PA-440. Cockatoo was first built this way and has since been moved to the standard.
DO NOT DO: policy-based IPsec on an EdgeRouter (site outage, 26 Oct 2026 ~14:30)
The Cato AI assistant suggested removing vti bind and adding tunnel 1 local prefix 10.6.0.0/16 remote prefix 0.0.0.0/0 on both Cato peers ("Cato requires policy-based"). Committing it took Gembrook offline: the kernel IPsec policy diverted all traffic from 10.6.0.0/16 into the Cato tunnel — overriding routing, including inter-site traffic to the hub — and removed the VTIs the BGP sessions ran over. Recovered by rebooting onto the saved config.boot. Cato's own IKEv2 site documentation supports route-based 0/0 tunnels; policy-based is the Meraki-specific KB workaround and does not even fix the multi-TS issue. Never apply policy-based tunnels on any ER site.
Build recipe (single-WAN site)
- Audit the device:
show version,show interfaces,show ip route,show ip ospf neighbor,show configuration commands | grep -E 'firewall|nat|vpn|ospf'. Note the WAN IP, LAN prefixes, loopback, hub VTIs, and that the WAN-local firewall already accepts IKE 500/4500 and ESP from any peer (all PBR ERs do, for the hub tunnels). - Create the Cato site (IPsec IKEv2, Responder Only, FQDN identifiers, IPv4 PoP destinations, explicit parameters, private IPs per schema, BGP neighbours, real bandwidth) and generate PSKs.
- Apply the strongSwan drop-in (below). Hub tunnels bounce for about 2 seconds on
ipsec restart. - Apply the EdgeOS template with the site values. Set the VTI /31 addresses and commit before adding the BGP neighbours (the validator rejects a neighbour that is not inside a configured VTI subnet; a /30 typo will do the same).
commit-confirm 10, verify,confirm,save.- Run the unattended re-establish proof (below). Only after that is the site "done".
EdgeOS template
Replace <S> with the site number, <SITE> with the site name, <catoSiteId> from the Cato page, and the WAN / loopback / legacy-range values from the audit. Quote PSKs.
# ---- One-time, outside EdgeOS config (survives reboot, NOT firmware upgrade) ----
sudo tee /etc/strongswan.d/zz-pbr-cato.conf >/dev/null <<'EOF'
# PBR: suppress acquire-derived traffic selectors so trap-triggered IKEv2
# initiations propose only the configured 0.0.0.0/0 (Cato rejects multi-TS).
# Not preserved by EdgeOS firmware upgrade - re-apply after upgrading.
charon {
ignore_acquire_ts = yes
}
EOF
sudo ipsec restart # hub tunnels bounce ~2 s
# ---- EdgeOS configuration (replace <...> values; PSKs in single quotes) ----
configure
# IKE / ESP groups
set vpn ipsec ike-group IKE-CATO key-exchange ikev2
set vpn ipsec ike-group IKE-CATO ikev2-reauth no
set vpn ipsec ike-group IKE-CATO lifetime 19800
set vpn ipsec ike-group IKE-CATO proposal 1 dh-group 14
set vpn ipsec ike-group IKE-CATO proposal 1 encryption aes256
set vpn ipsec ike-group IKE-CATO proposal 1 hash sha256
set vpn ipsec ike-group IKE-CATO dead-peer-detection action restart
set vpn ipsec ike-group IKE-CATO dead-peer-detection interval 30
set vpn ipsec ike-group IKE-CATO dead-peer-detection timeout 30
set vpn ipsec esp-group ESP-CATO lifetime 3600
set vpn ipsec esp-group ESP-CATO mode tunnel
set vpn ipsec esp-group ESP-CATO pfs dh-group14
set vpn ipsec esp-group ESP-CATO proposal 1 encryption aes256
set vpn ipsec esp-group ESP-CATO proposal 1 hash sha256
# VTIs (site side even, Cato side odd; MUST be /31)
set interfaces vti vti<S>00 address 10.254.<S>.<S>0/31
set interfaces vti vti<S>00 description 'Cato Melbourne (primary)'
set interfaces vti vti<S>00 mtu 1400
set interfaces vti vti<S>01 address 10.254.<S>.<S>2/31
set interfaces vti vti<S>01 description 'Cato Sydney (secondary)'
set interfaces vti vti<S>01 mtu 1400
set protocols ospf passive-interface vti<S>00
set protocols ospf passive-interface vti<S>01
set firewall options mss-clamp interface-type vti
set firewall options mss-clamp mss 1350
# Peers (route-based VTI, ER initiates, FQDN identifier)
set vpn ipsec site-to-site peer 113.30.140.95 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 113.30.140.95 authentication pre-shared-secret '<PSK-PRIMARY>'
set vpn ipsec site-to-site peer 113.30.140.95 authentication id @<catoSiteId>.23991.catonetworks.com
set vpn ipsec site-to-site peer 113.30.140.95 authentication remote-id 113.30.140.95
set vpn ipsec site-to-site peer 113.30.140.95 connection-type initiate
set vpn ipsec site-to-site peer 113.30.140.95 description 'Cato Melbourne PoP'
set vpn ipsec site-to-site peer 113.30.140.95 ike-group IKE-CATO
set vpn ipsec site-to-site peer 113.30.140.95 local-address <WAN-IP-PRIMARY-PATH>
set vpn ipsec site-to-site peer 113.30.140.95 vti bind vti<S>00
set vpn ipsec site-to-site peer 113.30.140.95 vti esp-group ESP-CATO
set vpn ipsec site-to-site peer 202.75.244.10 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 202.75.244.10 authentication pre-shared-secret '<PSK-SECONDARY>'
set vpn ipsec site-to-site peer 202.75.244.10 authentication id @<catoSiteId>.23991.catonetworks.com
set vpn ipsec site-to-site peer 202.75.244.10 authentication remote-id 202.75.244.10
set vpn ipsec site-to-site peer 202.75.244.10 connection-type initiate
set vpn ipsec site-to-site peer 202.75.244.10 description 'Cato Sydney PoP'
set vpn ipsec site-to-site peer 202.75.244.10 ike-group IKE-CATO
set vpn ipsec site-to-site peer 202.75.244.10 local-address <WAN-IP-SECONDARY-PATH>
set vpn ipsec site-to-site peer 202.75.244.10 vti bind vti<S>01
set vpn ipsec site-to-site peer 202.75.244.10 vti esp-group ESP-CATO
# Routing policy
set policy prefix-list <SITE>-PREFIXES rule 10 action permit
set policy prefix-list <SITE>-PREFIXES rule 10 prefix 10.<S>.0.0/16
set policy prefix-list <SITE>-PREFIXES rule 10 le 24
set policy prefix-list <SITE>-PREFIXES rule 20 action permit
set policy prefix-list <SITE>-PREFIXES rule 20 prefix <legacy-range>/24
set policy prefix-list <SITE>-PREFIXES rule 90 action permit
set policy prefix-list <SITE>-PREFIXES rule 90 prefix <loopback>/32
set policy prefix-list CATO-ALLOWED-IN rule 10 action permit
set policy prefix-list CATO-ALLOWED-IN rule 10 prefix 10.41.0.0/16
set policy prefix-list CATO-ALLOWED-IN rule 10 le 24
set policy prefix-list CATO-ALLOWED-IN rule 20 action permit
set policy prefix-list CATO-ALLOWED-IN rule 20 prefix 10.254.254.0/24
set policy prefix-list CATO-ALLOWED-IN rule 20 le 32
set policy route-map CATO-CONNECTED rule 10 action permit
set policy route-map CATO-CONNECTED rule 10 match ip address prefix-list <SITE>-PREFIXES
set policy route-map CATO-OUT-PRI rule 10 action permit
set policy route-map CATO-OUT-PRI rule 10 match ip address prefix-list <SITE>-PREFIXES
set policy route-map CATO-OUT-SEC rule 10 action permit
set policy route-map CATO-OUT-SEC rule 10 match ip address prefix-list <SITE>-PREFIXES
set policy route-map CATO-OUT-SEC rule 10 set as-path-prepend '6500<S> 6500<S>'
set policy route-map CATO-IN-PRI rule 10 action permit
set policy route-map CATO-IN-PRI rule 10 match ip address prefix-list CATO-ALLOWED-IN
set policy route-map CATO-IN-PRI rule 10 set local-preference 200
set policy route-map CATO-IN-SEC rule 10 action permit
set policy route-map CATO-IN-SEC rule 10 match ip address prefix-list CATO-ALLOWED-IN
set policy route-map CATO-IN-SEC rule 10 set local-preference 100
# BGP
set protocols bgp 6500<S> parameters router-id <loopback>
set protocols bgp 6500<S> parameters distance prefix 0.0.0.0/0 distance 115
set protocols bgp 6500<S> redistribute connected route-map CATO-CONNECTED
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 remote-as 64515
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 description 'Cato Melbourne'
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 timers holdtime 90
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 timers keepalive 30
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 soft-reconfiguration inbound
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 route-map import CATO-IN-PRI
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>1 route-map export CATO-OUT-PRI
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 remote-as 64515
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 description 'Cato Sydney'
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 timers holdtime 90
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 timers keepalive 30
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 soft-reconfiguration inbound
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 route-map import CATO-IN-SEC
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 route-map export CATO-OUT-SEC
commit-confirm 10
# ... verify tunnels and BGP, then:
confirm
save
Verification
export VYATTA_PAGER=cat
show vpn ipsec status
show vpn ipsec sa # NOT 'show vpn ipsec state' - that prints live ESP keys
sudo ipsec statusall | grep -E 'peer-(113|202)'
show vpn log | grep -E 'peer-(113|202)' | grep -E 'initiating|IKE_AUTH response|CHILD_SA .* established|TS_UNACCEPT|AUTH_FAILED|NO_PROPOSAL'
show ip bgp summary
show ip bgp neighbors 10.254.<S>.<S>1 advertised-routes # must be ONLY this site's prefixes
show ip bgp neighbors 10.254.<S>.<S>1 received-routes # ~127 offered
show ip route bgp # must be ONLY 10.41.0.0/16 + 10.254.254.x at [115/...]
show ip route | grep -E '10\.(1|3|4|5|6|7|8|9|10|11|12)\.' # inter-site routes must still be OSPF [110/...] via hub VTIs
sudo ping -c 3 10.254.<S>.<S>1
Unattended re-establish proof
# Prove the ER re-establishes on its own (Cato is Responder Only, so it cannot help):
sudo ipsec down peer-113.30.140.95-tunnel-vti
# wait up to ~3 minutes, then:
show vpn log | grep peer-113.30.140.95 | grep -E 'initiating IKE_SA|sending packet.*4500|IKE_AUTH response|CHILD_SA .* established'
# Expect: 'initiating IKE_SA' (not 'typed'), IKE_AUTH request 384 bytes (FQDN id) or 352 (IPv4 id),
# response '[ IDr AUTH SA TSi TSr ]' and 'CHILD_SA ... established'. 416 bytes + N(TS_UNACCEPT) = drop-in missing.
show ip bgp summary
Two-WAN-path sites (one path per Cato HA role)
Sites with a PTP/fibre path through a hub plus an LTE path (Gembrook West, Mater Christi) use two tunnels, one per path: primary role = PTP/fibre path → Melbourne PoP, secondary role = LTE path → Sydney PoP. Both are in BGP; the primary carries local-pref 200 and no prepend, the secondary local-pref 100 with the ASN prepended twice, and Cato itself double-prepends secondary-role routes and only uses the secondary role when every primary-role tunnel is down. This is exactly the shape Cato's own HA guides use for third-party routers (FortiGate, Cisco IOS, VMware Edge).
Why not four tunnels (both PoPs over both paths) like the KL1 PA-440: EdgeOS keys site-to-site peer by address and has a single routing table, so two tunnels to the same PoP IP from two paths would need hostname-keyed peers (EdgeOS refuses them for VTIs: "an ip address must be specified for VTIs") plus a persistent ip rule post-config script. The only clean alternative is a distinct PoP address per path, and the account's three IPsec IP licences are all allocated. Rejected as too complex; revisit only if licences change.
Extra configuration for a two-path site:
- Per-path host routes so each tunnel leaves by the right interface:
set protocols static route 113.30.140.95/32 next-hop <PTP next hop>andset protocols static route 202.75.244.10/32 next-hop <LTE gateway>. - Peer
local-address= the address on that path (the PTP side uses the private transit address; the hub PA-440 NATs it, so the tunnel runs NAT-T on UDP 4500 — the hub's NAT and security policy must permit 500/4500 from the transit subnet). - The LTE-local firewall ruleset on these sites is per-source, so add accept rules for the Sydney PoP (IKE 500/4500 and ESP). The PTP path enters an interface with no local ruleset.
- Cato page: WAN2 row identifier
<catoSiteId>.23991.2.catonetworks.com; last-mile for the PTP row is its share of the hub's link. - Do not export the transit /24 (e.g. 10.250.97.0/24, 192.168.127.0/24).
Operations
BGP neighbour reset (EdgeOS 3.0.1 has no working clear/reset command)
configure
set protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 shutdown
commit
delete protocols bgp 6500<S> neighbor 10.254.<S>.<S>3 shutdown
commit
exit
Recovery after a bad commit
# From a hub-side box (or via the site loopback 10.100.x.1 / hub VTI address if LAN replies are being swallowed):
ssh <ER>
configure
load # reloads the saved config.boot
commit
exit
# or, if the device is unreachable, power-cycle: it boots from config.boot (the last 'save').
EdgeOS 3.0.1 gotchas
- Any
set vpn ipseccommit — including logging changes — restarts charon: all tunnels on the box (hub ones included) bounce for about 2 seconds. Do IPsec commits in a quiet window. sudo ipsec stroke loglevel net 1/enc 1give live detail but are lost on every charon restart.set vpn ipsec loggingis persistent but noisy — remove it after the build.show vpn ipsec stateprints live ESP keys. Useshow vpn ipsec sa. If keys were ever displayed or pasted, force a rekey.- VTI addresses must be /31. A /30 makes the BGP validator reject the neighbour.
parameters distance global ...is not accepted; useparameters distance prefix 0.0.0.0/0 distance 115. It applies to routes installed after the commit — reset the neighbour if the routes were already there.- Site-to-site peers are keyed by IP; hostname peers are refused for VTIs.
- config.boot is in braces format —
grepit by value, not by set-path. Commit "connecting to charon.ctl failed" on a logging change is the charon restart race and is harmless. - Use
grep -Erather thanmatch '\|';sudo ping -c 3rather thanping count;export VYATTA_PAGER=catto stop the pager swallowing output. - If a bad firewall or IPsec policy swallows LAN replies, the device is usually still reachable on its loopback 10.100.x.1 or a hub VTI address.
Post-firmware-upgrade runbook
- Confirm
/etc/strongswan.d/zz-pbr-cato.confstill exists; if not, re-create it andsudo ipsec restart. - Run the unattended re-establish proof. A 416-byte IKE_AUTH followed by TS_UNACCEPT means the drop-in is missing.
Reference: Cato PoPs and schema
| Item | Value |
|---|---|
| Melbourne PoP (primary) | 113.30.140.95 |
| Sydney PoP (secondary) | 202.75.244.10 |
| Cato ASN | 64515 |
| Site ASN | 6500<site> |
| VTIs | vti<site>00 (primary), vti<site>01 (secondary) |
| /31s | 10.254.<site>.<site>0/31 and .<site>2/31; site even, Cato odd |
| Identifier | <catoSiteId>.23991.catonetworks.com (WAN2: .23991.2.) |
| Import allowlist | 10.41.0.0/16 le 24; 10.254.254.0/24 le 32 |
| Known Cato site IDs | Gembrook 1000000006, Cockatoo 1000000007, Gembrook West 1000000008, Mater Christi 1000000009 |
Maintenance notes
Update this page if Cato support applies the backend multi-TS setting (the drop-in then becomes unnecessary but harmless), if PoP addresses or IP licences change, or after an EdgeOS firmware upgrade changes strongSwan behaviour. Keep the post-upgrade runbook in the fleet upgrade procedure.