Routing with Linux 'cause you really love the command line Jim Salter Technomancer, Mercenary Sysadmin, Small Business Owner Today's slides can be found at: http://openoid.net/presentations/ This presentation is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. (C) 2015 jim@openoid.net
super techie sysadmin crap ahead. WARNING: super techie sysadmin crap ahead. proceed at own risk
What's in one of these, anyway? At a minimum: DHCP server DNS server router (lol) firewall NAT
One of these kids is not like the others...
Performance Reliability Flexibility Security Mastery Why Linux? Why bare? Performance Reliability Flexibility Security Mastery
Which Linux? Ubuntu. if you don't like it, write your own “how to build a Linux router” presentation
stripped down clean CLI apt packages predictable LTS seriously, why Ubuntu? stripped down clean CLI apt packages predictable LTS
But I like a GUI ='( X then try an x86 build of DD-WRT! =) --------------------------------------------------
But I like a GUI ='( then try an x86 build of pfSense! =)
Performance, you say? yes, performance =)
Overview * configure network interfaces * enable IP forwarding in /etc/sysctl.conf * enable DHCP service with isc-dhcp-server * enable DNS service with bind9 * set up NAT with iptables masquerade * set up firewall rules with iptables
configure interfaces # /etc/network/interfaces # loopback interface auto lo iface lo inet loopback # The WAN interface (marked LAN1 on the case) auto p4p1 iface p4p1 inet dhcp # The LAN interface (marked LAN2 on the case) auto p1p1 iface p1p1 inet static address 192.168.99.1 netmask 255.255.255.0
enable ipv4 forwarding you@box:~$ sudo nano /etc/sysctl.conf # Uncomment the next line to enable # packet forwarding for IPv4 #net.ipv4.ip_forward=1 you@box:~$ sudo sysctl -p
dhcp and dns you@box:~$ sudo apt-get update you@box:~$ sudo apt-get install isc-dhcp-server you@box:~$ sudo apt-get install bind9 # /etc/dhcp/dhcpd.conf subnet 192.168.99.0 netmask 255.255.255.0 { range 192.168.99.100 192.168.99.199; option routers 192.168.99.1; option domain-name-servers 192.168.99.1; option broadcast-address 192.168.99.255; } you@box:~$ sudo /etc/init.d/isc-dhcp-server restart
startup script you@box:~$ \ sudo touch /etc/network/if-pre-up.d/iptables; sudo chmod 755 /etc/network/if-pre-up.d/iptables #!/bin/sh # this is /etc/network/if-pre-up.d/iptables # it starts the firewall immediately prior # to any network interface coming online. /sbin/iptables-restore << EOF # rules go here EOF
If it doesn't end with COMMIT, your ruleset won't parse! iptables anatomy This is a table. It begins with its *name and the default policies for its :chains. *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT If it doesn't end with COMMIT, your ruleset won't parse!
skeleton iptables *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT *filter :FORWARD ACCEPT [0:0] # Service rules -A INPUT -j DROP # Forwarding rules -A FORWARD -j DROP
the *nat table *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] # p4p1 is WAN interface, p1p1 is LAN interface -A POSTROUTING -o p4p1 -j MASQUERADE COMMIT
*filter table - srv rules :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] # basic global accept - ICMP, loopback, traceroute, established -A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -m state --state ESTABLISHED -j ACCEPT # enable traceroute rejections to get sent out -A INPUT -p udp -m udp --dport 33434:33523 -j REJECT --reject-with icmp-port-unreachable # DNS, SSH, DHCP client requests - accept from LAN -A INPUT -i p1p1 -p tcp --dport 53 -j ACCEPT -A INPUT -i p1p1 -p udp --dport 53 -j ACCEPT -A INPUT -i p1p1 -p tcp --dport 22 -j ACCEPT -A INPUT -i p1p1 -p udp --dport 67:68 -j ACCEPT # drop all other inbound traffic -A INPUT -j DROP
*filter section - forwarding # Forwarding rules # forward packets along established/related connections -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # forward from LAN (p1p1) to WAN (p4p1) -A FORWARD -i p1p1 -o p4p1 -j ACCEPT # drop all other forwarded traffic -A FORWARD -j DROP COMMIT
port forwarding # pinholes go in *nat table before its COMMIT! # NAT pinhole: HTTP from WAN to LAN -A PREROUTING -p tcp -m tcp -i p4p1 --dport 80 -j DNAT --to-destination 192.168.99.100:80 # the matching forward rules go in *filter table # before its COMMIT! # forwarded traffic from our NAT pinhole -A FORWARD -p tcp -d 192.168.99.100 --dport 80 -j ACCEPT
ha, ha, you can't read this #!/bin/sh # This is /etc/network/if-pre-up.d/iptables. It starts the firewall immediately prior to any network interface coming online. WAN=p4p1 LAN=p1p1 /sbin/iptables-restore << EOF *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] -A POSTROUTING -o $WAN -j MASQUERADE # NAT pinhole: HTTP from WAN to LAN -A PREROUTING -p tcp -m tcp -i $WAN --dport 80 -j DNAT --to-destination 192.168.99.100:80 COMMIT *filter :FORWARD ACCEPT [0:0] # Service rules # basic global accept rules - ICMP, loopback, traceroute, established all accepted -A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -m state --state ESTABLISHED -j ACCEPT # enable traceroute rejections to get sent out -A INPUT -p udp -m udp --dport 33434:33523 -j REJECT --reject-with icmp-port-unreachable # DNS - accept from LAN -A INPUT -i $LAN -p tcp --dport 53 -j ACCEPT -A INPUT -i $LAN -p udp --dport 53 -j ACCEPT # SSH - accept from LAN -A INPUT -i $LAN -p tcp --dport 22 -j ACCEPT # DHCP client requests - accept from LAN -A INPUT -i $LAN -p udp --dport 67:68 -j ACCEPT # drop all other inbound traffic -A INPUT -j DROP # Forwarding rules # forward packets along established/related connections -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # forward from LAN (p1p1) to WAN (p4p1) -A FORWARD -i $LAN -o $WAN -j ACCEPT # allow traffic from our NAT pinhole -A FORWARD -p tcp -d 192.168.99.100 --dport 80 -j ACCEPT # drop all other forwarded traffic -A FORWARD -j DROP EOF
Questions? Comments? Angry denunciations?