openbsd-gateway.md (10931B)
1 ### Setting up a home gateway with OpenBSD + other goodies 2 3 If you have a spare box with two or more NICs, you can turn it into a powerful OpenBSD router. 4 In this tutorial, I will walk you through my gateway configuration. 5 6 **Remember! Do not blindly copy paste the configuration files!** 7 8 ### Available hardware and network layout 9 10 My router is a [Shuttle XH81V](http://global.shuttle.com/main/productsDetail?productId=1823). It has two Realtek 11 NICs. 12 13 I have a single local subnet, 10.0.0.0/24. 14 15 Because of lack of additional NICs or a [VLAN](https://en.wikipedia.org/wiki/Virtual_LAN) capable switch, 16 there is no [DMZ](https://en.wikipedia.org/wiki/DMZ_%28computing%29). 17 To avoid exposing many services to the outside, I typically use ssh tunneling or a VPN 18 to access local services behind the gateway. 19 20 I have a dedicated server hosted in a DC. I use [tinc](http://www.tinc-vpn.org/) in a bridged mode 21 configuration to make the server appear on my local subnet. This way, I can access the server transparently even on 22 machines on my local network that I cannot install tinc to. 23 24 For IPv6, I use a [Hurricane Electric](https://tunnelbroker.net/) tunnel. Their service has proven reliable 25 with virtually no downtime experienced in the past year. 26 27 ### Topics covered 28 29 The following topics will be discussed: 30 31 * Firewall, routing and NAT configuration 32 * DHCP server configuration 33 * Split horizon DNS + dnscrypt_proxy 34 * PXE booting 35 * Configuring an IPv6 gif(4) tunnel with Hurricane Electric 36 * NetFlow sensor and collector configuration 37 * Debugging tips 38 39 ### Firewall, routing and NAT configuration 40 41 There is an excellent [tutorial](http://www.openbsd.org/faq/pf/example1.html) in the pf FAQ. 42 Fore more information, check the [pf.conf(5)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/pf.conf.5), 43 [hostname.if(5)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/hostname.if.5) and 44 [ifconfig(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/ifconfig.8) manpages. 45 46 #### /etc/pf.conf 47 48 int_if = "re1" 49 sshbox = "10.0.0.2" 50 martians = "{ 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 \ 51 169.254.0.0/16 172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 \ 52 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \ 53 224.0.0.0/4 240.0.0.0/4 255.255.255.255/32 }" 54 55 set loginterface egress 56 set skip on lo0 57 set block-policy return 58 59 match in all scrub (no-df random-id) 60 61 match out on egress inet from !(egress:network) to any nat-to (egress:0) 62 63 block drop in quick on egress from { no-route urpf-failed $martians } 64 block return out quick on egress to $martians 65 block 66 67 pass in on $int_if 68 pass in on egress inet proto icmp to (egress) 69 pass in on egress inet proto tcp to (egress) port ssh rdr-to $sshbox 70 pass out 71 72 #### /etc/sysctl.conf 73 74 net.inet.ip.forwarding=1 75 76 #### /etc/hostname.re0 77 78 description "WAN" 79 dhcp 80 81 #### /etc/hostname.re1 82 83 description "LAN" 84 inet 10.0.0.1 255.255.255.0 10.0.0.255 85 up 86 87 Reboot the router. This isn't required but it is a good idea to test that your changes 88 are correctly set after a fresh boot. 89 90 ### DHCP server configuration 91 92 I use [2f30.org](https://2f30.org) as the default search domain. I have a [split horizon DNS](https://en.wikipedia.org/wiki/Split-horizon_DNS) 93 configuration so I can access my machines from my local network as well as from the outside. 94 95 #### /etc/dhcpd.conf 96 97 option domain-name "2f30.org"; 98 option domain-name-servers 10.0.0.1; 99 100 subnet 10.0.0.0 netmask 255.255.255.0 { 101 option routers 10.0.0.1; 102 range 10.0.0.32 10.0.0.127; 103 104 host sshbox { 105 hardware ethernet aa:bb:cc:dd:ee:ff; 106 fixed-address 10.0.0.2; 107 } 108 } 109 110 Update /etc/rc.conf.local: 111 112 dhcpd_flags="re1" 113 114 Restart dhcpd: 115 116 /etc/rc.d/dhcpd restart 117 118 ### Split horizon DNS 119 120 I am using unbound(8) as a caching DNS resolver. 121 122 #### /var/unbound/etc/unbound.conf 123 124 server: 125 interface: 10.0.0.1 126 access-control: 10.0.0.0/24 allow 127 128 local-data: "gw.2f30.org. IN A 10.0.0.1" 129 local-data-ptr: "10.0.0.1 gw.2f30.org." 130 131 local-data: "sshbox.2f30.org. IN A 10.0.0.2" 132 local-data-ptr: "10.0.0.2 sshbox.2f30.org." 133 134 forward-zone: 135 name: "." 136 forward-addr: 208.67.222.222 137 forward-addr: 208.67.220.220 138 139 Update /etc/rc.conf.local: 140 141 unbound_flags= 142 143 Restart unbound: 144 145 /etc/rc.d/unbound restart 146 147 At this point, you should be able to plug a machine to your switch, get an IP address 148 and browse the web. 149 150 You should also be able to access $sshbox from the outside over ssh on the default port. 151 In my configuration this is a separate machine but could just as well be the router itself. 152 153 ### Using dnscrypt_proxy with unbound 154 155 First install dnscrypt_proxy from packages. 156 157 Adjust /etc/rc.conf.local: 158 159 dnscrypt_proxy_flags="-l /dev/null -R dnscrypt.eu-nl -a 127.0.0.1:53" 160 pkg_scripts="dnscrypt_proxy" 161 162 Start it: 163 164 /etc/rc.d/dnscrypt_proxy start 165 166 Then adjust the unbound configration: 167 168 #### /var/unbound/etc/unbound.conf 169 170 server: 171 interface: 10.0.0.1 172 access-control: 10.0.0.0/24 allow 173 do-not-query-localhost: no # needed as dnscrypt is listening on localhost 174 175 local-data: "gw.2f30.org. IN A 10.0.0.1" 176 local-data-ptr: "10.0.0.1 gw.2f30.org." 177 178 local-data: "sshbox.2f30.org. IN A 10.0.0.2" 179 local-data-ptr: "10.0.0.2 sshbox.2f30.org." 180 181 forward-zone: 182 name: "." 183 forward-addr: 127.0.0.1 184 forward-addr: 208.67.220.220 185 186 Restart unbound: 187 188 /etc/rc.d/unbound restart 189 190 You should use [tcpdump(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/tcpdump.8) 191 to confirm that DNS requests are encrypted. 192 193 ### PXE booting 194 195 I use PXE booting on my laptop to upgrade OpenBSD. I run a tftp server on my router 196 to serve the latest bsd.rd. 197 198 #### Setting up tftpd and dhcpd for PXE booting 199 200 Prepare /tftpboot: 201 202 mkdir /tftpboot 203 cp /usr/mdec/pxeboot /tftpboot 204 205 Update /etc/dhcpd.conf: 206 207 subnet 10.0.0.0 netmask 255.255.255.0 { 208 filename "pxeboot"; 209 next-server 10.0.0.1; 210 ... 211 } 212 213 Update /etc/rc.conf.local: 214 215 tftpd_flags="-l 10.0.0.1 /tftpboot" 216 217 Restart dhcpd and tftpd: 218 219 /etc/rc.d/tftpd restart 220 /etc/rc.d/dhcpd restart 221 222 #### Cron job to fetch latest bsd.rd 223 224 Use crontab -e as root to add a new job as follows: 225 226 15 10 * * * /usr/bin/ftp -o /tftpboot/bsd.rd http://ftp.openbsd.org/pub/OpenBSD/snapshots/amd64/bsd.rd 1>/dev/null 227 228 It will download bsd.rd once a day at 10:15 in the morning. 229 230 To test, plug your laptop to the switch and choose to boot over the network. Once you get to the OpenBSD 231 boot prompt, type /bsd.rd and hit return. 232 233 ### Configuring an IPv6 gif(4) tunnel with Hurricane Electric 234 235 First of all, you will have to create an account on their [website](https://tunnelbroker.net). From there, 236 follow their guide to set up a tunnel. You will basically have to choose the tunnel endpoint. Find the one 237 with the minimum latency. 238 239 #### /etc/sysctl.conf 240 241 net.inet6.ip6.forwarding=1 242 243 #### /etc/hostname.gif0 244 245 description "Hurricane Electric 6in4 link" 246 tunnel <your-ipv4-endpoint> <their-ipv4-endpoint> 247 mtu 1480 248 !ifconfig gif0 inet6 alias 2001:XXXX:XXXX:XXXX::2 2001:XXXX:XXXX:XXXX::1 prefixlen 128 249 !route -n add -inet6 default 2001:XXXX:XXXX:XXXX::1 250 251 #### /etc/hostname.re1 252 253 inet6 alias 2001:XXXX:XXXX:XXXX::1 64 254 255 This will add an IPv6 alias on your router's internal interface. 256 257 #### /etc/pf.conf 258 259 pass in on egress inet proto 41 from <their-ipv4-endpoint> to (egress) 260 pass in on gif0 inet6 261 262 Update /etc/rc.conf.local: 263 264 rtadvd_flags="re1" 265 266 Reboot your router. 267 268 On your OpenBSD client, enable autoconfiguration: 269 270 ifconfig em0 inet6 autoconf 271 272 ### NetFlow sensor and collector configuration 273 274 I use [NetFlow](https://en.wikipedia.org/wiki/NetFlow) to get an idea of what kind of traffic passes through my gateway. 275 276 To configure a netflow sensor on the gateway: 277 278 #### /etc/pf.conf 279 280 set state-defaults pflow 281 282 #### /etc/hostname.pflow0 283 flowsrc 10.0.0.1 flowdst 10.0.0.2:5555 284 285 Activate sensor: 286 287 pfctl -f /etc/pf.conf 288 sh /etc/netstart pflow0 289 290 On the receiver, in this case the box with address 10.0.0.2 we'll install [flowd](http://www.mindrot.org/files/flowd/README). It is a secure and minimal 291 netflow collector written by Damien Miller. 292 293 First, install flowd from ports. 294 295 #### /etc/flowd.conf 296 297 logfile "/var/log/flowd" 298 listen on 10.0.0.2:5555 299 flow source 10.0.0.1 300 store ALL 301 302 Restart flowd: 303 304 /etc/rc.d/flowd restart 305 306 Give it a moment and use flowd-reader(8) on the specified logfile to examine the flows. 307 308 ### Debugging tips 309 310 One of the advantages of using OpenBSD as opposed to a standard consumer grade router is that 311 you have all the needed tools at your disposal for debugging your network. The following manpages 312 should be of interest. 313 314 * [tcpdump(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/tcpdump.8) 315 * [systat(4)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/systat.1) 316 * [dig(1)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/dig.1) 317 * [arp(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/arp.8) 318 * [ndp(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/ndp.8) 319 * [route(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/route.8) 320 * [netstat(1)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/netstat.1) 321 * [pflogd(8)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/pflogd.8) 322 * [pflow(4)](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man4/pflow.4) 323 324 Keep your configuration as simple as possible. Do not randomly poke on sysctl knobs you do not 325 understand. Rely on the defaults unless you have a good reason not to. 326 327 If you have made extensive changes on a running system, do a final reboot to make sure everything 328 comes back up as expected. 329 330 Consider having a second machine connected over serial to your router. This way you can capture a trace 331 if the router crashes. It can also be used as an out-of-band mechanism to configure your router without 332 hooking up a monitor and a keyboard. 333 334 ### Reading material 335 336 I've found the following references highly informative and useful. 337 338 * [OpenBSD FAQ](http://www.openbsd.org/faq/) 339 * [TCP/IP Illustrated: Volume 1](http://www.amazon.co.uk/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0321336313/ref=sr_1_1?s=books&ie=UTF8&qid=1453299772&sr=1-1&keywords=tcp%2Fip+illustrated) 340 * [Unix Network Programming](http://www.amazon.co.uk/Unix-Network-Programming-Addison-Wesley-Professional/dp/0131411551/ref=sr_1_1?s=books&ie=UTF8&qid=1453299853&sr=1-1&keywords=unix+network+programming) 341 * [Book of PF](https://www.nostarch.com/pf3) 342 * [IPv6 for IPv4 Experts](https://sites.google.com/site/yartikhiy/home/ipv6book) 343 * [IPv6 Core Protocols Implementation](http://www.amazon.co.uk/Protocols-Implementation-Morgan-Kaufmann-Networking-x/dp/0124477518) 344 * [TCP/IP guide](http://www.tcpipguide.com/) 345 * [Internetworking with TCP/IP Volume 1](http://www.amazon.co.uk/Internetworking-Tcp-Ip-Principles-Architecture-y/dp/9332550107/ref=sr_1_1?s=books&ie=UTF8&qid=1458050786&sr=1-1&keywords=Internetworking+with+TCP%2FIP)