Juniper Junos Host Zone

I recently have been building some new firewalls and finally got a chance to play with a feature released with 11.4 junos os. Using the junos-host security zone to statefully firewall incoming RE based traffic instead of using a stateless firewall filter say on the router/firewalls loopback. I am still yet to see the full advantages and disadvantages of using such a system to protect the firewall. From what I can tell, if you had lets say 5 zones you wanted to protect them from the “outside” you would have to write the same policy for every zone that you have on the system. i.e. from the internet to junos-host, from accounts to junos-host, from sales to junos-host, from engineering to junos-host; That would go on for all zones you would want to permit access to the SRX. In my example here, I only want to secure against the zone that the internet has been placed in. So its a simple and single to and from zone policy.

Here is my policy configuration from a zone ive called untrust for demonstration purposes to the junos-host zone

set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match source-address allowed_hosts
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match destination-address any
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-icmp-all
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-radius
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-snmp-agentx
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-ssh
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-bgp
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-http
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-https
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-ospf
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect match application junos-tacacs
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect then permit
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect then log session-init
set security policies from-zone untrust to-zone junos-host policy routing-engine-protect then count

set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp match source-address allowed_hosts_snmp
set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp match destination-address any
set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp match application snmp
set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp then permit
set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp then log session-init
set security policies from-zone untrust to-zone junos-host policy routing-engine-snmp then count

I have created two policies here, one for general protocols and remote access and another just for SNMP. I have created some address sets for the source traffic I want to permit accessing this firewall. These are management servers and consoles that should be allowed to interact with the firewall.

Another point worth noting here is even though you are allowing various protocols in the security policy, Junos OS still requires you to add the protocols and system services under the security zone hierarchy. There is a bit of double handling here but nothing of too much concern. An example snippet of this here:

 
set security zones security-zone untrust host-inbound-traffic system-services ping
set security zones security-zone untrust host-inbound-traffic system-services snmp
set security zones security-zone untrust host-inbound-traffic protocols bgp
set security zones security-zone untrust host-inbound-traffic protocols bfd

Initially when I set this up, nothing seemed to work. I was pretty much at the point of almost not going any further when a colleague of mine at the time had discovered that junos-host policies are completely backwards compared to standard junos security policies. As you will probably know, on the SRX platform, and for that matter, any firewall structure, the default action should be deny unless otherwise permitted explicitly. However, for the junos host zone, if you don’t deny traffic explicitly, everything will be permitted no matter if you have it matched and permitted in the policy or not. This is when a great little apply-group comes in handy to globally place a deny policy in for any combination of security policies you have on the system. Credit here for this one goes to Graham Brown @mountainrescuer (JNCIP-SEC) for coming up with this apply group and kindly sharing it with me.

set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL match source-address any
set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL match destination-address any
set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL match application any
set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL then deny
set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL then log session-init
set groups BLANKET_DENY_ALL_POLICY security policies from-zone <*> to-zone <*> policy DENY_ALL then count
set security policies apply-groups BLANKET_DENY_ALL_POLICY

And here are the results! (As of 12 something, there is this awesome command you can view to show policy hit count)

perrin@fw01.nz> show security policies hit-count | match DENY_ALL 
 3       InternetCombined InternetCombined  DENY_ALL       0            
 19      InternetCombined SRX_LAN           DENY_ALL       14355        
 22      InternetCombined Tunnel_Services   DENY_ALL       73           
 24      SRX_LAN          InternetCombined  DENY_ALL       0            
 26      SRX_LAN          Tunnel_Services   DENY_ALL       0            
 28      SRX_LAN          InternetCombined_WAN DENY_ALL    0            
 30      Tunnel_Services  InternetCombined  DENY_ALL       1083         
 33      Tunnel_Services  SRX_LAN           DENY_ALL       69606        
 36      Tunnel_Services  Tunnel_Services   DENY_ALL       0            
 39      InternetCombined_WAN SRX_LAN       DENY_ALL       5            
 42      InternetCombined_WAN Tunnel_Services DENY_ALL     479          
 44      CiscoVPN         InternetCombined  DENY_ALL       0            
 46      CiscoVPN         SRX_LAN           DENY_ALL       0

That output is from the firewall ive used in other posts here to give you an example of the output, it doesn’t actually run the junos-host zone like in this blog.

I will now show you the operation of the firewall I have implemented the junos-host zone on.

perrin@lab.fwl01.syd04> show security policies hit-count  | match junos-host                    
 1       untrust          junos-host        router_protect 5995         
 2       untrust          junos-host        DENY_ALL       214

I have done a few tests with various hosts and protocols to make sure this works as expected, specifically SNMP and SSH.
Here I will remove my cacti server that polls this firewall from the address-set that is currently allowing it to communicate via SNMP

delete security zones security-zone untrust address-book address-set vocus_monitoring address 202.124.x.x/32

You can see here that once I removed this host, the server can no longer communicate with the SRX demonstrating the global deny policy is working well.
Screen Shot 2014-03-05 at 12.57.07 pm
Once that has been rolled back, all is well again.
Screen Shot 2014-03-05 at 1.00.10 pm
Here is an example with SSH, the my server external IP has been removed from the list

perrin@server:~$ ssh perrin@175.x.x.2
ssh: connect to host 175.x.x.2 port 22: Connection timed out

with SSH enabled and server external IP added back into the address-set

perrin@server:~$ ssh perrin@175.x.x.2
perrin@175.x.x.2's password: 
--- JUNOS 12.1X44-D25.5 built 2013-10-24 20:29:21 UTC
{primary:node0}
perrin@lab.fwl01.syd04>

You can also see here the hit counts have incremented after traffic has been allowed and denied

perrin@lab.fwl01.syd04> ...hit-count | match junos-host                       
 1       untrust          junos-host        router_protect 6165         
 2       untrust          junos-host        DENY_ALL       228

On my SRX220, I use a stateless filter that does roughy the same job as this statefull filter, it really comes down to your setup and application base whether its going to be best suited to you.
For example, for me to do pretty much the same job with a firewall filter, I’m using 350 lines of “set” configuration, various policy-statements and policers at this state I like the way it works and want to keep it this way. I won’t give you the set output, and all the components that make it up, its far too long!

perrin@fw01.nz> show configuration firewall | display set | count     
Count: 350 lines

And here is the hit count, which demonstrates how many filters and policers I’m actually using!

perrin@fw01.nz> show firewall filter lo0.0-i 

Filter: lo0.0-i                                                
Counters:
Name                                                Bytes              Packets
accept-ah-lo0.0-i                                       0                    0
accept-bfd-lo0.0-i                                      0                    0
accept-bgp-lo0.0-i                               45838200               801626
accept-dhcp-lo0.0-i                               1029986                 3102
accept-dns-lo0.0-i                                   3221                   21
accept-esp-lo0.0-i                                      0                    0
accept-http-lo0.0-i                               2941611                44749
accept-ike-lo0.0-i                               23924260                63582
accept-nat_t-lo0.0-i                             10178583               110789
accept-ntp-lo0.0-i                                 846108                11133
accept-ospf-lo0.0-i                             414951400              3643606
accept-rip-igmp-lo0.0-i                                 0                    0
accept-rip-udp-lo0.0-i                                  0                    0
accept-rsvp-lo0.0-i                              37662104               418416
accept-snmp-lo0.0-i                             126560749               890182
accept-ssh-lo0.0-i                                4374951                59621
discard-all-TTL_1-unknown-lo0.0-i                       0                    0
discard-icmp-lo0.0-i                               365221                 6520
discard-ip-options-lo0.0-i                            256                    8
discard-netbios-lo0.0-i                                 0                    0
discard-tcp-lo0.0-i                                260264                 5104
discard-udp-lo0.0-i                               2554056                 7831
discard-unknown-lo0.0-i                               280                    7
no-icmp-fragments-lo0.0-i                               0                    0
Policers:
Name                                                Bytes              Packets
mgmt-police-10m-accept-ssh-lo0.0-i                                           0
mgmt-police-1m-accept-dns-lo0.0-i                                            0
mgmt-police-1m-accept-ntp-lo0.0-i                                            0
mgmt-police-5m-accept-established-tcp-fetch-lo0.0-i                          0
mgmt-police-5m-accept-established-tcp-ftp-data-lo0.0-i                       0
mgmt-police-5m-accept-established-tcp-ftp-data-syn-lo0.0-i                    0
mgmt-police-5m-accept-established-tcp-ftp-lo0.0-i                            0
mgmt-police-5m-accept-established-tcp-ssh-lo0.0-i                            0
mgmt-police-5m-accept-established-tcp-telnet-lo0.0-i                         0
mgmt-police-5m-accept-established-udp-ephemeral-lo0.0-i                      0
mgmt-police-5m-accept-icmp-lo0.0-i                                           0
mgmt-police-5m-accept-snmp-lo0.0-i                                           0
mgmt-police-5m-accept-traceroute-icmp-lo0.0-i                                0
mgmt-police-5m-accept-traceroute-tcp-lo0.0-i                                 0
mgmt-police-5m-accept-traceroute-udp-lo0.0-i                                 0

Some credit here needs to go to engineers Boye Olowoyeye and Tim Hoffman, @hoffnz (both JNCIE-SP) for doing a lot of ground work on these filters before I took them, modified and added to it.

I have found I can be far more granular with the stateless filters at my current knowledge set especially coming from a ISP background and doing a lot of firewall filters and “ACLs” for customer solutions but again it really comes down to the individual and what works best for your system.