FWIW.CO.ZA

Blog of Christiaan Rademan.

JunOS Router Control plane protection

I recently had to build some filters for implementations and will be sharing them. The goal here is to provide an up-to-date example of a strong protection filtering for both IPv4 and IPV6 and to the address topic of why filters are required.

The topic of router security is fairly complex. So much so that the IETF has an informational RFC 6192 produced to outline best practices. The RFC includes examples for both IOS- and Junos based products.

Short introduction

Modern routers have the forwarding plane separated from the control plane and can forward millions+ of packets per second with ease. However that does not mean the control plane can handle those volumes. If the control plane is over-loaded, it will not able to send or receive routing protocol messages and other important control plane packets in a timely manner such as keep-alives. As a consequence loss of routing protocol adjacency can disrupt traffic flow though the forwarding plane.

Juniper carrier routers packet forwarding happens completely in hardware on the forwarding plane. The router consists of: a routing engine where all the protocols run and forwarding plane (PFE) which receives updates from the RE and programs forwarding functionality.

Since the Routing Engine does not handle packet forwarding its processing cannot be overwhelmed by packets that are supposed to be forwarded.

Firewall filters and policers in JunOS can be used to mitigate certain types of bad traffic that are destined to the router.

Attacks and prevention strategies

A form of denial of service attack on the control plane of routing equipment can lead to the scenario describe above.

There are many ways to protect your router and one of them not included in this post is filtering and policing on broadcast, multicast and unknown traffic. This known as a BUM filter that I may share in another post for Layer2 related networking.

Lastly in addition the Trio-based MX routers have additional DDoS detection features, which is for another post. However the filters provided is the required to be used in combination with other mechanisms to secure your infrastructure.

ARP Denial of Service

ARP request packets are sent to the broadcast MAC addresses while ARP replies are sent to the requested source mac. Improper configuration in the network causing broadcast storms could result in flooding of ARP packets to the routing engine. This could also be possible that a port receives lots of ARP requests and reply packets as part of DOS attack. Without protection these packets will all be sent to the routing engine.

By default Juniper routers have a policer for ARP packets that is shared by all interfaces on a line-card and the rate limits the aggregate ARP traffic to a value of 150Kbit/s.

The above default policer applied to ARP packets can be modified using hidden cli commands

firewall {
   arp-bandwidth-limit 32k;
   arp-burst-size-limit 2k;
}

Below is more aggressive configuration that can be applied on a per port basis. Its better in since one port being flooded does not impact the aggregate ports on the same line card.

groups {
   PROTECT-ARP {
       interfaces {
           <*> {
               unit <*> {
                   family inet {
                       policer {
                           arp ARP;
                       }
                   }
               }
           }
       }
       firewall {
           policer ARP {
               if-exceeding {
                   bandwidth-limit 8k;
                   burst-size-limit 1501;
               }
               then discard;
           }
       }
   }
}
firewall {
   apply-groups [ PROTECT-ARP ];
}

Note it could be applied either under physical for all logical interfaces or just under a specific logical interface using apply-groups PROTECT-ARP

Example of applying the above ARP policing to specific interface

interfaces {
   ge-0/0/0 {
       apply-groups PROTECT-ARP;
       description "NAP-AFRICA PEERING EXCHANGE";
       unit 0 {
           family inet {
               filter {
                   input-list [ RFC1918 MARTIANS BAD-PORTS ACCEPT ];
                   output-list [ RFC1918 MARTIANS BAD-PORTS ACCEPT ];
               }
               address 196.46.25.100/24;
           }
       }
   }
}

Malicious control plane traffic

The protection filter both for both IPV4 and IPV6 is combined within a simple apply-group to guard against resource depletion denial of service attacks and securing the access to specific protocols using filters. Using apply-groups the filters automatically are updated based on the configuration. For example if you add another BGP neighbor you do not have to add it to any specific prefix list.

However its required to specify core interfaces and mpls loopbacks and prefixes that do have access to the system via SSH or TELNET.

MPLS Loopbacks is used by unicast tcp LDP sessions for example.

groups {
   SECURE-RE {
       interfaces {
           lo0 {
               unit <*> {
                   family inet {
                       filter {
                           input SECURE-RE4;
                       }
                   }
                   family inet6 {
                       filter {
                           input SECURE-RE6;
                       }
                   }
               }
           }
       }
       policy-options {
           prefix-list RFC1918 {
               10.0.0.0/8;
               172.16.0.0/12;
               192.168.0.0/16;
           }
           prefix-list BGP-NEIGHBORS {
               apply-path "protocols bgp group <*> neighbor <*>";
           }
           prefix-list NTP-PEERS {
               apply-path "system ntp peer <*>";
           }
           prefix-list NTP-SERVER {
               apply-path "system ntp server <*>";
           }
           prefix-list NTP-BOOT-SERVER {
               apply-path "system ntp boot-server <*>";
           }
           prefix-list DNS-SERVERS {
               apply-path "system name-server <*>";
           }
           prefix-list INTERFACES-IPV4 {
               apply-path "interfaces <*> unit <*> family inet address <*>";
           }
           prefix-list LOOPBACKS-IPV4 {
               apply-path "interfaces lo0 unit <*> family inet address <*>";
           }
           prefix-list SNMP-CLIENT-LISTS {
               apply-path "snmp client-list <*> <*>";
           }
           prefix-list SNMP-COMMUNITY-CLIENTS {
               apply-path "snmp community <*> clients <*>";
           }
           prefix-list INTERFACES-IPV6 {
               apply-path "interfaces <*> unit <*> family inet6 address <*>";
           }
           prefix-list LOOPBACKS-IPV6 {
               apply-path "interfaces lo0 unit <*> family inet6 address <*>";
           }
       }
       firewall {
           family inet {
               filter SECURE-RE4 {
                   term FIRST-FRAGEMENT {
                       from {
                           first-fragment;
                       }
                       then {
                           discard;
                       }
                   }
                   term IS-FRAGMENT {
                       from {
                           is-fragment;
                       }
                       then {
                           discard;
                       }
                   }
                   term SYN-FLOOD {
                       from {
                           protocol tcp;
                           tcp-flags "(syn & !ack) | fin | rst ";
                       }
                       then {
                           policer TCP-INIT;
                           next term;
                       }
                   }
                   term RSVP {
                       from {
                           source-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           protocol rsvp;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term IP-OPTIONS {
                       from {
                           ip-options any;
                       }
                       then {
                           discard;
                       }
                   }
                   term SSH-TELNET {
                       from {
                           source-prefix-list {
                               SSH-TELNET4;
                           }
                           protocol tcp;
                           destination-port [ ssh telnet ];
                       }
                       then accept;
                   }
                   term SSH-TELNET-OUT {
                       from {
                           source-prefix-list {
                               SSH-TELNET4;
                           }
                           protocol tcp;
                           source-port [ ssh telnet ];
                           destination-port 1024-65535;
                       }
                       then accept;
                   }
                   term ICMP {
                       from {
                           protocol icmp;
                           icmp-type [ echo-request echo-reply unreachable time-exceeded source-quench timestamp timestamp-reply info-request info-reply ];
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term TRACEROUTE {
                       from {
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol udp;
                           ttl 1;
                           destination-port 33435-33450;
                       }
                       then {
                           policer TRACEROUTE;
                           accept;
                       }
                   }
                   term DNS {
                       from {
                           source-prefix-list {
                               DNS-SERVERS;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol udp;
                           source-port domain;
                       }
                       then {
                           policer DNS;
                           accept;
                       }
                   }
                   term NTP {
                       from {
                           source-prefix-list {
                               NTP-SERVER;
                               NTP-PEERS;
                               NTP-BOOT-SERVER;
                               LOOPBACKS-IPV4;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol udp;
                           destination-port ntp;
                       }
                       then {
                           policer NTP;
                           accept;
                       }
                   }
                   term NTP-LOCAL {
                       from {
                           source-prefix-list {
                               LOOPBACKS-IPV4;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol udp;
                           source-port ntp;
                       }
                       then {
                           policer NTP;
                           accept;
                       }
                   }
                   term SNMP {
                       from {
                           source-prefix-list {
                               SNMP-CLIENT-LISTS;
                               SNMP-COMMUNITY-CLIENTS;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol udp;
                           destination-port snmp;
                       }
                       then {
                           policer SNMP;
                           accept;
                       }
                   }
                   term OSPF {
                       from {
                           destination-address {
                               224.0.0.5/32;
                               224.0.0.6/32;
                           }
                           source-prefix-list {
                               INTERFACES-IPV4;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol ospf;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term BGP-IN {
                       from {
                           source-prefix-list {
                               BGP-NEIGHBORS;
                           }
                           protocol tcp;
                           destination-port bgp;
                       }
                       then accept;
                   }
                   term BGP-OUT {
                       from {
                           source-prefix-list {
                               BGP-NEIGHBORS;
                           }
                           protocol tcp;
                           source-port bgp;
                           destination-port 1024-65535;
                       }
                       then accept;
                   }
                   term VRRP {
                       from {
                           destination-address {
                               224.0.0.18/32;
                           }
                           source-prefix-list {
                               INTERFACES-IPV4;
                           }
                           protocol vrrp;
                       }
                       then {
                           policer VRRP;
                           accept;
                       }
                   }
                   term LDP {
                       from {
                           destination-address {
                               224.0.0.2/32;
                           }
                           source-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           protocol udp;
                           destination-port ldp;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term LDP-UNICAST {
                       from {
                           source-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           protocol tcp;
                           port ldp;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term TLDP-DISCOVER {
                       from {
                           destination-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           protocol udp;
                           destination-port ldp;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term LDP-IGMP {
                       from {
                           destination-address {
                               224.0.0.2/32;
                           }
                           source-prefix-list {
                               INTERFACES-IPV4;
                               MPLS-LOOPBACKS;
                           }
                           protocol igmp;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term OTHER {
                       then {
                           log;
                           discard;
                       }
                   }
               }
           }
           family inet6 {
               filter SECURE-RE6 {
                   /* Beware - VRRPv3 with authentication or OSPFv3 with Authentication enabled may use AH/ESP */
                   term DISCARD-EXTENSION-HEADERS {
                       from {
                           next-header [ ah dstopts egp esp fragment gre icmp igmp ipip ipv6 no-next-header routing rsvp sctp ];
                       }
                       then discard;
                   }
                   term SYN-FLOOD {
                       from {
                           next-header tcp;
                           tcp-flags "(syn & !ack) | fin | rst ";
                       }
                       then {
                           policer TCP-INIT;
                           next term;
                       }
                   }
                   term NEIGBOR-DISCOVERY {
                       from {
                           next-header icmpv6;
                           icmp-type 133-136;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term INVERSE-NEIGHBOR-DISCOVERY {
                       from {
                           next-header icmpv6;
                           icmp-type 141-142;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-DEST-UNREACHABLE {
                       from {
                           next-header icmpv6;
                           icmp-type destination-unreachable;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-PACKET-TOO-BIG {
                       from {
                           next-header icmpv6;
                           icmp-type packet-too-big;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-TIME-EXCEEEDED {
                       from {
                           next-header icmpv6;
                           icmp-type time-exceeded;
                           icmp-code 0;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-ECHO-REPLY {
                       from {
                           next-header icmpv6;
                           icmp-type echo-reply;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-ECHO-REQUEST {
                       from {
                           next-header icmpv6;
                           icmp-type echo-request;
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term ICMP-PARAMTER-PROBLEM {
                       from {
                           next-header icmpv6;
                           icmp-type parameter-problem;
                           icmp-code [ 1 2 ];
                       }
                       then {
                           policer ICMP;
                           accept;
                       }
                   }
                   term DNS {
                       from {
                           source-prefix-list {
                               DNS-SERVERS;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV6;
                           }
                           next-header [ udp tcp ];
                           source-port domain;
                       }
                       then {
                           policer DNS;
                           accept;
                       }
                   }
                   term NTP {
                       from {
                           source-prefix-list {
                               NTP-BOOT-SERVER;
                               NTP-PEERS;
                               LOOPBACKS-IPV6;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV6;
                           }
                           next-header udp;
                           destination-port ntp;
                       }
                       then {
                           policer NTP;
                           accept;
                       }
                   }
                   term NTP-LOCAL {
                       from {
                           source-prefix-list {
                               LOOPBACKS-IPV6;
                           }
                           destination-prefix-list {
                               INTERFACES-IPV6;
                           }
                           next-header udp;
                           source-port ntp;
                       }
                       then {
                           policer NTP;
                           accept;
                       }
                   }
                   term SSH-TELNET {
                       from {
                           source-prefix-list {
                               SSH-TELNET6;
                           }
                           next-header tcp;
                           destination-port [ ssh telnet ];
                       }
                       then accept;
                   }
                   term TRACEROUTE {
                       from {
                           destination-prefix-list {
                               INTERFACES-IPV6;
                           }
                           next-header udp;
                           destination-port 33435-33450;
                           hop-limit 1;
                       }
                       then {
                           policer TRACEROUTE;
                           accept;
                       }
                   }
                   term OSPF3 {
                       from {
                           source-address {
                               fe80::/64;
                           }
                           next-header ospf;
                           interface-set CORE;
                       }
                       then accept;
                   }
                   term BGP-IN {
                       from {
                           source-prefix-list {
                               BGP-NEIGHBORS;
                           }
                           next-header tcp;
                           destination-port bgp;
                       }
                       then accept;
                   }
                   term BGP-OUT {
                       from {
                           source-prefix-list {
                               BGP-NEIGHBORS;
                           }
                           next-header tcp;
                           source-port bgp;
                           destination-port 1024-65535;
                       }
                       then accept;
                   }
                   term OTHER {
                       then discard;
                   }
               }
           }
           policer TCP-INIT {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer ICMP {
               if-exceeding {
                   bandwidth-limit 2m;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer TRACEROUTE {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer DNS {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer NTP {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer SNMP {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer VRRP {
               if-exceeding {
                   bandwidth-limit 500k;
                   burst-size-limit 1501;
               }
               then discard;
           }
           policer NON-IP {
               if-exceeding {
                   bandwidth-limit 250k;
                   burst-size-limit 1501;
               }
               then discard;
           }
       }
   }
}

Example of applying SECURE-RE Filter

apply-groups [ SECURE-RE ];
firewall {
   interface-set CORE {
       et-0/0/0.0;
       et-0/0/1.0;
   }
}
policy-options {
   prefix-list SSH-TELNET4 {
       127.0.0.1/32;
   }
   prefix-list MPLS-LOOPBACKS {
       10.10.10.0/24
   }
   prefix-list SSH-TELNET6 {
       ::1/128;
   }
}