Bridge between two LANs with OpenBSD

My router is sharing the internet connection for an ethernet network and a WiFi network. Both of them where on their own sub-networks.

On my iPhone (using the WiFi network), I have the Remote application, allowing to control the iTunes on my Mac (which is using the ethernet network). Since they are not in the same network, it doesn’t work (even if routes are properly specified). The solution is to create a bridge for those two networks.

I already blogged about how I configured WiFi on my OpenBSD router.

Bridge configuration

Here is the configuration of the interfaces (rl0 if the ethernet interface ans rum0 if the WiFi interface):

inet 192.168.2.254 255.255.255.0 NONE

Nothing specific as expected.

up media autoselect mode 11g mediaopt hostap nwid <SSID> wpa wpaprotos wpa2 wpaakms psk wpapsk <SHARED KEY>

Here there is a slight modification, an IP address is not needed anymore. Bridge configuration:

add rl1
add rum0
up
PF

Be sure that PF is allowing packets between the two interfaces, in /etc/pf.conf you should have something like this:

int_if="rl1"
wlan_if="rum0"
 
pass quick on $int_if no state
pass quick on $wlan_if no state

It’s a bit simplistic, you may write more sophisticated filtering rules depending on your needs.

DHCP

My router is also acting as a DHCP for ethernet and WiFi devices. To activate DHCP, add the following line in /etc/rc.conf.local:

dhcpd_flags=""

Tell dhcpd to listen on rl1 only (rum0 does not have any IP so we don’t have to bind dhcpd to it):

dhcpd configuration:

shared-network LAN {
        option domain-name "example.net";
        option domain-name-servers <primary_dns_ip>, <secondary_dns_ip>;
 
        subnet 192.168.2.0 netmask 255.255.255.0 {
                option routers 192.168.2.254;
                range 192.168.2.32 192.168.2.127;
        }
}
Links
Posted in Uncategorized. Tags: , , , , , . No Comments »

Configuring OpenBSD as a WiFi access point

Goal

Now that my WiFi dongle works, I want to configure an access point with it so I could connect to my network and to the internet using WiFi.

My router is still an OpenBSD 4.4 fit-PC box, with the following network interfaces:

  • rl0 (ethernet) connected to my broadband modem, configured by my ISP‘s DHCP.
  • rl1 (ethernet) connected to my network switch, static configuration (192.168.1.254)
  • rum0 (WiFi) static configuration (192.168.2.254)

So I have two local networks and I want them to be able to communicate with each other and connect to the internet.

Ethernet configuration
dhcp NONE NONE NONE
inet 192.168.1.254 255.255.255.0 NONE
Setting up the WiFi dongle

The WiFi dongle needs to be configured as an access point. Network configuration is done in /etc/hostname.rum0 (it can also be configured with ifconfig but in order to keep the configuration after the next reboot it must be written in that file).

inet 192.168.2.254 255.255.255.0 NONE media autoselect mode 11g mediaopt hostap nwid [SSID] wpa wpaprotos wpa2 wpaakms psk wpapsk [shared key]

The beginning is a typical static configuration with 192.168.2.254 as IP address and 255.255.255.0 netmask. Detailed information for each parameter can be find in ifconfig‘s manpage.

  • mode 11g tells the dongle to use IEEE 802.11g standard (by default the dongle was using IEEE 802.11b)
  • mediaopt hostap tell the driver to use the dongle as an access point
  • nwid [SSID] set network’s name, the one showed when scanning WiFi access points ([SSID] must be replaced with the name of the network)
  • wpa use WPA protocol to protect the WiFi network
  • wpaprotos wpa2 tells that I only want to use wpa2, no wpa1
  • wpaakms psk set the authentication protocol to PSK (Pre Shared Key)
  • wpapsk [shared key] set the pre shared key (256 bits). It’s generated with the following command: wpa-psk [SSID] [passphrase] (where [passphrase] is the secret pass phrase, the one to type in the client devices to connect to the access point)
DHCP

I want WiFi clients to have their network configuration set automatically. So I need to set up a DHCP server.

DHCP configuration is in /etc/dhcpd.conf:

shared-network WLAN {
        option  domain-name "example.net";
        option  domain-name-servers xxx.xxx.xxx.xxx, yyy.yyy.yyy.yyy;
 
        subnet 192.168.2.0 netmask 255.255.255.0 {
                option routers 192.168.2.254;
                range 192.168.2.32 192.168.2.127;
        }
}

I want DHCP to give addresses only for WiFi devices, so only on rum0 interface. The list of interfaces to work on is stored in /etc/dhcpd.interfaces, I just have to write rum0 in it.

Activating the DHCP server is done by adding the following line to /etc/rc.conf.local:

(…)
dhcpd_flags=""
PF

A major feature of OpenBSD is Packet Filter (aka PF). This is the tool to filter TCP/IP traffic and do mostly anything on network packets. The official PF’s FAQ is very useful.

Here is an small configuration to get the described network to work. Configuration is done in /etc/pf.conf:

# PF options
set skip on lo
 
# Set variables
ext_if="rl0"
int_if="rl1"
wlan_if="rum0"
 
# Normalize packets
scrub all random-id fragment reassemble reassemble tcp
 
# NAT
nat on $ext_if inet from $int_if:network to any -> $ext_if
nat on $ext_if inet from $wlan_if:network to any -> $ext_if
 
block log all
antispoof log quick for { lo $int_if $wlan_if }
pass quick on $int_if no state
pass quick on $wlan_if no state
 
# Allow outgoing traffic
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto { udp, icmp } all modulate state

Activating PF is done by adding the following line to /etc/rc.conf.local:

(…)
pf=YES
Conclusion

Reboot to take all the changes into account and check that the configuration is still set. I tried to connect with my laptop and my phone, it works.

Of course I had several problems, the main one was to forgot a parameter in WiFi configuration, so I had to read the documentation. When you do so (and ask a bit Google for help), OpenBSD is quite easy to configure (well, considering that I don’t have a GUI with a good wizard for it).

D-Link DWA-110 on OpenBSD 4.4

In order to reduce power consumption and simplify my home network, I wanted to remove my WIFI router and replace it by adding an USB WIFI dongle on my router (a fit-PC with OpenBSD on it).

Choosing a dongle

As WIFI hardware is mostly proprietary stuff with Windows only drivers, not all of them are able to run on OpenBSD (or Linux).

So my requirements are:

  • USB WIFI dongle (USB is the only kind of connectors I can use on my fit-PC)
  • recognized by OpenBSD
  • do not requires non free (as in free speech) binary firmware
  • can work as an access point

I already had an Acer WLAN-G-US1 dongle, it has a ZyDAS chipset, which is supported by the zyd driver, but it can’t act as an access point.

From the OpenBSD’s supported WIFI hardware page I randomly selected the rum driver (working with Ralink RT2501USB and RT2601USB chipsets) and went to a store with the list of dongle models supported.

So I bought a refurbished D-Link DWA-110.

Plugging the dongle

When plugging it in the fit-PC, I got the following message in /var/log/messages:

(…)
Nov  7 20:00:32 hal /bsd: ugen0 at uhub0
Nov  7 20:00:32 hal /bsd: port 1 "Ralink 802.11 bg WLAN" rev 2.00/0.01 addr 2
(…)

What did just happened? The dongle is not recognized and the generic USB driver is associated with it.

Digging a bit in the manuals I found that in rum manual on my OpenBSD do not have D-Link DWA-110 in the hardware list. In fact, the online manual is more up to date than the one in OpenBSD which is already at least two weeks old… So my dongle will be supported in next OpenBSD release.

So what? Can’t do anything to fix that?

Compiling the kernel

The problem here is just that OpenBSD do not know that D-Link DWA-110 works with the current rum driver.

It’s quite easy to change that, but it requires recompiling OpenBSD’s kernel and rebooting.

First, download kernel sources:

# cd /usr/src
# wget ftp://ftp.crans.org/pub/OpenBSD/4.4/sys.tar.gz
# tar zxvf sys.tar.gz

Then, add the relevant changes to the drivers source files and the USB devices list.

  • Add the following line in the file /usr/src/sys/dev/usb/if_rum.c in the vendors/products list:
{ USB_VENDOR_DLINK2,            USB_PRODUCT_DLINK2_DWA110 },
  • In /usr/src/sys/dev/usb/usbdevs in the D-Link products add:
product DLINK2 DWA110           0x3c07  DWA-110
  • In /usr/src/sys/dev/usb/usbdevs_data.h in the usb_known_products structure add:
{
    USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110,
    "DWA-110",
},
  • And in /usr/src/sys/dev/usb/usbdevs.h:
#define USB_PRODUCT_DLINK2_DWA110       0x3c07          /* DWA-110 */

Then compile the kernel and reboot (this can be a bit long, especially on a slow computer like my fit-PC, it was about half an hour):

# cd /usr/src/sys/arch/`arch -s`/conf
# config GENERIC
# cd ../compile/GENERIC/
# make depend
# make
# make install
# reboot

Now we can check the USB devices:

# usbdevs -dv
Controller /dev/usb0:
addr 1: full speed, self powered, config 1, OHCI root hub(0x0000), AMD(0x1022), rev 1.00
  uhub0
 port 1 addr 2: full speed, power 300 mA, config 1, 802.11 bg WLAN(0x3c07), Ralink(0x07d1), rev 0.01
  rum0
 port 2 powered
 port 3 powered
 port 4 powered

The rum driver is associated with the D-Link dongle.

We can see that it uses around 300 mA on a 5 V USB power source, so I assume that the dongle is using 1.5 W. My actual WIFI router consumes 4 W.

The fit-PC was consuming 3.7 W, now with the dongle plugged in and running it consumes 5.5 W, that’s 1.8 W for the dongle, not so far from the theory.

Anyway, it seems that DWA-110 was already in “-current”, so it should have been in November’s release.

Useful links: