You know how insecure 802.11x wireless networks are. In this article we'll create an OpenBSD-based secure wireless access point that prevents unauthorized access and encrypts every packet using a VPN tunnel. OpenBSD is one of the most secure operating systems available, is easy to use, and includes almost everything you need for this project in the base installation. OpenBSD supports a wide range of hardware platforms. You don't really need a behemoth for this project; my access point/router runs quite happily on a 166MHz Pentium. A quiet, low-power embedded board such as one from Soekris or the PC Engines WRAP works well. However, if you expect to have lots of clients connected at the same time, consider using a more powerful CPU or a crypto-accelerator card like the ones built by Soekris. For the wireless part you can either use a wireless adapter support by OpenBSD and have your box run as the actual access point -- which I recommend -- or use a regular access point connected via a crossover UTP cable to an Ethernet interface on the box. If you choose the latter course, keep in mind that most hardware access points use unencrypted Web-based administration interfaces and thus might be vulnerable to attacks. Configuring a wireless adapter to act as an access point in OpenBSD is a simple matter of creating /etc/hostname.ral0 (replace ral0 with your adapter's interface): # /etc/hostname.ral0 inet 192.168.2.254 255.255.255.0 NONE media autoselect mediaopt hostap mode 11g nwid my_secure_wlan chan 11 and issuing the command sh /etc/netstart ral0 as root. If you don't yet have OpenBSD installed, check chapter 4 of OpenBSD's excellent FAQ. For our setup, a minimum installation of bsd, base38.tgz, and etc38.tgz will be fine; feel free to install anything else you might want. For our VPN we could use OpenBSD's excellent implementation of IPsec (included in the base system), but we'll use OpenVPN instead because it can be deployed easily on both the server and a wide range of clients, including *BSD, Linux, Windows, and Mac OS X. OpenVPN scales well and is secure. The software is already included in OpenBSD's ports and packages repositories, so go ahead and install it. Authentication and firewall configuration In order to authenticate wireless clients connecting to our access point we'll use OpenSSH and OpenBSD's packet filter, pf(4), glued together by authpf(8). Start with the SSH daemon configuration by adding the following lines to /etc/ssh/sshd_config: Protocol 2 ClientAliveInterval 15 ClientAliveCountMax 3 PermitRootLogin no StrictModes yes MaxAuthTries 6 AllowUsers YOUR_USERNAMES_SPACE_SEPARATED Before you start sshd on system startup make sure sshd_flags= exists in your /etc/rc.conf.local file. If sshd is not already running, start it by running sshd as root. Our access point has three physical network interfaces: ext_if, connected to the Internet (e.g. to a DSL modem); int_if, connected to the wired LAN; and wlan_if, the wireless interface. It also has a virtual interface, tun0, for the VPN. Make sure to replace rl0, pppoe0, and ral0 in the following configuration files with your system's interface names. Now let's configure our packet filter through /etc/pf.conf. Our setup, as configured below, allows every packet on our wired, VPN, and loopback interfaces to pass through, but only limited incoming SSH traffic (to avoid brute-force attacks) from the wireless interface. It also does NAT on the external interface. # /etc/pf.conf: pf configuration file. # macros ext_if = "pppoe0" int_if = "rl0" wlan_if = "ral0" vpn_if = "tun0" tcp_flags = "flags S/SA keep state" # abusers table tablepersist # authpf table table persist # traffic normalization scrub in all # nat nat on $ext_if from !($ext_if) -> ($ext_if:0) # authpf nat-anchor "authpf/*" rdr-anchor "authpf/*" binat-anchor "authpf/*" anchor "authpf/*" # block everything by default block log all # block everything from abusers table block log quick from # allow outgoing packets to the internet pass out on $ext_if proto tcp all flags S/SA modulate state pass out on $ext_if proto { udp, icmp } all keep state # wireless interface (allow limited ssh to avoid brute-force attacks) pass in quick on $wlan_if proto tcp to ($wlan_if) port ssh $tcp_flags (max-src-conn 10, max-src-conn-rate 15/5, overload flush global) # allow everything from wired lan, vpn and loopback pass quick on { lo, $int_if, $vpn_if } # antispoof protection for all interfaces antispoof quick for { lo, $int_if, $wlan_if, $vpn_if } # End of /etc/pf.conf Enable packet filter by issuing pfctl -e -f /etc/pf.conf as root. Add the following lines to /etc/rc.conf.local to have it started automatically on system startup: pf=YES pf_rules=/etc/pf.conf For more information on pf, read the pf(4), pf.conf(5), and pfctl(4) man pages, PF User Guide, and Firewalling with OpenBSD's PF packet filter by Peter N. M. Hansteen, which also includes an authpf guide. Issue the command touch /etc/authpf/authpf.conf to create the empty file required by authpf, then create /etc/authpf/authpf.rules with the following lines: # /etc/authpf/authpf.rules: firewall rules for authenticated hosts. # macros wlan_if = ral0 # allow authenticated hosts to connect to openvpn daemon pass in quick on $wlan_if proto udp from $user_ip to ($wlan_if) port 1194 keep state # End of /etc/authpf/authpf.rules To add a login class for authpf, add these lines to /etc/login.conf: authpf:\ :shell=/usr/sbin/authpf:\ :tc=default: Also add /usr/sbin/authpf to /etc/shells to add in the list of acceptable shells; for more info check login.conf(5) and chpass(1) man pages. Now create users with the adduser command, making sure to set authpf as their shell and login class. Also make sure to add these users to the AllowUsers line in /etc/ssh/sshd_config. If you accept SSH connections over the Internet, add them in USER@WIRELESS_SUBNET format -- e.g. AllowUsers JimmyNewtron@192.168.2.* -- to tighten things a little bit more. If everything is working properly, connecting to your access point from a wireless client using OpenSSH or PuTTY will give you access to OpenVPN, which we'll set up now. VPN Configuration Before you begin, read OpenVPN's HOWTO. We'll use OpenVPN in bridged mode, bridging together the wired and VPN interfaces, in order to permit services such as Samba and CUPS to work as if wireless clients were connected on the wired LAN. After installing OpenVPN from OpenBSD's ports or packages, you must create certificates and keys for the server and the clients. As root, issue the following commands: # mkdir -p /etc/openvpn/keys # cp -r /usr/local/share/examples/openvpn/easy-rsa /etc/openvpn # chown -R root:wheel /etc/openvpn # chmod 700 /etc/openvpn/keys # cd /etc/openvpn/easy-rsa # . ./vars # ./clean-all # ./build-ca # ./build-key-server server # ./build-key client1 # ./build-key client2 etc. # ./build-dh # /usr/local/sbin/openvpn --genkey --secret ta.key # cd keys # mv ca.crt dh1024.pem server.crt server.key ta.key /etc/openvpn/keys # chmod 644 /etc/openvpn/keys/{ca.crt,dh1024.pem,server.crt} # chmod 600 /etc/openvpn/keys/{server.key,ta.key} Distribute ca.crt, clientXX.crt, clientXX.key, and ta.key using a secure medium (e.g. SCP or a USB memory stick) to your clients. Next, create /etc/openvpn/server.conf: # /etc/openvpn/server.conf: OpenVPN server configuration daemon openvpn writepid /var/openvpn/pid status /var/openvpn/status 10 local 192.168.2.254 # change to your wlan if's IP port 1194 proto udp dev tun0 dev-type tap client-to-client ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/server.crt key /etc/openvpn/keys/server.key dh /etc/openvpn/keys/dh1024.pem server-bridge 192.168.1.254 255.255.255.0 192.168.1.100 192.168.1.120 # change to your setup ifconfig-pool-persist /var/openvpn/ipp.txt push "redirect-gateway local def1" keepalive 10 120 tls-auth /etc/openvpn/keys/ta.key 0 cipher BF-CBC # Blowfish (default) max-clients 5 user _openvpn group _openvpn persist-key persist-tun verb 3 mute 20 chroot /var/empty # End of /etc/openvpn/server.conf Now issue the following commands to create the user and group _openvpn (which the daemon will run as) and the /var/openvpn directory, and configure the tun0 interface and the bridge between it and the wired interface: # groupadd -g 500 _openvpn # useradd -u 500 -g 500 -c 'OpenVPN Server' -s /sbin/nologin -d /var/openvpn -m _openvpn # echo 'link0 up' > /etc/hostname.tun0 # echo -e 'add rl0\nadd tun0\nup' > /etc/bridgename.bridge0 # sh /etc/netstart tun0 # sh /etc/netstart bridge0 Start the OpenVPN daemon with /usr/local/sbin/openvpn --config /etc/openvpn/server.conf and add the following lines in /etc/rc.local to have it started automatically: if [ -x /usr/local/sbin/openvpn ]; then /usr/local/sbin/openvpn --config /etc/openvpn/server.conf fi Check /var/log/daemon to make sure the daemon started with no problems. Now let's configure our first client, on a Linux platform, by creating /etc/openvpn/keys, adding the OpenVPN user and group, copying the keys we created into it, and creating /etc/openvpn/client1.conf: # /etc/openvpn/client1.conf: OpenVPN client configuration client dev tap proto udp remote 192.168.2.254 1194 # replace with your access point's IP resolv-retry infinite nobind user openvpn group openvpn persist-key persist-tun mute-replay-warnings ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/client1.crt key /etc/openvpn/keys/client1.key ns-cert-type server tls-auth /etc/openvpn/keys/ta.key 1 cipher BF-CBC verb 3 mute 20 chroot /var/empty # End of /etc/openvpn/client1.conf Again, check /var/log/messages to make sure everything is OK. If it is, issue openvpn --config /etc/openvpn/client1.conf to connect to the server. Try pinging a host on your wired LAN or browsing the network to make sure the connection actually works. To verify that everything passing through our wireless client is encrypted, start tcpdump on the wireless and VPN interfaces on the access point. Ping the access point from the client and verify that the output looks like the following: # tcpdump -env -ttt -i ral0 tcpdump: listening on ral0, link-type EN10MB Nov 15 21:01:28.865218 0:11:6b:34:91:59 0:e:35:e3:ff:51 0800 223: 192.168.2.254.1194 > 192.168.2.1.32875: udp 181 (ttl 64, id 20205, len 209) # tcpdump -env -ttt -i tun0 tcpdump: WARNING: tun0: no IPv4 address assigned tcpdump: listening on tun0, link-type EN10MB Nov 15 21:05:46.569068 be:88:12:eb:0:4b 0:80:48:1d:e:28 0800 98: 192.168.1.100 > 192.168.1.254: icmp: echo request (id:0926 seq:1) (DF) (ttl 64, id 0, len 84) Nov 15 21:05:46.569375 0:80:48:1d:e:28 be:88:12:eb:0:4b 0800 98: 192.168.1.254 > 192.168.1.100: icmp: echo reply (id:0926 seq:1) (DF) (ttl 255, id 44123, len 84) If your client runs OpenBSD, replace dev tap with dev tun0 dev-type tap in /etc/openvpn/client1.conf. Windows clients should be the same as Linux. Go on and enjoy your secure wireless access point!
Wireless
Calculators
Free Space Loss Calculator
mW and dbm Converter
Fresnel Zone Calculator
Tx Power Calculator
Operating System Margin
ERP Calculator
Range Calculator
Helix Antenna Calculator
WEP Key Generator
![]()
Antenna Designs
Yagi Directional Antenna
Colinear Omnii Directional Antenna
5dbi Colinear Omnii Directional Antenna
Helical Directional Antenna
Bi Quad Directional Antenna
![]()
Hardware
Linux Access Point
OpenBSD/OpenVPN Access Point
Embedded Linux Access Point/Router/Firewall
![]()
Standards
802.11 Standards