Route-Based Site-to-Site VPN on Juniper SRX Security Gateways

My inaugural post! I wanted to start with something that has become fundamental to network connectivity and security; Virtual Private Networks (VPN). In this scenario Site-to-Site VPNs on Juniper SRX security gateways, a.k.a. firewalls.

We have two networks, an office and a lab, in two cities, Milwaukee (office) and Chicago (lab).

Using Firewall Filters and Counters as a tcpdump Alternative in Junos

Junos is truly a great Network Operating System, the best in my opinion. When it comes to being able to sniff traffic directly from an interface though it falls short. I imagine this is because the control and forwarding planes are completely separate. A few weeks ago we had an issue where traffic was entering the firewall, being processed by the Services Processing Cards (SPCs) to the point we saw a log entry that the session was setup, but we did not see it egress the firewall. We wanted a way to quickly ascertain if the packet is leaving the device. This is where firewall filters and counters come in handy. Because they are applied directly to an interface, they are processed first when the packet comes in and last as the packet leaves the device.

First we are going to create a filter unique to the traffic we want to monitor, this is much like the options we would pass to tcpdump to filter traffic. We create a firewall filter called PACKET-EGRESS and create two terms. The first term sets the criteria we want to match and the second term permits the traffic. I cannot stress the importance of the second term, if you forget it you will drop all traffic as firewall filters implicitly deny traffic!


set firewall filter PACKET-HTTP-COUNT term 1 from source-address 192.168.1.73/32
set firewall filter PACKET-HTTP-COUNT term 1 from destination-address 8.8.8.8/32
set firewall filter PACKET-HTTP-COUNT term 1 from destination-port 80
set firewall filter PACKET-HTTP-COUNT term 1 then count PACKET-EGRESS-COUNT
set firewall filter PACKET-HTTP-COUNT term 2 then accept

Now that our criteria are set the next step is to apply the firewall filter to an interface. We could apply to to the ingress interface if we wanted to ensure traffic is reaching the device or on the egress interface if we want to ensure traffic is leaving the device. In this example we will apply it to the egress interface.


set interfaces reth15 unit 40 family inet filter output PACKET-EGRESS

Applying the firewall filter to an interface via input would measure traffic that has reached the interface whereas applying the firewall filter to an interface via output would measure traffic that has transited an interface.

Using apply-groups to Log a Default Deny Policy on Juniper SRX Firewalls

It is a requirement, and in some cases it is the law, to log session denies on firewalls for accountability. On the Juniper SRX firewalls there is no boolean option to log default drops, instead you have to create a policy that explicitly denies and then logs via then log session-init. This becomes an issue when creating new global policies as they are always applied to the bottom and therefore below the policy we create to explicitly deny and log traffic. We have been pushing Juniper via a Feature Enhancement Request to include logging in as part of the default set security policies default-policy stanza so we didn’t have to worry about managing a default drop policy.

Until that time a co-worker and good friend of mine, Doug Didier (@KegedViolence), had a great idea to use apply-groups to manage the global policy as they are by default applied last. To do this we create a group, called in this case DENY-WITH-LOGGING, and then create our default deny and log policy under that.


[email protected]# set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING match source-address any
[email protected]# set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING match destination-address any
[email protected]# set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING match application any
[email protected]# set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING then deny
[email protected]# set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING then log session-init

Side note, notice there is no set groups DENY-WITH-LOGGING security policies global policy DENY-WITH-LOGGING then log session-close as the session does not get setup on a wing and therefor there is no session to close.

We then apply this group to the security policies section of the configuration.

[email protected]# set security policies apply-groups DENY-WITH-LOGGING

After commiting the change there are two ways to validate this. First from the configuration we can display inheritance in the configuration.

[email protected]# show security policies global | display inheritance 
policy ICMP {
    match {
        source-address any;
        destination-address any;
        application junos-icmp-all;
    }
    then {
        permit;
        log {
            session-init;
            session-close;
        }
    }
}
##
## 'DENY-WITH-LOGGING' was inherited from group 'DENY-WITH-LOGGING'
##
policy DENY-WITH-LOGGING {
    ##
    ## 'match' was inherited from group 'DENY-WITH-LOGGING'
    ##
    match {
        ##
        ## 'any' was inherited from group 'DENY-WITH-LOGGING'
        ##
        source-address any;
        ##
        ## 'any' was inherited from group 'DENY-WITH-LOGGING'
        ##
        destination-address any;
        ##
        ## 'any' was inherited from group 'DENY-WITH-LOGGING'
        ##
        application any;
    }
    ##
    ## 'then' was inherited from group 'DENY-WITH-LOGGING'
    ##
    then {
        ##
        ## 'deny' was inherited from group 'DENY-WITH-LOGGING'
        ##
        deny;
        ##
        ## 'log' was inherited from group 'DENY-WITH-LOGGING'
        ##
        log {
            ##
            ## 'session-init' was inherited from group 'DENY-WITH-LOGGING'
            ##
            session-init;
        }
    }
}

Secondly we can can also validate this in operational mode.

[email protected]> show security policies global 
Global policies:
  Policy: ICMP, State: enabled, Index: 29, Scope Policy: 0, Sequence number: 1
    Source addresses: any
    Destination addresses: any
    Applications: junos-icmp-all
    Action: permit, log
  Policy: DENY-WITH-LOGGING, State: enabled, Index: 30, Scope Policy: 0, Sequence number: 2
    Source addresses: any
    Destination addresses: any
    Applications: any
    Action: deny, log

Though you could also do this in a zone-to-zone fashion this is the type of time that global policies were designed to handle. Whether you manage ten or ten thousand security policies you will realize what a time and troubleshooting saver this can be.