,

Site-to-Site IPSec: Juniper to Cisco Through MikroTik NAT

Key Takeaways

  • The crypto in the original build is obsolete — don’t copy it. 3DES and DH group 2 were reasonable in 2017 and are not acceptable now. Modern equivalents are given alongside each config below.
  • NAT is the whole problem. The SRX sits behind a MikroTik holding the only public IP, so IKE has to survive address translation. That means NAT-T on UDP 4500, and forwarding both 500 and 4500.
  • Use route-based VPN, not policy-based. A Cisco VTI talking to a Juniper st0 interface behaves like a normal routed link — you can run a routing protocol over it and troubleshoot it with show interface.
  • Clamp MSS or you’ll chase phantom faults. The tunnel comes up, ping works, and large transfers hang. 1360 on both ends fixes it.

This one came from a real requirement: the company ran Cisco in the data centre and Juniper in the branches, and we wanted a backup path for one branch that didn’t depend on the fixed line. The answer was LTE — a MikroTik wAP LTE kit with a public IP from the mobile carrier, with the SRX behind it.

That last detail is what makes this interesting. The SRX doesn’t hold the public address. The MikroTik does, and the SRX sits behind it on a private /30, so the IPSec negotiation has to cross a NAT boundary.

The topology

Site-to-site IPSec topology: Cisco ISR in the data centre with public IP 1.1.1.1, MikroTik wAP LTE with public IP 2.2.2.2 over the mobile network, and a Juniper SRX100 behind it on 172.16.1.2/30

  1. Cisco ISR in the DC, public IP 1.1.1.1
  2. MikroTik wAP LTE at the branch, public IP 2.2.2.2 on the LTE interface
  3. Juniper SRX100 behind the MikroTik on 172.16.1.2/30

The tunnel is built between 1.1.1.1 and 2.2.2.2. The SRX believes its peer is 1.1.1.1 and never sees its own public address — the MikroTik translates on the way through.

Read this before you copy the crypto

The configs below are the ones that ran in production in 2017. Two choices in them are no longer defensible:

  • 3DES. NIST’s SP 800-131A Rev. 2 disallowed three-key TDEA for encryption after 31 December 2023 — decryption of legacy data only. RFC 8247 demoted ENCR_3DES to MAY, noting every implementation already has AES.
  • DH group 2 (1024-bit MODP). RFC 8247 marks it SHOULD NOT, explicitly because it’s within reach of a well-funded attacker. Group 14 (2048-bit MODP) is MUST; group 19 (256-bit ECP) is SHOULD.

SHA-1 for integrity is in the same category — RFC 8247 keeps AUTH_HMAC_SHA1_96 only as MUST-, and flags the growing attacks against SHA-1.

What to use instead on the same platforms:

! Cisco — modern replacement for the ISAKMP policy below
crypto isakmp policy 1
 encr aes 256
 hash sha256
 authentication pre-share
 group 14

crypto ipsec transform-set TSET esp-aes 256 esp-sha256-hmac
 mode tunnel

On the SRX, drop proposal-set compatible — that’s what pulls in 3DES and group 2 — and name the proposal explicitly:

set security ike proposal IKE_PROP authentication-method pre-shared-keys
set security ike proposal IKE_PROP dh-group group14
set security ike proposal IKE_PROP authentication-algorithm sha-256
set security ike proposal IKE_PROP encryption-algorithm aes-256-cbc

set security ipsec proposal IPSEC_PROP protocol esp
set security ipsec proposal IPSEC_PROP authentication-algorithm hmac-sha-256-128
set security ipsec proposal IPSEC_PROP encryption-algorithm aes-256-cbc

Both ends have to agree, so change them together — a mismatched proposal fails in phase 1 and the logs will tell you exactly which attribute didn’t match.

The rest of the build — the VTI, the NAT rules, the MSS clamp — is unaffected by any of this and still stands.

Cisco ISR: route-based VTI

The tunnel interface. tunnel mode ipsec ipv4 is what makes this a VTI rather than a GRE tunnel with crypto bolted on:

interface Tunnel10
 description TO REMOTE BRANCH
 bandwidth 15000
 ip address 172.20.1.1 255.255.255.252
 ip mtu 1400
 ip tcp adjust-mss 1360
 tunnel source GigabitEthernet0/0/0
 tunnel mode ipsec ipv4
 tunnel destination 2.2.2.2
 tunnel protection ipsec profile VTI

A host route pointing the peer address at the upstream next hop, so tunnel traffic doesn’t try to recurse through the tunnel:

ip route 2.2.2.2 255.255.255.255 1.1.1.2

And the crypto — shown as it ran, with the caveats above:

crypto isakmp policy 1
 encr 3des
 authentication pre-share
 group 2
crypto isakmp key SHAREDKEY address 2.2.2.2
crypto isakmp invalid-spi-recovery
crypto isakmp keepalive 10
!
crypto ipsec transform-set TSET esp-3des esp-sha-hmac
 mode tunnel
!
crypto ipsec profile VTI
 set transform-set TSET

Two lines there are worth understanding rather than pasting:

  • crypto isakmp keepalive 10 — DPD every 10 seconds. On an LTE path this is not optional. The carrier will drop the session and without DPD the Cisco keeps an SA alive for a peer that’s long gone.
  • crypto isakmp invalid-spi-recovery — when one end restarts and starts sending on an SA the other end no longer knows about, this renegotiates instead of black-holing. Same class of problem, same environment.

Note the pre-shared key is bound to 2.2.2.2, the MikroTik’s public address — that’s the source address the Cisco actually sees, not the SRX’s private one.

Juniper SRX: st0 and the gateway

The SRX side, as it ran. bind-interface st0.10 is the Juniper equivalent of the VTI — a secure tunnel interface you route over:

security {
    ike {
        policy IKE_DC {
            mode main;
            proposal-set compatible;
            pre-shared-key ascii-text "SHAREDPASS"; ## SECRET-DATA
        }
        gateway GW_DC {
            ike-policy IKE_DC;
            address 1.1.1.1;
            external-interface fe-0/0/6.0;
        }
    }
    ipsec {
        policy Juniper {
            proposal-set compatible;
        }
        vpn VPN_DC {
            bind-interface st0.10;
            ike {
                gateway GW_DC;
                ipsec-policy Juniper;
            }
            establish-tunnels immediately;
        }
    }
    alg {
        dns disable;
    }
    flow {
        tcp-mss {
            ipsec-vpn {
                mss 1360;
            }
        }
    }
}

Three things doing real work:

  • establish-tunnels immediately — bring the tunnel up at commit rather than waiting for interesting traffic. On a backup path you want it already up, because the moment you need it is the moment you don’t want to wait for a negotiation.
  • mode main — works here because the responder is identified by a fixed IP. Behind a dynamic address you’d need aggressive mode or IKEv2.
  • tcp-mss ipsec-vpn 1360 — the SRX-side MSS clamp, matching ip tcp adjust-mss 1360 on the Cisco.

Then put the outside interface in the untrust zone and — the step people forget — allow IKE inbound on it. Without this the SRX silently drops the negotiation:

set security zones security-zone untrust interfaces fe-0/0/6.0
set security zones security-zone untrust host-inbound-traffic system-services ike

If zones and host-inbound-traffic are unfamiliar, the SRX cheat sheet covers the model this sits on.

MikroTik: the NAT that makes it work

This is the part specific to having the firewall behind another device. The MikroTik owns 2.2.2.2 and has to hand IKE through to the SRX:

/ip firewall nat
add action=dst-nat chain=dstnat dst-address=2.2.2.2 dst-port=500 
    in-interface=lte1 protocol=udp to-addresses=172.16.1.2 to-ports=500
add action=dst-nat chain=dstnat dst-address=2.2.2.2 dst-port=4500 
    in-interface=lte1 protocol=udp to-addresses=172.16.1.2 to-ports=4500
add action=src-nat chain=srcnat out-interface=lte1 src-address=172.16.1.2 
    to-addresses=2.2.2.2

Both ports are required. UDP 500 carries the initial IKE exchange. Once both peers detect a NAT between them, they migrate to UDP 4500 and encapsulate ESP inside UDP — that’s NAT-T, and it exists precisely because ESP is a protocol in its own right with no ports for a NAT device to translate.

Forward only 500 and you get the classic symptom: phase 1 completes, phase 2 never does, and the logs look fine on both ends.

The src-nat rule matters just as much. Return traffic from the SRX has to leave with 2.2.2.2 as its source, or the Cisco receives packets from an address that doesn’t match the SA it negotiated and discards them.

Verifying it on the SRX

Phase 1 — is the IKE SA up:

show security ike security-associations

node0:
--------------------------------------------------------------------------
Index    State  Initiator cookie  Responder cookie  Mode  Remote Address
1990848  UP     0a8d1bb614de2965  47ade7df5b93f10f  Main  1.1.1.1

UP and mode Main is what you want. For detail on a specific SA:

show security ike security-associations index <index> detail
show security ike security-associations <peer-ip>
show security ike stats

Phase 2 — is there an actual IPSec SA passing traffic:

show security ipsec security-associations | no-more

node0:
--------------------------------------------------------------------------
  Total active tunnels: 3
  ID          Algorithm       SPI       Life:sec/kb   Mon lsys Port Gateway
  <131073     ESP:3des/sha1   828f5d73  1299/4426652  -   root  500 1.1.1.1
  >131073     ESP:3des/sha1   3c0637c3  1299/4426652  -   root  500 1.1.1.1

You want a pair — < inbound and > outbound. One direction only means traffic is being encrypted but nothing is coming back, which usually points at the NAT rules rather than the crypto.

Note the Port column reads 500 here. Behind a NAT that has been detected you’d expect 4500 instead — a useful confirmation that NAT-T actually engaged.

And when a tunnel that should be up isn’t:

show security ipsec inactive-tunnels

On the Cisco side the equivalents are show crypto isakmp sa, show crypto ipsec sa, and show interface Tunnel10. Because it’s a VTI, that last one tells you the line protocol state like any other interface — which is most of why route-based is worth the setup.

What actually broke

Two things, both worth knowing in advance:

MSS. Without the clamp the tunnel comes up, ping works, SSH works, and anything that moves a real payload stalls. IPSec overhead pushes packets past the path MTU, and if PMTU discovery is being filtered anywhere — likely on a carrier LTE path — you get a silent black hole for large packets. 1400 MTU and 1360 MSS on both ends.

LTE address changes. A “static” public IP from a mobile carrier is static until it isn’t. When 2.2.2.2 changes, the Cisco’s crypto map and host route both still point at the old one and the tunnel stays down until someone updates them. DPD detects the failure quickly; it can’t fix it. If you’re building this now, IKEv2 with a dynamic peer identity is the better answer.

Sources


Related: How to make a private VPN server in 10 minutes, Making Home Lab. Part 1

More about Mike →

← Previous
Next →