Routers and Firewalls

UQCS

Oct 12, 2015

me

  • dlg@openbsd.org
  • dlg@uq.edu.au

why?

  • appliances are terrible
  • appliance dev/support stops when the product ships
  • appliances are opaque
  • to learn
  • to do cool things

routers

  • routers are network peers who forward traffic
  • routers only look at the destination address
  • decide where the destination is by a route lookup
  • simply send the packet on
  • everything else is a host and terminates traffic

routers

  • your adsl gateway+access point+switch thing
  • the box(es) between all the faculty networks

firewalls

  • a layer outside the traditional network stack or devices
  • implements network policy
  • drop or modify packets
  • modifications can include NAT
  • ...or just let them go through

firewalls

  • your computers have firewalls
  • your phones have firewalls
  • your router at home is also a firewall

openbsd

  • a general purpose unix-like operating system
  • long focus on correctness and security
  • long history in network facing roles
  • routing, pf, ppp/pppoe, dhcp/dhcpd, etc, etc

openbsd network stack

  • packet reception (network driver)
  • ip input
  • ip stack (sockets or routing)
  • ip output
  • packet transmission (network driver)

pf

  • packet filter
  • code in the kernel
    • stores policy (rules)
    • stores state
    • code to apply policy
  • userland control tool
    • human readable ruleset
    • supports macros
    • parses and translates ruleset to kernel
    • monitoring/inspection

pf

  • rules basically say "yes" or "no" to packets based on their properties
  • properties include which interface, address family, src/dst ip addresses, ip protocol, tcp/udp ports, os, flags, user/group, etc
  • last matching rule wins, unless "quick"
  • rules can modify packets
  • can modify src/dst ips/ports, routing, logging, labels, prio, queueing, etc
  • block in on em0 inet proto udp from any to 192.168.0.1
    pass out quick on em0 inet proto tcp to any port http
    

    openbsd network stack with pf

    • packet reception (network driver)
    • ip input
    • pf (inbound)
    • ip stack (sockets or routing)
    • pf (outbound)
    • ip output
    • packet transmission (network driver)

    home gateway

    • using mine as a reference
    • adsl
    • wifi
    • wired ethernet
    • nat for v4
    • dns+dhcp
    • v6 tunnels from aarnet

    the router

    • a computer with multiple network cards
    • ive used an 486 DX2, p1, IPX, ultra 10, graphite mac, routerboard rb400, alix, intel nas
    • now a dell desktop
    • draytek vigor 130 adsl modem
    • ubiquiti unifi AP
    • switches for 2 or 3 wired devs

    getting on the internet

    • pppoe(4)
    • annoying magic for negotiated addresses and routes
    dlg@apathy ~$ sudo cat /etc/hostname.pppoe0
    inet 0.0.0.0 255.255.255.255 NONE \
    	pppoedev vlan3 authproto pap \
    	authname 'dgwynne@l2tp.tpg.com.au' authkey 'lolz' up \
    	group external
    dest 0.0.0.1
    !/sbin/route add default -ifp pppoe0 0.0.0.1
    	
    dlg@apathy ~$ sudo /etc/netstart pppoe0
    dlg@apathy ~$ ifconfig pppoe0
    pppoe0: flags=28851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST,NOINET6> mtu 1492
            priority: 0
            dev: vlan3 state: session
            sid: 0xaa0d PADI retries: 25 PADR retries: 0 time: 12:18:50
            sppp: phase network authproto pap 
            groups: pppoe external egress
            status: active
            inet 60.241.41.69 --> 10.20.21.72 netmask 0xffffffff
    dlg@apathy ~$ route -n get default
       route to: default
    destination: default
           mask: default
        gateway: 10.20.21.72
      interface: pppoe0
     if address: 60.241.41.69
       priority: 8 (static)
          flags: 
         use       mtu    expire
    23397073         0         0 
    	

    inside the network

    • everything on a single l3 network
    • AP bridges it to wifi
    dlg@apathy ~$ sudo cat /etc/hostname.em0
    inet 10.0.127.1 255.255.255.0 NONE 
    inet alias 10.0.127.15 255.255.255.255
    inet6 2001:388:e000:ba00:7c06:2e08:93a0:95b8 64
    group internal
    	
    dlg@apathy etc$ ifconfig em0
    em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
            lladdr b8:ac:6f:9c:af:d9
            priority: 0
            groups: internal
            media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause)
            status: active
            inet 10.0.127.1 netmask 0xffffff00 broadcast 10.0.127.255
            inet 10.0.127.15 netmask 0xffffffff
            inet6 fe80::baac:6fff:fe9c:afd9%em0 prefixlen 64 scopeid 0x1
            inet6 2001:388:e000:ba00:7c06:2e08:93a0:95b8 prefixlen 64
    

    routing

    • off by default
    dlg@apathy etc$ grep ^net.*forwarding /etc/sysctl.conf
    net.inet.ip.forwarding=1        # 1=Permit forwarding (routing) of IPv4 packets
    net.inet6.ip6.forwarding=1      # 1=Permit forwarding (routing) of IPv6 packets
    

    NAT

    • nat was invented after the ip stack
    • implemented in firewalls
    • pf.conf:
    # default action is pass
    match on pppoe0 scrub (max-mss 1452)
    match out on pppoe0 nat-to (pppoe0)
    
    • pf is on by default
    • load new rules
    dlg@apathy etc$ sudo pfctl -f /etc/pf.conf
    dlg@apathy etc$ sudo pfctl -sr
    match on pppoe0 all scrub (max-mss 1452)
    match out on pppoe0 all nat-to (pppoe0) round-robin
    

    testing

    dlg@powermon:~$ ping -c 4 www.google.com
    PING www.google.com (216.58.220.132) 56(84) bytes of data.
    64 bytes from syd09s01-in-f132.1e100.net (216.58.220.132): icmp_req=1 ttl=56 time=39.6 ms
    64 bytes from syd09s01-in-f4.1e100.net (216.58.220.132): icmp_req=2 ttl=56 time=63.1 ms
    64 bytes from syd09s01-in-f132.1e100.net (216.58.220.132): icmp_req=3 ttl=56 time=67.4 ms
    64 bytes from syd09s01-in-f4.1e100.net (216.58.220.132): icmp_req=4 ttl=56 time=55.2 ms
    
    --- www.google.com ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3002ms
    rtt min/avg/max/mdev = 39.641/56.352/67.416/10.594 ms
    dlg@powermon:~$ traceroute -n www.google.com
    traceroute to www.google.com (216.58.220.132), 30 hops max, 60 byte packets
     1  10.0.127.1  0.475 ms  0.393 ms  0.464 ms
     2  10.20.21.72  27.622 ms  28.493 ms  29.941 ms
     3  203.219.166.66  38.244 ms  38.093 ms  37.971 ms
     4  203.219.35.70  45.181 ms  45.268 ms  46.679 ms
     5  203.219.107.6  45.257 ms  46.378 ms  47.548 ms
     6  216.239.51.218  48.187 ms  51.020 ms  53.081 ms
     7  216.239.46.151  54.052 ms * *
     8  216.58.220.132  97.535 ms  93.850 ms  102.969 ms
    
    dlg@powermon:~$ uname -ap
    Linux powermon 3.8.13-bone26 #1 SMP Fri Aug 16 20:56:24 UTC 2013 armv7l GNU/Linux
    dlg@powermon:~$ /sbin/ifconfig
    eth0      Link encap:Ethernet  HWaddr d4:94:a1:98:b4:27  
              inet addr:10.0.127.8  Bcast:10.0.127.255  Mask:255.255.255.0
              inet6 addr: fe80::d694:a1ff:fe98:b427/64 Scope:Link
              inet6 addr: 2001:388:e000:ba00:d694:a1ff:fe98:b427/64 Scope:Global
              UP BROADCAST RUNNING ALLMULTI MULTICAST  MTU:1500  Metric:1
              RX packets:1002356 errors:0 dropped:180694 overruns:0 frame:0
              TX packets:615284 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:177816801 (169.5 MiB)  TX bytes:101462197 (96.7 MiB)
              Interrupt:56 
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:18 errors:0 dropped:0 overruns:0 frame:0
              TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:1904 (1.8 KiB)  TX bytes:1904 (1.8 KiB)
    

    dhcp

    dlg@apathy etc$ sudo cat /etc/dhcpd.conf
    # DHCP server options.
    # See dhcpd.conf(5) and dhcpd(8) for more information.
    
    option  domain-name "home.animata.net";
    option  domain-name-servers 10.0.127.1;
    
    subnet 10.0.127.0 netmask 255.255.255.0 {
            option routers 10.0.127.1;
            range 10.0.127.192 10.0.127.223;
    
            host xbmc {
                    hardware ethernet ec:a8:6b:fb:2d:59;
                    fixed-address xbmc.home.animata.net;
            }
            host powermon {
                    hardware ethernet d4:94:a1:98:b4:27;
                    fixed-address powermon.home.animata.net;
            }
    }
    dlg@apathy ~$ sudo rcctl set dhcpd flags em0
    dlg@apathy ~$ sudo rcctl enable dhcpd
    dlg@apathy ~$ sudo rcctl start dhcpd
    dhcpd(ok)
    

    dns

    • im still using bind
    • bind was replaced with nsd and unbound in base
    • use unbound as a local caching resolver

    unbound.conf

    dlg@apathy ~$ sudo cat /var/unbound/etc/unbound.conf
    ## Simple recursive caching DNS
    #
    server:
    	interface: 0.0.0.0
    	access-control: 10.0.127.0/24 allow
    	interface: ::0
    	access-control: 2001:388:e000:ba00::/64 allow
    	local-zone: "home.animata.net." static
    	local-data: "router.home.animata.net. IN A 10.0.127.1"
    	local-data-ptr: "10.0.127.1 router.home.animata.net."
    	local-data: "powermon.home.animata.net. IN A 10.0.127.8"
    	local-data-ptr: "10.0.127.8 powermon.home.animata.net."
    	# etc etc + v6 shizz
    
    forward-zone:
    	name: "."
    	forward-addr: 8.8.8.8
    	forward-addr: 8.8.4.4
    dlg@apathy ~$ sudo rcctl enable unbound
    dlg@apathy ~$ sudo rcctl start unbound
    unbound(ok)
    

    v6 tunnels

    dlg@apathy ~$ sudo cat /etc/hostname.gif0
    inet6 2001:388:f000::13a5 128 2001:388:f000::13a4 prefixlen 128 group external
    tunnel 60.241.41.69 202.158.196.131
    !/sbin/route -q add -inet6 default 2001:388:f000::13a4
    dlg@apathy ~$ ifconfig gif0
    gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
            priority: 0
            groups: gif external egress
            tunnel: inet 60.241.41.69 -> 202.158.196.131
            inet6 2001:388:f000::13a5 -> 2001:388:f000::13a4 prefixlen 128
            inet6 fe80::baac:6fff:fe9c:afd9%gif0 ->  prefixlen 64 scopeid 0x6
    
    dlg@apathy ~$ ping6 -c 4 www.google.com
    PING6(56=40+8+8 bytes) 2001:388:f000::13a5 --> 2404:6800:4006:800::2004
    16 bytes from 2404:6800:4006:800::2004, icmp_seq=0 hlim=56 time=232.194 ms
    16 bytes from 2404:6800:4006:800::2004, icmp_seq=1 hlim=56 time=239.131 ms
    16 bytes from 2404:6800:4006:800::2004, icmp_seq=2 hlim=54 time=263.988 ms
    16 bytes from 2404:6800:4006:800::2004, icmp_seq=3 hlim=56 time=193.882 ms
    
    --- www.google.com ping6 statistics ---
    4 packets transmitted, 4 packets received, 0.0% packet loss
    round-trip min/avg/max/std-dev = 193.882/232.299/263.988/25.133 ms
    dlg@apathy ~$ traceroute6 -nI www.google.com
    traceroute6 to www.google.com (2404:6800:4006:800::2004), 64 hops max, 60 byte packets
     1  2001:388:f000::13a4  59.714 ms  68.968 ms  60.796 ms
     2  2001:388:1:5001::1  74.159 ms  65.797 ms  91.692 ms
     3  * 2001:388:1:d:212:1eff:fe90:7000  90.885 ms  78.907 ms
     4  2001:388:1:92::1  47.926 ms  64.653 ms  63.123 ms
     5  2001:388:1:93::2  68.632 ms  67.87 ms  113.412 ms
     6  2001:388:1:94::2  74.774 ms  74.89 ms  107.967 ms
     7  2001:388:1:30::2  242.293 ms  234.007 ms  191.987 ms
     8  2001:504:13::210:41  192.402 ms  187.435 ms  221.367 ms
     9  2001:4860::1:0:6b01  196.793 ms  192.119 ms  206.846 ms
    10  * 2001:4860::8:0:7a19  187.946 ms  199.53 ms
    11  2001:4860::1:0:8604  252.188 ms  247.727 ms  202.372 ms
    12  2001:4860:0:1::1253  191.951 ms *  232.709 ms
    13  2404:6800:4006:800::2004  220.165 ms  227.037 ms  225.401 ms
    

    more realistic pf.conf

    set skip on lo0
    
    _h_thinmac="10.0.127.66 2001:388:e000:ba00:6aa8:6dff:fe0e:f56c"
    h_thinmac="{" $_h_thinmac "}"
    h_home="60.241.41.69"
    h_aarnet_broker="202.158.196.131"
    
    match on pppoe0 scrub (max-mss 1452)
    match on gif0 scrub (max-mss 1024)
    match out on pppoe0 nat-to (pppoe0)
    
    block log # default policy
    
    pass in quick on pppoe0 inet proto ipv6 from $h_aarnet_broker to $h_home
    
    pass inet proto icmp all icmp-type echoreq
    pass inet6 proto icmp6 all icmp6-type echoreq
    pass on internal
    pass out on external
    
    pass in quick on pppoe0 inet  proto { tcp udp } to $h_home port 51416 rdr-to $h_thinmac keep state (max 128)
    pass in quick on gif0   inet6 proto { tcp udp } to port 51416
    pass in quick on external proto { tcp udp } to (external) port 51413:51414
    pass in quick proto tcp to (external) port { ssh }
    

    pf in eait

    • pair of dell R720s in active+passive config
    • redundant OSPF paths to ITS
    • dual myx(4) 10G cards in a trunk(4)
    • 70-80 vlan(4) interfaces on top of the trunk
    • 80+ carp(4) interfaces
    • ~2000 line pf.conf which becomes ~3400 rules

    interface groups

    • most eait networks are for clients in buildings buildings
    • ~15 buildings, each with staff, labs, services, experiments, avkit
    • interfaces are assigned to groups based on type
    • pf filters on the groups, not individual interfaces

    received-on

    • openbsd records which interface packets arrived on
    • pf can filter on that
    • pass out on $staff_servers from any received-on staff

    logging

    • default rule is block log
    • blocked packets appear on pflog0
    • can use tcpdump to see whats blocked live
    • pflogd writes a pcap file you can read afterward

    questions?

    i'm on irc