OpenBSD/Bridging ADSL/Wireless HOWTO

Version: 1.12
Author: Doug Winter
Contact: doug@pigeonhold.com
Date: 2004-01-25
Web site:http://www.britishsteal.com/

Contents

License

Copyright (c) 2004 Doug Winter

This document is released under the Creative Commons Attribution license. You are free to copy, modify and distribute this work as long as you give me the credit. The full license text is available from their site.

Introduction

This document gives detailed instructions on setting up a particular combination of hardware that I consider provides the best possible small office or home networking configuration. It provides ADSL, Wireless Access Point, Firewalling, Nameserver, DHCP Server and you have the option of adding IPSec if you wish.

All this for 65 quid, if you can find an old PC from somewhere.

The Theory

We're going to construct a network that looks like this:

+-----+  ADSL   +--------+  Ether  +----------+
| ISP |---------| Bridge |---------| Firewall |--- Ethernet
+-----+  PPPoA  +--------+  PPPoE  +----------+
                                        |
                                        | Wireless
                                        |  802.11b

The firewall provides a these services:

  • PPPoE protocol support
  • PPP dialling
  • PPP Interface provision
  • Wireless Host Access Point
  • Domain Name services
  • DHCP
  • Packet Filtering

Importantly it provides these better and more cheaply than any equivalent I know of.

We are going to run the router as a PPP BRIDGE. Instead of working as an IP Router, where it routes IP packets from place to place, we are going to run it purely to convert PPP traffic from PPP-over-ATM (PPPoA: as used as standard in the UK for ADSL provision) to PPP-over-Ethernet (PPPoE: something our firewall can understand).

This means that all IP-layer functionality will be handled on the OpenBSD system, which provides a far higher quality environment. Also, your router does not have an IP address, so cannot be accessed directly (without reconfiguring the firewall). This means you should be insulated from the, quite common, security flaws in these devices.

Knowledge Required

This document expects you to be familiar with IP routing and with UNIXlike operating systems.

You will also need to know these specific things:

  • What networks and netmasks to use for your ethernet and wireless network
  • What IP addresses to use for your ethernet and wireless interfaces
  • What the WEP encryption key you are going to use for your wireless network is (although I show how to generate a new one if you need it)
  • What the VPI and VCI values are for your ADSL provider (in the UK these are 0 and 38)
  • What your ADSL ppp login username and password are

Hardware

If you vary from this particular list, you may well find the configuration will have to change too. YMMV.

  • Virtually any x86 PC, of any specification. Just find an old box somewhere. The machine I used has the following spec:

    • 432MHz Intel P4
    • 128MB RAM
    • 4GB HDD
  • Ethernet network cards. You will probably want two. Anything supported by OpenBSD will be fine. I've got a Realtek 8139 and a DEC Tulip. If you want quality, get Intel, perhaps the dual ethernet cards. We're only putting a few Mbps through these though, so there's no need to splash out.

  • Another PC with ethernet, running pretty much any OS. You have one of these already, or you wouldn't be reading this.
  • An ethernet hub or switch.
  • A piece of crossover ethernet cable. These can be annoyingly hard to get hold of. Make sure it really is a crossover.

Software

The following instructions are for OpenBSD 3.4. OpenBSD has the very best networking support of any OS I've used. It is also perhaps the simplest of modern UNIXlike Operating Systems, which makes it good for restricted use systems such as this.

Setting up The Base OS

Install the three network cards in the PC.

Connect the ADSL router to one of the ethernet cards with the crossover ethernet cable. There is no need to connect the ADSL cable yet.

Now install OpenBSD. You should probably read through the rest of this document first, to get a feel for what you'll be doing. Follow the OpenBSD installation instructions that come with it. I'd strongly suggest purchasing a CD distribution, it'll make the install easier, and you are supporting the developers. Alternatively you can download and burn an ISO, or you can do a floppy/network install. However, since you haven't got a network yet, the network install might be tricky :)

Do a default install. You can partition the whole disk as a single partition if you like (apart from swap obviously), or break out /var, /usr, /home as normal. For small disks, I'd suggest a seperate /var partition, and everything else on a single partition. YMMV.

Once you are installed and booted, you should see your network devices in the dmesg. Check that you can, it'll look something like:

wi0 at pci1 dev 8 function 0 "Intersil PRISM2.5 Mini-PCI WLAN" rev 0x01: irq 11
wi0: PRISM2.5 ISL3874A(Mini-PCI), Firmware 1.0.7 (primary), 1.3.6 (station), address 00:09:5b:11:f4:48
rl0 at pci1 dev 9 function 0 "Realtek 8139" rev 0x10: irq 10 address 00:30:bd:19:38:39
rlphy0 at rl0 phy 0: RTL internal phy
de0 at pci1 dev 10 function 0 "DEC 21140" rev 0x22: irq 11
de0: 21140A [10-100Mb/s] pass 2.2 address 00:40:05:a5:82:74

If you can see your three network devices, then all should be ok.

Configuring the Networks

Your firewall has three network interfaces, named by their drivers. This means the names will vary depending on the manufacturer of the cards. In my example here, I have rl0, de0 and wi0. rl0 is going to be my internet facing interface, de0 my local ethernet and wi0 the local wireless.

As you are probably aware, WEP has some severe security issues. You should not rely on WEP to make your wireless network secure. If you require a secure wireless network, run IPSec over it. Some new standards for wireless security are on the way, and these will hopefully be sufficient when they are available.

If you haven't got an existing WEP key, you can generate a nice shiny new random one with:

openssl rand 13 | hexdump -e '13/1 "%02x"'

This generates a 104-bit key, which is 26 hex characters long.

I have chosen to assign 192.168.100.0/24 to the ethernet network and 192.168.101.0/24 to the wireless network. I'm following a common policy of assigning the .254 address to the outbound gateway of a network, so my interfaces are going to be configured as follows:

/etc/hostname.de0:

inet 192.168.100.254 255.255.255.0 NONE

The above may have been done already, since part of installation asks you for your network interface configuration.

/etc/hostname.wi0:

inet 192.168.101.254 255.255.255.0 NONE nwid <network-id> mediaopt hostap nwkey 0x<wep-key>

Replace <network-id> with a short string for your network, doesn't matter what it is. Replace <wep-key> with your hexadecimal wep key. Note that your wep key needs to be preceded by 0x, because it is in hex, so will look like, for example, 0x38a10ab537797103b8762c241a in the configuration above.

Once you have configured your hostname files, reboot and ensure with ifconfig that the interfaces are correctly configured. The wireless one will look something like:

wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        address: 00:09:5b:11:f4:48
        nwid <network-id>
        nwkey <wep-key>
        powersave off
        media: IEEE802.11 autoselect hostap (DS2)
        status: active
        inet 192.168.101.254 netmask 0xffffff00 broadcast 192.168.101.255
        inet6 fe80::209:5bff:fe11:f448%wi0 prefixlen 64 scopeid 0x1

Note that it's in hostap mode, and has a wep key configured. Incidentally, WEP keyage has been confused immensely on some Windows systems. Sometimes they ask for a passphrase, which they they hash into a key (presumably they assume their punters are too stupid to operate a pen to write a key down). Sometimes they ask for it in four chunks. I'm afraid Windows is beyond me mostly, so you're on your own with it.

Configuring the Router

Plug the hub/switch into the other ethernet port on the firewall. Plug your other PC into the switch.

You will need to get HTTP access to the router to configure it. However, once it is fully configured, we will not be accessing it over IP. This is because it will be running as a bridge.

The router comes as default configured like:

  • IP Address: 10.0.0.2
  • Username: admin
  • Password: epicrouter

It's default route is over it's WAN port, however, so if like me you aren't running X Windows on your firewall, you won't be able to just stick 10.0.0.2 in your browser on your other PC and expect to get to it, because it won't route packets back to you.

What I'd suggest is using an ssh tunnel to proxy your HTTP connection. On your other PC run:

ssh -L 9999:10.0.0.2:80 <firewallIP> sleep 10000

replacing <firewallIP> with the ethernet address of your firewall. Now you can point your browser at http://localhost:9999 and you will be tunneled to the router.

You will now need to configure your router as a bridge.

Router Configuration Settings

These configuration changes are what is required from factory default. If it isn't listed, leave the field as it was by default.

Rather uninutitively, for each page:

  • Make the specified changes
  • Click SUBMIT at the bottom of the right-hand frame
  • Click save settings on the left

When the router has come back up, check the changes have committed.

Configuration: WAN

  • VPI: 0
  • VCI: 38
  • Static IP Address: 0.0.0.0
  • Subnet Mask: 0.0.0.0
  • Gateway: 0.0.0.0
  • Bridge: Enabled

Configuration: LAN

  • DHCP Server: Off

Configuration: DNS

  • DNS Proxy Selection: Disable DNS Proxy

Now connect your router to the ADSL line and reboot it. Watch the ADSL status page to check that it connects. When it's live it will say "SHOWTIME". The blinkenlights on the front panel will blink.

Configuring your PPP Daemon

Your bridge is now running, but you need to provide an IP connection over it to your ISP. On OpenBSD the PPP daemon runs in userspace, and PPPoE connectivity is provided by a seperate userspace helper application.

Here's the configuration files you'll need:

/etc/ppp/ppp.conf:

default:
    set log Phase Chat IPCP CCP tun command
    set redial 15 0
    set reconnect 15 10000

pppoe:
    set device "!/usr/sbin/pppoe -i <interface>"
    disable acfcomp protocomp
    deny acfcomp
    set mtu max 1492
    set speed sync
    enable lqr
    set lqrperiod 5
    set cd 5
    set dial
    set login
    set timeout 0
    set authname <username>
    set authkey <password>
    add! default HISADDR
    enable mssfixup

In the above, replace <interface> with the interface that is connected to the router (in my case rl0) and <username> and <password> with your adsl login details.

/etc/ppp/options:

lock
auth
usehostname

With these files in place, you can bring your network up with:

# ppp -ddial pppoe

You can watch the progress of the ppp connection by tailing /var/log/ppp.log. If it works you will see eventually a line like:

Jan 24 14:31:42 edam ppp[7082]: tun0: IPCP: deflink: LayerUp.

In your logs, indicating that ppp is up and running. A new virtual network interface has been created, tun0, and this is your internet interface. It will look something like:

tun0: flags=8011<UP,POINTOPOINT,MULTICAST> mtu 1492
        inet xxx.xxx.xxx.xxx --> yyy.yyy.yyy.yyy netmask 0xffffffff

Now you are on the internet. You won't be routing packets though, because forwarding hasn't been turned on. So edit /etc/sysctl.conf to enable ip forwarding. You want:

net.inet.ip.forwarding=1

When you reboot you'll be routing packets.

Finally, you want to dial the internet on boot, so add to the end of /etc/rc.local:

ifconfig rl0 up
ppp -ddial pppoe

Security

You will obviously want to filter traffic to and from the Internet. You will also want to NAT your network, so that all traffic comes from your internet IP address. You're actual pf ruleset will depend on what you do, however a good starting configuration will look something like the following. Replace <internal-if>, <internal-net> and <wireless-net> with appropriate values. For my system they are:

int_if="de0"
internal_net="192.168.100.0/24"
wireless_net="192.168.101.0/24"

/etc/pf.conf:

# our defines
ext_if="tun0"
int_if="<internal-if>"
unroutable="{ 127.0.0.1/8, 10.0.0.0/8, 172.16.0.0/12, \
              192.168.0.0/16, 255.255.255.255/32 }"

internal_net="<internal-net>"
wireless_net="<wireless-net>"

# force packets to conform to specifications.  You can miss off the
# no-df if you don't intend to use IPSec.
scrub in  all no-df
scrub out all no-df

nat on $ext_if from $internal_net to any -> $ext_if
nat on $ext_if from $wireless_net to any -> $ext_if

# ftp-proxy support
rdr on $int_if proto tcp from any to any port ftp -> 127.0.0.1 port 8021

# block and log everything by default
block             log
block return-rst  log inet proto tcp
block return-icmp log inet proto udp

# pass everything on our internal interfaces
pass log quick on $int_if
pass log quick on wi0
pass log quick on lo0

# block some known bad ports without logging
block return-rst  in quick on $ext_if proto tcp from any to any \
    port { 111, 443, 445, 1080, 6000, 6667 }
block return-icmp in quick on $ext_if proto udp from any to any \
    port { 137, 138, 139, 1434 }

# block and log reserved addresses
block in log quick on $ext_if inet from $unroutable to any

# block spoofed or broken nat packets
block out log quick on $ext_if from !$ext_if to any

# ICMP - allow ping
pass out log quick on $ext_if inet proto icmp from $ext_if to any \
    icmp-type 8 code 0 keep state queue (q_max)
pass in  log quick on $ext_if inet proto icmp from any to $ext_if \
    icmp-type 8 code 0 keep state (max 32) queue (q_low)

# UDP - allow outbound connections
pass out log quick on $ext_if inet proto udp from $ext_if to any keep state

# TCP - allow outbound connections
pass out log quick on $ext_if inet proto tcp from $ext_if to any modulate state flags S/SA

Pf will allow the inbound parts of ICMP, UDP and TCP traffic that has been successfully initiated in those last four rules automatically, because they keep state.

In /etc/inetd.conf, uncomment the following line, and HUP inetd:

127.0.0.1:8021 stream tcp   nowait  root    /usr/libexec/ftp-proxy ftp-proxy

This provides transparent ftp proxying, so you can ftp out of your network. FTP has issues with NAT.

Now configure the ppp daemon to bring the packet filter up when the internet interface, tun0, comes up:

/etc/ppp/ppp.linkup:

pppoe:
    ! sh -c "/sbin/ifconfig pflog0 up"
    ! sh -c "/sbin/pfctl -e -f /etc/pf.conf"
    ! sh -c "/sbin/pflogd"

Note that so far there's no restrictions on wireless connections - if someone breaks your WEP key (which is easy) they can connect with impunity. I'm not going to cover IPSec configuration here, because getting it to interoperate properly in a heterogenous network is a pita.

Additional Services

Finally you probably want to run DHCP and a DNS server on the firewall, serving your internal networks. This makes configuration of your other computers far simpler, and centralises administration.

DNS Server Configuration

The nameserver that comes distributed with OpenBSD is BIND 9. It's heavily audited by the OpenBSD team, and comes preconfigured to run in a chroot. IMO this makes it secure enough to run on a firewall.

For the simplest configuration, copy /var/named/etc/named-simple.conf as /var/named/etc/named.conf, and add configuration for your ISPs nameservers. Just add to the options section something like:

forwarders {
    212.158.192.2;
    212.158.192.3;
};

With those addresses replaced by your ISPs nameservers. Then put in resolv.conf:

lookup file bind
nameserver 127.0.0.1

You may also want to add a search line for whatever your domains are. You should also add stanzas to your named.conf file for your internal systems.

in /etc/rc.conf, change the named_flags to be blank, so that named is started on boot.

DHCP Server Configuration

You should configure /etc/dhcpd.conf appropriately for your network topology. Mine looks like:

default-lease-time 600;
max-lease-time 7200;

authoritative;

# Wireless Network
subnet 192.168.101.0 netmask 255.255.255.0 {
    option domain-name "wireless.example.com";
    range 192.168.101.3 192.168.101.253;
    option routers 192.168.101.254;
    option domain-name-servers 192.168.101.254;
}

# Ethernet Network
subnet 192.168.100.0 netmask 255.255.255.0 {
    option  domain-name "example.com";
    range   192.168.100.2 192.168.100.253;
    option  routers 192.168.100.254;
    option domain-name-servers 192.168.100.254;
}

If you wish your known hosts to have fixed addresses (I do), then add stanzas like:

host cheddar {
    hardware ethernet 00:30:AB:20:22:60;
    fixed-address 192.168.101.1;
}

host roquefort {
    hardware ethernet 00:09:5B:27:FE:09;
    fixed-address 192.168.101.2;
}

This allows you to have fixed internal IP addresses, but with central configuration of their values.

Now configure the DHCP server to run on boot by editing /etc/rc.conf and changing the dhcpd_flags line to:

dhcpd_flags=-q      # for normal use: "-q"

Configuration Summary

After all that, power cycle your router and reboot your firewall to make sure it all comes up properly. It should now:

  • configure the wi0 interface and your ethernet interface
  • run BIND and dhcpd
  • dial your ISP
  • negotiate a PPP link
  • bring the tun0 interface up
  • start the packet filter
  • start the packet filter logging daemon

When you bring a machine up on the wireless network, your server will act as the Access Point (i.e. it will transmit packets to other stations), will route between the networks, and it will configure them via DHCP. Ethernet hosts will be handled similarly.

IPSec

This is really outside the scope of this document - Configuration of IPSec is a huge issue. However, manually keyed IP Sec VPNs can be set up between OpenBSD systems quite easily, if your requirements are simple, and I give an example here.

If you have two OpenBSD 3.4 gateways, then you just need to:

  1. enable the esp sysctl. See /etc/sysctl.conf for:

    net.inet.esp.enable=1           # 0=Disable the ESP IPsec protocol
    
  2. copy /usr/share/ipsec/rc.vpn as /etc/rc.vpn

  3. edit /etc/rc.vpn on both hosts and change:

    • GW_LOCAL
    • GW_REMOTE
    • LOCAL_NETWORKS
    • REMOTE_NETWORKS
  4. I had no success with 3des encryption, interoperating with an OpenBSD 3.2 host, but blowfish worked fine. I don't know why. So you may wish to change ENC to blf (AIUI it's better than 3des anyway).

  5. Generate your keys on one host.

    This example is for blowfish encryption (160-bit keys) and SHA1 authentication (160-bit keys):

    # openssl rand 20 | hexdump -e '20/1 "%02x"' > /etc/esp-enc-key
    # openssl rand 20 | hexdump -e '20/1 "%02x"' > /etc/esp-auth-key
    
  6. copy your keys to the other host.

  7. On one gateway, you should reverse the values of SPI_OUT and SPI_IN.

  8. Add "sh /etc/rc.vpn" to the end of your /etc/rc.local script

Now you'll need to amend your firewall rules to allow the ESP traffic to your internet facing interfaces, and then you can add rules to your enc0 interface to specify what traffic is allowed over the vpn. Remember you need to do this to both gateways.

You might want some rules like, say:

# allow all traffic over the vpn
pass log quick on enc0

# allow ESP traffic to the gateway
pass log quick on $ext_if proto esp from $remote_gw to { $ext_if, $internal_net }
pass log quick on $ext_if proto esp from { $ext_if, $internal_net } to $remote_gw

You probably want to restrict traffic over the vpn, although your rules will depend on what you need to do.