SRX - Using go-junos to quickly build and deploy IPsec VPN's

IPsec VPN's are a very efficient and secure way to establish connectivity between remote sites. If you have multiple locations, building the configurations can be a bit cumbersome and take a bit of time. I'll show you an example of how using the go-junos API library can make this a very easy task.

Building Our VPN

You will need to create a configuration on both ends, but for this example, let's assume that you only manage the headend SRX, and the remote site is a vendor's firewall.

Connect to the SRX

jnpr, err := junos.NewSession("headend-srx", "admin", "Juniper1!")  
if err != nil {  
    fmt.Println(err)
}
defer jnpr.Close()  

Once we've established our connection to the SRX, we can jump right in and start to build our tunnel.

Create a new Tunnel

Creating a new tunnel takes simple command where we specify the following information:

  • Name of our VPN
  • Local and remote endpoints (IP addresses)
  • External interface of our SRX (typically the interface where our local IP address is tied to).
  • Security-zone where our st0 interface will reside.
  • Perfect-forward-secrecy: To enable, use a Diffe-Hellman group number. To disable use 0.
  • Establish tunnel option. traffic will establish the tunnel on-traffic, immediately will establish the tunnel immediately.
  • main mode or aggressive mode
  • PSK
vpn := jnpr.NewIPsecVPN("Some-VPN", "1.2.3.4", "5.5.5.5", "ge-0/0/1.0", "vpn", 0, "immediately", "main", "supersecret")  

IKE Phase 1

Now we can create our IKE phase 1 proposals. You can specify a single one, or multiple if you like. Phase1() allows the following options:

  • Name of the proposal, i.e. "sha1-aes256."
  • Diffe-Hellman group
  • Authentication algorithm
  • Encryption algorithm
  • Lifetime in seconds
vpn.Phase1("sha1-aes256", 2, "sha1", "aes-256", 28800)  
vpn.Phase1("sha1-3des", 2, "sha1", "3des", 86400)  

IKE Phase 2

Once we have phase 1 completed, we can move on to create our phase 2 proposals with similar options:

  • Proposal name
  • Authentication algorithm
  • Encryption algorithm
  • Lifetime in seconds
  • Protocol: ah or esp
vpn.Phase2("sha1-aes256", "sha1", "aes-256", 3600, "esp")  
vpn.Phase2("sha1-3des", "sha1", "3des", 3600, "ah")  

Traffic-Selectors (SA)

The final piece that we'll need to configure is our traffic-selectors. Some other vendor's call these "proxy-ID's," but they are the same thing.

We do this by specifying a list of local IP addresses and/or subnets, as well as the remote end's:

local := []string{  
    "10.0.0.0/8",
    "172.20.0.0/16",
    "192.168.30.5/32",
}
remote := []string{  
    "192.168.100.0/24",
    "192.168.101.0/24",
}
vpn.TrafficSelector(local, remote)  

Building and Deploying The Configuration

Now that we have configured all of the parts needed to establish a site-to-site VPN tunnel, we need to deploy our configuration to the SRX. Once we build our config, we can easily deploy it with the Config() function:

vpnConfig := vpn.BuildIPsecVPN()  
jnpr.Config(vpnConfig, "set", true)  

NOTE: If your SRX is configured for HA (chassis cluster) then you have to make sure to put the st0.<unit> interface under the routing-instance that is configured.

If you wanted to view the configuration that will be deployed, you can always just print it using the following command in your script:

fmt.Println(vpnConfig)  

Using this example, the configuration will look like the following:

set interfaces st0.5 family inet  
set security zones security-zone vpn interfaces st0.5  
set security ike proposal sha1-aes256 authentication-method pre-shared-keys  
set security ike proposal sha1-aes256 dh-group group2  
set security ike proposal sha1-aes256 authentication-algorithm sha1  
set security ike proposal sha1-aes256 encryption-algorithm aes-256-cbc  
set security ike proposal sha1-aes256 lifetime-seconds 28800  
set security ike proposal sha1-3des authentication-method pre-shared-keys  
set security ike proposal sha1-3des dh-group group2  
set security ike proposal sha1-3des authentication-algorithm sha1  
set security ike proposal sha1-3des encryption-algorithm 3des-cbc  
set security ike proposal sha1-3des lifetime-seconds 86400  
set security ike policy Some-VPN mode main  
set security ike policy Some-VPN pre-shared-key ascii-text "supersecret"  
set security ike policy Some-VPN proposals sha1-aes256  
set security ike policy Some-VPN proposals sha1-3des  
set security ike gateway Some-VPN address 5.5.5.5  
set security ike gateway Some-VPN external-interface ge-0/0/1.0  
set security ike gateway Some-VPN ike-policy Some-VPN  
set security ike gateway Some-VPN local-identity inet 1.2.3.4  
set security ike gateway Some-VPN remote-identity inet 5.5.5.5  
set security ipsec proposal sha1-aes256 protocol esp  
set security ipsec proposal sha1-aes256 authentication-algorithm hmac-sha1-96  
set security ipsec proposal sha1-aes256 encryption-algorithm aes-256-cbc  
set security ipsec proposal sha1-aes256 lifetime-seconds 3600  
set security ipsec proposal sha1-3des protocol ah  
set security ipsec proposal sha1-3des authentication-algorithm hmac-sha1-96  
set security ipsec proposal sha1-3des encryption-algorithm 3des-cbc  
set security ipsec proposal sha1-3des lifetime-seconds 3600  
set security ipsec policy Some-VPN proposals sha1-aes256  
set security ipsec policy Some-VPN proposals sha1-3des  
set security ipsec vpn Some-VPN bind-interface st0.5  
set security ipsec vpn Some-VPN ike gateway Some-VPN  
set security ipsec vpn Some-VPN ike idle-time 60  
set security ipsec vpn Some-VPN ike ipsec-policy Some-VPN  
set security ipsec vpn Some-VPN establish-tunnels immediately  
set security ipsec vpn Some-VPN traffic-selector ts1 local-ip 10.0.0.0/8 remote-ip 192.168.100.0/24  
set security ipsec vpn Some-VPN traffic-selector ts2 local-ip 10.0.0.0/8 remote-ip 192.168.101.0/24  
set security ipsec vpn Some-VPN traffic-selector ts3 local-ip 172.20.0.0/16 remote-ip 192.168.100.0/24  
set security ipsec vpn Some-VPN traffic-selector ts4 local-ip 172.20.0.0/16 remote-ip 192.168.101.0/24  
set security ipsec vpn Some-VPN traffic-selector ts5 local-ip 192.168.30.5/32 remote-ip 192.168.100.0/24  
set security ipsec vpn Some-VPN traffic-selector ts6 local-ip 192.168.30.5/32 remote-ip 192.168.101.0/24  

Wrap-up

As you can see, in just a few steps we were able to quickly build and deploy a new site-to-site VPN. Here's what the script looks like when it all comes together:

package main

import (  
    "fmt"
    "github.com/scottdware/go-junos"
)

func main() {  
    jnpr, err := junos.NewSession("headend-srx", "admin", "Juniper1!")
    if err != nil {
        fmt.Println(err)
    }
    defer jnpr.Close()

    vpn := jnpr.NewIPsecVPN("Some-VPN", "1.2.3.4", "5.5.5.5", "ge-0/0/1.0", "vpn", 0, "immediately", "main", "supersecret")
    vpn.Phase1("sha1-aes256", 2, "sha1", "aes-256", 28800)
    vpn.Phase1("sha1-3des", 2, "sha1", "3des", 86400)
    vpn.Phase2("sha1-aes256", "sha1", "aes-256", 3600, "esp")
    vpn.Phase2("sha1-3des", "sha1", "3des", 3600, "ah")

    local := []string{
        "10.0.0.0/8",
        "172.20.0.0/16",
        "192.168.30.5/32",
    }
    remote := []string{
        "192.168.100.0/24",
        "192.168.101.0/24",
    }
    vpn.TrafficSelector(local, remote)

    vpnConfig := vpn.BuildIPsecVPN()
    jnpr.Config(vpnConfig, "set", true)
}