Reading Time: 4 minutes
One of the things that I am called upon to do fairly often in my current role is to configure remote access VPN devices for some site or another. Often these sites are transient in nature, only staying active for weeks or months at the longest before disappearing forever–or at least until I don’t care any more.
Because I spend a fair amount of time setting these VPN tunnels up, I have gotten fairly good at the ins and outs of IPsec VPN tunnel configuration and troubleshooting. I was even beginning to think of myself as a bit of a VPN whisperer. That was about to change, however.
We use Cisco’s ASA product line everywhere for this type of thing, and as many of you no doubt know, if you use one vendor’s product for VPN tunnels you are generally in a good position. You’ll likely still have problems from time to time–just enough to keep you honest–but it works itself out. This is the model we’d been following for several years. Until now.
For reasons passing interest here, we made the decision to start exploring the use of Juniper’s SRX product line for our remote, transient tunnel destinations and smaller offices. We were not–and are not–prepared to rip-and-replace our entire ASA installed base, though, so these Juniper devices would have to integrate with the existing infrastructure. This, as they say, is when the proverbial excrement hit the fan.
As anyone who deals in these things knows, mixing vendors on either side of a VPN tunnel is generally a recipe for trouble. Depending on vendors, your troubles range from the “few drinks after work” type to the “move to Mexico and open a beach bar” kind. I had heard from many people that I trust that the SRX to ASA configuration was this latter type.
Juniper SRX devices prefer a type of VPN tunnel known as a route-based VPN. I’m not going to go into specifics here, but suffice it to say it’s a technique that makes sense and a lot of vendors work this way. Cisco’s ASA, on the other hand, prefers a type of VPN tunnel known as policy-based. Policy-based VPNs have some limitations and seem to be favored mostly by Cisco and anyone who wants to integrate with Cisco. I had to make things work without changing much on the HQ side (where the Corporate ASA units sit) outside of what we normally do, so that meant that the SRX at the remote site needed to be configured in a policy-based way.
Bring on the pain.
The process I followed went something like this:
- Spend a couple of days learning the Juniper SRX syntax. This part was actually kind of fun.
- Spend 5 minutes configuring new tunnel on corporate ASA.
- Spend 3+ days trying to get Juniper to talk to ASA. Spend only slightly more time configuring as banging head on desk.
- Spend 5.5 hours spread over two more days with jTAC. Bang head more while they can’t figure it out either.
- Go home, relax, have eureka moment, race back to office, make one-line change, FIX EVERYTHING!
- Go back home and drink.
As it turns out, the problem can best be described as something that every Cisco Engineer learns in infancy: Cisco is consistently inconsistent. For example, when the ASA refers to SHA, do you suppose it’s refering to the old SHA‑0 or the SHA‑1 that corrected a flaw in the old SHA‑0? Dunno. Since they, in some places, only say “SHA” and in others “SHA‑1” it’s anybody’s guess, really.
The main thing I re-learned from this experience is that the defaults–the little timers, identities, and various other little bits–that make up a successful negotiation for an IPsec tunnel are different across platforms. Sometimes you really have to search to find what they’re called. Sometimes you have to bang your head on the desk for a few days.
One more thing: this post was typed up quickly, with no editing, and way too much coffee. If I’ve overlooked things, gotten things wrong, or just confused you more, I apologize and I’ll try to come back and clean it up later. In the mean time, hopefully the diagram and configurations below will help you in your own quest to get a policy-based VPN configured between the SRX and ASA.
Oh, and as soon as I recover from this experience I’ll build out a configuration to do a route-based example, which looks to only require a couple of changes on the SRX side and a tad more tweaking perhaps on the ASA side.
ASA CONFIGURATION (Sanitized):
crypto map outside_map 1 match address outside_cryptomap_3 crypto map outside_map 1 set connection-type bi-directional crypto map outside_map 1 set peer 5.5.5.5 crypto map outside_map 1 set ikev1 phase1-mode main crypto map outside_map 1 set ikev1 transform-set ESP-AES-256-SHA crypto map outside_map 1 set reverse-route crypto map outside_map interface outside
crypto ipsec ikev1 transform-set ESP-AES-256-SHA esp-aes-256 esp-sha-hmac crypto ipsec security-association lifetime seconds 28800 crypto ipsec security-association lifetime kilobytes 4608000 crypto ipsec security-association replay window-size 64 crypto ipsec fragmentation before-encryption outside crypto ipsec fragmentation before-encryption inside crypto ipsec df-bit copy-df outside crypto ipsec df-bit copy-df inside
crypto ikev1 enable outside crypto ikev1 policy 4 authentication pre-share encryption aes-256 hash sha group 2 lifetime 28800 nat (inside,outside) source static CISCO_NETWORK CISCO_NETWORK destination static JUNIPER_NETWORK JUNIPER_NETWORK no-proxy-arp
object network CISCO_NETWORK subnet 10.0.0.0 255.255.0.0 description Cisco Network
object network JUNIPER_NETWORK subnet 10.7.24.0 255.255.255.0 description Juniper Network
JUNIPER CONFIGURATION (Sanitized):
proposal ike-policy1 { authentication-method pre-shared-keys; dh-group group2; authentication-algorithm sha1; encryption-algorithm aes-256-cbc; lifetime-seconds 28800; } policy ike-policy1 { mode main; proposals ike-policy1; pre-shared-key ascii-text "$%#@!!!"; ## SECRET-DATA } gateway ike-gate { ike-policy ike-policy1; address 5.5.5.5; local-identity inet 6.6.6.6; external-interface fe-0/0/0; }
proposal IPSEC_PROPOSAL { protocol esp; authentication-algorithm hmac-sha1-96; encryption-algorithm aes-256-cbc; lifetime-seconds 28800; } policy IPSEC_POLICY { proposals IPSEC_PROPOSAL; } vpn ike-vpn { ike { gateway ike-gate; inactive: proxy-identity { local 10.7.24.0/24; remote 10.0.0.0/16; service any; } ipsec-policy IPSEC_POLICY; } establish-tunnels immediately; }
source { rule-set trust-to-untrust { from zone trust; to zone untrust; rule nonat { match { source-address 10.7.24.0/24; destination-address 10.0.0.0/16; } then { source-nat { off; } } } rule ZZZ { match { source-address 0.0.0.0/0; destination-address 0.0.0.0/0; } then { source-nat { interface; } } } } }