IPv6 and Junos – Firewall Filter (ACLs)

For IPv6 testing I’ve been asked to do one of the more noddy things to test Firewall Filters; these are Stateless Firewall Filters and are what Cisco call Access Control Lists (ACL). Unlike Stateful Firewall Filters, Stateless Filters do not inspect traffic flows, pattern or keep a record of network connections, as such TCP streams and/or UDP communication. Instead, these filters evaluate packet contents statically against a set of packet-matching rules that either permit or deny packets transiting the switch.

Firewall Filter (ACL) is an important feature for a switch to have as it provides some (although limited) protection for devices and host directly connected. I said that this was one of the more noddy things as there’s only one difference between creating a Firewall Filter for IPv4 and IPv6. However, as they say, better to be safe than sorry! With all that said and done, this post will be to show how you’d configure and implement a Stateless Firewall Filter within Junos.

Let’s get cracking 🙂

I had a pretty simple topology, using a Juniper EX Series 4200 switch configured with two Layer-3 vlans, and I’ve set up two Ubuntu 14.04LTS ESXi host; 1 of the host will be configured as a webserver (km-vm1) and the other as a client trying to access the server (km-vm3)

Firewall Filter Topology

Firstly, I created all of the physical and logical connections were expected, by running show ipv6 neighbors and show lldp neighbors

IPv6 SubnetsServers
[email protected]> show ipv6 neighbors 
IPv6 Address                 Linklayer Address  State       Exp Rtr Secure Interface
2001:123:212:1::2            00:0c:29:fc:d5:de  stale       202 no  no      vlan.300       
2001:192:168:2::2            00:0c:29:4f:26:c5  stale       1197 no no      vlan.200
[email protected]> show lldp neighbors 
Local Interface    Parent Interface    Chassis Id          Port info          System Name
ge-0/0/0.0         -                   00:0c:29:4f:26:bb   eth1               km-vm1                          
xe-0/1/0.0         -                   00:0c:29:fc:d5:d4   eth1               km-vm3

The goal of this test is ensure that KM-VM3 can ONLY access KM-VM1 on TCP ports 80 and 443, as these are well-known and IANA defined ports for unsecured (HTTP) and secured (HTTPS) web traffic, and ICMP traffic (ie. ping and traceroute).

Before configuring the Firewall Filter I wanted to see what was accessible for KM-VM3, so I ran a very useful open source utility for network discovery and a security auditing tool called nmap , to produce a port scan of the webserver. From the output we can see that not only are HTTP and HTTPS accessible, but the Port 22 Secure Shell (SSH) is open. As KM-VM1 doesn’t have any firewalling configured on the server level via iptables, KM-VM3 could be used to try and hack KM-VM1 by attacking the SSH port to gain access to the server, which is never good!

Port ScanSSH access
[email protected]:~$ nmap -6 2001:192:168:2::2

Starting Nmap 6.40 ( http://nmap.org ) at 2015-11-11 14:17 GMT
Nmap scan report for 2001:192:168:2::2
Host is up (0.0017s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https
[email protected]:~$ ssh 2001:192:168:2::2
The authenticity of host '2001:192:168:2::2 (2001:192:168:2::2)' can't be established.
ECDSA key fingerprint is e3:e3:f7:91:c0:30:a3:02:f9:1f:fd:aa:b7:0d:9c:9d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '2001:192:168:2::2' (ECDSA) to the list of known hosts.
[email protected]:192:168:2::2's password:

With that security risk in mind, lets add a Firewall Filter that will only allow access to ports 80, 443 and ICMP traffic. I created a prefix-list, webservers, that would list all the prefixes (IP addresses) for the webservers. Although in this example I’ll only have the one prefix, I was always taught to use prefix-lists for ease of configuration. This was configured under edit policy-options prefix-list stanza:

[email protected]# show policy-options       
prefix-list webservers {
    2001:192:168:2::2/128;
}

Now, for the Filter you’ll need to be under firewall family inet6 filter stanza, (for an IPv4 filter; firewall family inet filter). You can name your filter anything however, it can’t be more than 64 characters and if you have any spaces you’ll need to use ” ” marks. The same goes with naming your rules, which Junos calls terms. The Filter must have at least one term and the term(s) must have from or then statement. The from and then statements provide the actions of the term.

As you can see below, the Firewall Filter is named ALLOW-HTTP/HTTPS and has 3 terms:

{master:0}[edit firewall family inet6 filter ALLOW-HTTP/HTTPS]
[email protected]# show 
term allow-http/https {
    from {
        source-address {
            ::/0;
        }
        destination-prefix-list {
            webservers;
        }
        destination-port [ 80 443 ];
    }
    then accept;
}
term allow-icmp {
    from {
        icmp-type [ echo-reply echo-request neighbor-advertisement packet-too-big destination-unreachable neighbor-solicit ];
    }
    then accept;
}
term deny-all {
    then {
        count deny-all;
        log;
        discard;
    }
}

Lets break down each aspect of this Firewall Filter:

  • The first term allow-http/https states from source-address ::/0, for IPv6 is any address to the destination of the webservers, which has been defined in the prefix-list to ports 80 and 443 (HTTP and HTTPS) to then accept those packets
  • The second term allow-icmp states the different type of icmp packets that I want allowed and then those are accepted
  • The final term deny-all states that any other packets should be counted under deny-all, logged and discarded. By using the action discard, this will silently drop all packets without sending an ICMP reply back to the requestor
Note
With Junos, it is important to remember that when creating a Firewall Filter:

  • They works as Top-Down List, so the order of your rules is very significant, because once a rule has been matched, any rules below WILL NOT be checked.
  • Additionally just like with Cisco Firewall Filters come with an Implicit Deny at the end. If any packets don’t match any of the previous terms then they will be dropped automatically. Although this Implicit Deny is there, best practice to add a deny-all term at the end any Firewall Filter or ACL.
  • Finally, you can have only one input and one output filter per interface however have as many terms as you like. You can find all the guidelines that come with Firewall Filters here on Juniper’s TechLibrary page

Having created the filter, it will an input filter, as it is configured to filter traffic coming into the switch. Additionally, it will be place on the outside-facing interface, in this example, that has KM-VM3 in (vlan.300). This is because with any Filter, ACL or Firewall Policy, you want to stop any unnecessary traffic traversing your network at the furthest possible point, which is normally the edge of your network.

So under interface vlan unit 300 family inet6 filter stanza the Firewall Filter is placed as an input filter:

{master:0}[edit interfaces vlan unit 300]
[email protected]# show 
family inet6 {
    filter {
        input ALLOW-HTTP/HTTPS;
    }
    address 2001:123:212:1::1/64;
}

Having committed the configuration, if we go back onto KM-VM3 and do some testing we’ll be able to see the effect of the Firewall Filter. As we can see below, when the port scan was run again, only ports 80 and 433 are in an OPEN STATE and SSH port 22 isn’t shown at all now, and we’re able to ping. When we try SSH we get nothing, which shows that this filter is working as expected.

Port ScanICMP PingSSH access
[email protected]:~$ nmap -6 2001:192:168:2::2

Starting Nmap 6.40 ( http://nmap.org ) at 2015-11-11 15:30 GMT
Nmap scan report for 2001:192:168:2::2
Host is up (0.00072s latency).
Not shown: 998 filtered ports
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https
[email protected]:~$ ping6 2001:192:168:2::2
PING 2001:192:168:2::2(2001:192:168:2::2) 56 data bytes
9 packets transmitted, 9 received, 0% packet loss, time 7999ms
rtt min/avg/max/mdev = 0.464/0.545/0.662/0.066 ms
[email protected]:~$ ssh 2001:192:168:2::2
^C

For further verification, we can check the counter that was set under the deny-all term to see how many packets have been dropped. By running the command show firewall counter filter ALLOW-HTTP/HTTPS deny-all we’re able to see the counters at that time.

[email protected]> show firewall counter filter ALLOW-HTTP/HTTPS deny-all 

Filter: ALLOW-HTTP/HTTPS                                       
Counters:
Name                                                Bytes              Packets
deny-all                                              490                    5

As I said, when I started this post, the method of applying a Firewall Filter is exactly same in IPv6 world as it is in IPv4, with the exception of the filter location. Firewall Filters are extremely important in giving protection to hosts and devices connected to the switch if a stateful firewall such as a Juniper SRX or Cisco ASA isn’t suitable and/or available in your network design.

The following two tabs change content below.

Keeran Marquis

Network Engineer
Keeran Marquis is a Network Engineer. His main goal is to learn everything within the Networking field, pick up a little bit of scripting, be a poor man sysadmin and share whatever he knows! All Posts are his own views, opinions and experiences, no guarantees they will work for you but point you in the right direction 🙂
Share this:
Share

7 thoughts on “IPv6 and Junos – Firewall Filter (ACLs)”

  1. Fatima

    Hi Keeran,
    I have a question regarding Juniper firewalls and you might have the answer.
    We recently deployed a pair of Juniper MX960 routers to perform multiple network functions and among them the L3 statefull firewall function. on both sides of trusted and untrusted interfaces we are receiving MP-BGP VPNv4 routes. I do understand the IP flows discontinuity (flows are permitted or blocked) but I don’t understand why its not possible to advertise the MP-BGP routes from the trusted to untrusted and vice-versa.

    Thanks for help in advance.

    1. Keeran Marquis Post Author

      Hi Fatima

      Unfortunately, I’ve never worked with stateful firewalling on MXs before and i dont know if/how it could affect MP-BGP. The only thing i could think of if the MX is same as a SRX you may need to look at host-inbound or you may need to particular zones configured for MP-BGP. Outside of that i dont have clue sorry :'(

  2. Chris

    This is a good starter article, but does not really address how you would filter link-local traffic. For example, I have OSPFv3 and I’m trying to limit where I listen to it from. In this case, I am unable to create a filter for the IPv6 link local addresses which are auto-generated. However, I don’t want to create them, since that’s kind of the point of IPv6’s simplicity…you don’t have to. In the configuration below, I am using a prefix-list based on the “apply-path” parameter. This doesn’t pick up the link-local addresses at all, unless you define them in the config (which I’m trying not to do).

    So, how do you permit the desired OSPFv3 traffic to the Control Plane from while blocking it from elsewhere (like xe-0/0/0)? I haven’t completely figured it out yet, but suspect I may have to block OSPF at the xe-0/0/0.0 interface with a specific filter, though it seems kludgy and not likely to work.

    Here is my example, based on my real-world config, but not quite (as I run dual stack, BFD, and some other stuff).

    I have 2 MX104 routers, R1 and R2. I used the same interfaces on both to make things simpler. Both are connected to some ISP and peer using EBGP using xe-0/0/0.0. I have “inside” interfaces for my Internet Edge. Interface xe-2/0/0.0 is direct connected between R1 and R2. Interface xe-2/0/1.0 is connected to a Layer-2 switch to provide an alternate path between the routers and to my firewall (a device that is not germane to this discussion).

    Here is the relevant config for R1:
    set policy-options prefix-list OSPF-ROUTERS apply-path “interfaces unit 0 family inet6 address ”
    set policy-options prefix list EBGP-ROUTERS apply-path “protocols bgp group ebgp neighbor ”
    set policy-options prefix list IBGP-ROUTERS apply-path “protocols bgp group ibgp neighbor ”
    #
    set firewall filter CONTROL-PLANE term BGP from source-prefix-list EBGP-ROUTERS
    set firewall filter CONTROL-PLANE term BGP from source-prefix-list IBGP-ROUTERS
    set firewall filter CONTROL-PLANE term BGP from payload-protocol tcp
    set firewall filter CONTROL-PLANE term BGP from port 179
    set firewall filter CONTROL-PLANE term BGP then accept
    set firewall filter CONTROL-PLANE term OSPFv3 from source-prefix-list OSPF-ROUTERS
    set firewall filter CONTROL-PLANE term OSPFv3 from payload-protocol ospf
    set firewall filter CONTROL-PLANE term OSPFv3 then accept
    #
    set interfaces xe-0/0/0 unit 0 family inet6 address 2001:db8:aaaa::1/64
    set interfaces xe-2/0/0 unit 0 family inet6 address 2001:db8:dddd::1/64
    set interfaces xe-2/0/1 unit 0 family inet6 address 2001:db8:eeee::1/64
    set interfaces lo0 unit 0 family inet6 address 2001:db8:ffff::1/128
    set interfaces lo0 unit 0 family inet6 filter input CONTROL-PLANE
    #
    set routing-options router-id 192.0.2.1
    #
    set protocols bgp group ebgp type external
    set protocols bgp group ebgp neighbor 2001:db8:aaaa::2
    set protocols bgp group ebgp local-as 64500
    set protocols bgp group ebgp peer-as 64510
    #
    set protocols bgp group ibgp type internal
    set protocols bgp group ibgp neighbor 2001:db8:ffff::2
    set protocols bgp group ibgp local-as 64500
    set protocols bgp group ibgp peer-as 64500
    #
    set protocols ospf3 area 0.0.0.0 interface lo0.0 passive
    set protocols ospf3 area 0.0.0.0 interface xe-2/0/0.0
    set protocols ospf3 area 0.0.0.0 interface xe-2/0/1.0

    Here is the relevant config for R2:
    set policy-options prefix-list OSPF-ROUTERS apply-path “interfaces unit 0 family inet6 address ”
    set policy-options prefix list EBGP-ROUTERS apply-path “protocols bgp group ebgp neighbor ”
    set policy-options prefix list IBGP-ROUTERS apply-path “protocols bgp group ibgp neighbor ”
    #
    set firewall filter CONTROL-PLANE term BGP from source-prefix-list EBGP-ROUTERS
    set firewall filter CONTROL-PLANE term BGP from source-prefix-list IBGP-ROUTERS
    set firewall filter CONTROL-PLANE term BGP from payload-protocol tcp
    set firewall filter CONTROL-PLANE term BGP from port 179
    set firewall filter CONTROL-PLANE term BGP then accept
    set firewall filter CONTROL-PLANE term OSPFv3 from source-prefix-list OSPF-ROUTERS
    set firewall filter CONTROL-PLANE term OSPFv3 from payload-protocol ospf
    set firewall filter CONTROL-PLANE term OSPFv3 then accept
    #
    set interfaces xe-0/0/0 unit 0 family inet6 address 2001:db8:bbbb::1/64
    set interfaces xe-2/0/0 unit 0 family inet6 address 2001:db8:dddd::2/64
    set interfaces xe-2/0/1 unit 0 family inet6 address 2001:db8:eeee::2/64
    set interfaces lo0 unit 0 family inet6 address 2001:db8:ffff::2/128
    set interfaces lo0 unit 0 family inet6 filter input CONTROL-PLANE
    #
    set routing-options router-id 192.0.2.2
    #
    set protocols bgp group ebgp type external
    set protocols bgp group ebgp neighbor 2001:db8:bbbb::2
    set protocols bgp group ebgp local-as 64500
    set protocols bgp group ebgp peer-as 64511
    #
    set protocols bgp group ibgp type internal
    set protocols bgp group ibgp neighbor 2001:db8:ffff::1
    set protocols bgp group ibgp local-as 64500
    set protocols bgp group ibgp peer-as 64500
    #
    set protocols ospf3 area 0.0.0.0 interface lo0.0 passive
    set protocols ospf3 area 0.0.0.0 interface xe-2/0/0.0
    set protocols ospf3 area 0.0.0.0 interface xe-2/0/1.0

    1. Chris

      As an addendum, I found another way to skin this cat that can still be cut and pasted between R1 and R2:

      Here is how I would alter the filter. Instead of:
      set firewall filter CONTROL-PLANE term OSPFv3 from source-prefix-list OSPF-ROUTERS

      Use the following:
      set firewall family inet6 filter CONTROL-PLANE term OSPFv3 from interface interface xe-2/0/0.0
      set firewall family inet6 filter CONTROL-PLANE term OSPFv3 from interface interface xe-2/0/1.0
      set firewall family inet6 filter CONTROL-PLANE term OSPFv3 from interface interface lo0.0

    2. Keeran Marquis Post Author

      thanks for added info and sharing 🙂
      if you are going to use apply-paths then you can also have something like protocols ospf3 area 0.0.0.0 interface <*> that would work too

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.