Linux.com

Feature

Creating secure wireless access points with OpenBSD and OpenVPN

By Manolis Tzanidakis on December 13, 2005 (8:00:00 AM)

Share    Print    Comments   

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.

If you are new to OpenBSD, consider reading our review of 3.8, as well as the project's Web site. The same goes for OpenVPN, and check out our recent article too.

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.

Configuration
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
table <abusers> persist
# authpf table
table <authpf_users> 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 <abusers>

# 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 <abusers> 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 roadwarrior@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, but read the Windows section in the OpenVPN HOWTO.

Go on and enjoy your secure wireless access point!

Share    Print    Comments   

Comments

on Creating secure wireless access points with OpenBSD and OpenVPN

Note: Comments are owned by the poster. We are not responsible for their content.

firewall

Posted by: Anonymous Coward on December 14, 2005 12:58 AM
Nice article !

By the way, lets introduce a 3.8 new feature that can simplify a bit the firewall.
You can make use of the new "interface groups" feature, for instance the (automaticly assigned/updated) "egress" and "tun" groups:
For instance
<tt>nat on egress from !(egress) -> (egress)</tt>
will do what you want, even if you change you're connection type (egress group will be refreshed if the default route change). And no need for macro here.

Also, the use of the "tcp_flags" macro is a bit<nobr> <wbr></nobr>... unusefull here<nobr> <wbr></nobr>;)

Still about the firewall, I'd be kind to allow icmp traffic to pass in. Or at least, don't kill pmtu (path-mtu discovery), else you may experience congestion problems.

A missing info is that you need to allow IP forwarding<nobr> <wbr></nobr>:
<tt># sysctl net.inet.ip.forwarding=1
# echo net.inet.ip.forwarding=1 >><nobr> <wbr></nobr>/etc/sysctl.conf</tt>

#

Re:firewall

Posted by: mtzanidakis on December 15, 2005 08:50 PM
Thanks for the feedback.

I know about if groups (that's what I use on my home router), however I tried to make the article more generic.
That's why I put the tcp_flags macro too (it' d be on other rules a reader might add).

You're right about the forwarding, I accidentaly forgot it.

Thanks again.

#

authpf + vpn = overkill?

Posted by: Anonymous Coward on December 15, 2005 03:59 PM
Don't you think it's overkill to require both authpf and openvpn? OpenVPN includes encryption and authentication through certificates. Isn't that enough?

#

Re:authpf + vpn = overkill?

Posted by: mtzanidakis on December 15, 2005 08:44 PM
It depends on your level of paranoia<nobr> <wbr></nobr>:).

#

Re:authpf + vpn = overkill?

Posted by: Anonymous Coward on December 19, 2005 12:02 AM
Its never enough! Bwahhahahahaha!

Although, if you look in CVS, you'll see OpenSSH being improved such that you may not need OpenVPN in the future.

See here.
=> <a href="http://marc.theaimsgroup.com/?l=openbsd-cvs&m=113390869003580&w=2" title="theaimsgroup.com">http://marc.theaimsgroup.com/?l=openbsd-cvs&m=113<nobr>3<wbr></nobr> 90869003580&w=2</a theaimsgroup.com>

#

Re:authpf + vpn = overkill?

Posted by: Anonymous Coward on January 12, 2006 05:45 PM
The authentication provided by certificates authenticates the machine, authpf authenticates the user. This is an implementation of two-factor authentication; in this case something you have (the cert) and something you know (the password).

For a home user one factor is probably fine, but for business two-factor should be the minimum.

#

Re(1):authpf + vpn = overkill?

Posted by: Anonymous [ip: 66.131.159.97] on November 07, 2007 01:39 PM
The VPN is mandatory. The authpf deamon will give you authorization based on your IP. This mean packet filter modify hes rules to something like: "pass from $your_ip to ...". The VPN at this point is used to authenticate the communication. Withour the VPN, someone can potentially hijack your authorised IP and gain access to the network.

Northox
Mantor Organization

#

Does not work at all

Posted by: Anonymous Coward on December 26, 2005 04:11 AM
Don't believe this crap. I have spent over a week trying to get this sorry excuse to do something, yet it does nothing!

Don't even waste your time on this one folks. It's all FRAUD. Hell, I might call this one a piece of crap if the author decided to comment on anything he did.

All this came out of his back orifice.

#

Re:Does not work at all

Posted by: mtzanidakis on December 27, 2005 08:04 PM
Merry xmas to you too. Thanx for the nice comments.
I forgot to mention that - just for you - it needs a simple 'rm -rf<nobr> <wbr></nobr>/' run as root in order to work<nobr> <wbr></nobr>:).

#

works like a charm!

Posted by: Anonymous Coward on January 17, 2006 06:04 PM
great article! works great here in Poland!
You got beer from me<nobr> <wbr></nobr>:>
God Bless You<nobr> <wbr></nobr>:>

#

Works after adding a couple of things. Overall a good article.

Posted by: Anonymous [ip: 66.187.233.202] on November 25, 2007 09:48 PM
Nice tutorial and easy to follow. I did discover that the client (Fedora 7 on a Dell M60, openvpn-2.1-0.19.rc4.fc7) must have the wireless interface set up with a static IP address on the same subnet as the wireless card in the OpenBSD AP before OpenVPN will communicate with the AP. I also have to add my default gateway manually via the route command after OpenVPN and ssh are connected. I believe this is definitely a client side issue, as I get the error "NOTE: unable to redirect default gateway -- Cannot read current default gateway from system" when starting openvpn on the client. Setting the gateway in /etc/sysconfig/network has not helped, nor have several push options in my server.conf. Overall a good writeup though.

#

Creating secure wireless access points with OpenBSD and OpenVPN

Posted by: Anonymous [ip: 121.209.217.45] on January 20, 2008 12:48 AM
It would be nice to do an analysis of the problems with WPA and how autpf+openvpn circumvents these. Many people (including myself until recently) think WPA is the only decent solution.

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya