markus reichelt, December 2004
v1.1.1, last modified: 2006-05-01, status: unmaintained, kept for reference
This text is intended for linux users who already have installed OpenVPN (and OpenSSL) properly and want to use it to securely integrate WLAN into their private network. A succinct network layout is provided, as well as config examples for an OpenVPN server with static key on a linux box and client configurations with static key for both linux and Windows XP. The whole setup is DHCP-aware. Netfilter rules are given to securely integrate the WLAN connection into the the private network.
I'm happily using the Slackware 10+ distro as base system, both on my desktops and servers. The netfilter rules can be invoked standalone or added to MonMotha's Firewall script version 2.3.8.
This setup is known to work on Slackware 10.2 systems with OpenVPN 2.0.5 and OpenSSL 0.9.7i
.[top]
My network layout is very similar to this one, so I'm re-using the layout mentioned there.
### = Uplink to Internet Service Provider
--- = 100Mbit Fast Ethernet
/// = WLAN Connection
*** = VPN Connection
LINUX-SERVER
+-----------------+
+--------+ | +-------------+ |
| I S P |######| eth0/ppp0 | |
+--------+ | +-------------+ |
| |
| | +-----------------+
| +-------------+ | | +-------------+ |
| | eth1 |----------| SWITCH | |
| | 192.168.0.1 | | | +-------------+ |
| +-------------+ | | 192.168.0.0/24 |
| | +-----------------+
| |
| +-------------+ | +-----------------+
| | eth1:1 | | | +-------------+ |
| | 192.168.3.1 |----------| AccessPoint | |
| +------******************|******* | |
| * | | +------*------+ |
| * | | 192.168.3.2 |
| * | +-------/*/-------+
| +------*------+ | /*/
| | tap0(VPN) | | /*/
| | 10.1.1.1 | | /*/
| | | | /*/
| | tap1(VPN) | | /*/
| | 10.1.2.1 | | /*/
| +-------------+ | /*/
| | /*/
+-----------------+ /*/
/*************************/
/*/ /*/
/*/ /*/
+-------/*/---------+ +-------/*/---------+
| +---------------+ | | +---------------+ |
| | VPN-EndPpoint | | | | VPN-EndPpoint | |
| | 10.1.1.2 | | | | 10.1.2.3 | |
| +---------------+ | | +---------------+ |
| | Wireless LAN | | | | Wireless LAN | |
| | Client | | | | Client | |
| | slackware 10 | | | | windows xp | |
| +---------------+ | | +---------------+ |
| 192.168.3.3 | | 192.168.3.4 |
+-------------------+ +-------------------+
You'll notice that I use the virtual ethernet device eth1:1 instead of one more NIC, just for efficiency. The other subnets of my network are irrelavant to the task at hand, hence they aren't listed.
[top]
The linux box will be the OpenVPN server. Since this howto is using a static key, you need to create one in /etc/openvpn.
openvpn --genkey --secret /etc/openvpn/wireless-static.key
And when it comes to keys, don't forget to
chmod 0600 /etc/openvpn/wireless-static.key
Now it's time to create the config file which is located at /etc/openvpn/wireless-static.conf
#### SERVER /etc/openvpn/wireless-static.conf #### #listen on this ip only local 192.168.3.1 #we use tap device dev tap #set ip address and netmask of VPN tunnel server point ifconfig 10.1.1.1 255.255.255.0 #tell openvpn where to find the static key secret /etc/openvpn/wireless-static.key #sometimes this is required link-mtu 1544 #we want some log info verb 3 #use compression comp-lzo #give port number. if not given, 1194 is used. port 1195
That's all, now you can start the OpenVPN server with the following command
openvpn --config /etc/openvpn/wireless-static.conf
and you should see a similar output to this:
#### SERVER #### LZO compression initialized TUN/TAP device tap0 opened /sbin/ifconfig tap0 10.1.1.1 netmask 255.255.255.0 mtu 1467 broadcast 10.1.1.255 Data Channel MTU parms [ L:1544 D:1450 EF:45 EB:19 ET:32 EL:0 ] Local Options hash (VER=V4): '007023e0' Expected Remote Options hash (VER=V4): '007023e0' UDPv4 link local (bound): [undef]:1195 UDPv4 link remote: [undef]
That's it, your server is up and listening on port 1195. Now copy wireless-static.key to the client, preferrably to /etc/openvpn.
[top]
It is assumed that OpenVPN and OpenSSL have been installed properly on the client. Then proceed and create the client configuration file /etc/openvpn/wireless-static-client.conf
#### CLIENT /etc/openvpn/wireless-static-client.conf #### #we use tap device dev tap #address of openvpn server remote 192.168.3.1 #set ip address and netmask of vpn client tunnel endpoint ifconfig 10.1.1.2 255.255.255.0 #tell openvpn where to find the static key secret /etc/openvpn/wireless-static.key #route to server endpoint route-gateway 10.1.1.1 #redirect traffic redirect-gateway #use compression comp-lzo #again link-mtu 1544 #log info verb 3 #give port number. if not given, 1194 is used. port 1195
That's all, now you can start the OpenVPN client with the following command
openvpn --config /etc/openvpn/wireless-static-client.conf
and you should see a similar output to this:
#### CLIENT #### LZO compression initialized TUN/TAP device tap0 opened Data Channel MTU parms [ L:1544 D:1450 EF:45 EB:19 ET:32 EL:0 ] Local Options hash (VER=V4): 'fa340d5e' Expected Remote Options hash (VER=V4): 'fa340d5e' UDPv4 link local (bound): [undef]:1195 UDPv4 link remote: 192.168.3.1:1195 Peer Connection Initiated with 192.168.3.1:1195 Initialization Sequence Completed
Check the network, ping the tunnel endpoint from each side. Start with the client and enter
ping -c3 10.1.1.1
The output should be similar to this
#### CLIENT #### PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data. 64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=2.75 ms 64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=2.36 ms 64 bytes from 10.1.1.1: icmp_seq=3 ttl=64 time=2.40 ms --- 10.1.1.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 2.369/2.511/2.756/0.173 ms
Now the server:
ping -c3 10.1.1.2
The output should be similar to this
#### SERVER #### PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data. 64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=2.86 ms 64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=3.16 ms 64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=2.73 ms --- 10.1.1.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 2.733/2.921/3.168/0.187 ms
Got a Ping?! That's great! But what about routing? By default OpenVPN tries to adjust routes itself and in most cases it just works.Nevertheless we check it, starting from the server
/sbin/route -n
Only the important routes are listed here in this example, check for tap0
#### SERVER #### Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface [...] 192.168.3.1 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 255.255.255.255 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 255.255.255.255 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 192.168.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 217.5.xxx.xxx 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0 192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 10.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0 10.1.2.0 0.0.0.0 255.255.255.0 U 0 0 0 tap1 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 217.5.xxx.xxx 0.0.0.0 UG 0 0 0 ppp0 [...]
Experience shows that a big bunch of problems boil down to client routing troubles... Now let's hear what the client has to say.
/sbin/route -n
tap0 must be listed in the routing table as device and also as default gateway. If it's not listed as default gateway you must add the route on your own. The Fine Manual knows a lot about troubles, be sure to consult it.
#### CLIENT #### Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.3.1 192.168.3.1 255.255.255.255 UGH 0 0 0 eth1 192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 10.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 10.1.1.1 0.0.0.0 UG 0 0 0 tap0
Now try surfing the net, it should work. If you run a caching name server be sure that the client is allowed to inquire from 10.1.1.2 as well.
[top]
Actually I despise this 'operating system', but once in a while there's just no way around it. You have to make sure to install OpenVPN properly, usually just run the installer and be done with it. But only the config files are listed here (for reference), for the client on win xp and the seperate server config file on the linux box. Don't forget to copy the secret key to the windows 'machine'.
#### win xp CLIENT wireless-static.conf #### #we use tap device dev tap #address of openvpn server remote 192.168.3.1 #define port port 1196 #set ip address and netmask of client vpn endpoint ifconfig 10.1.2.3 255.255.255.0 #we need to set routes ourselves via batchfile up setroutes.bat #where is the key secret wireless-static.key #we want some log info verb 3 #compression is left off #comp-lzo
#### win xp CLIENT setroutes.bat #### route add 10.1.2.0 netmask 255.255.255.0 10.1.2.1 route add 0.0.0.0 mask 0.0.0.0 10.1.2.1
Create a link to where you installed OpenVPN (like "target C:\Programme\OpenVPN\bin\openvpn.exe --config wireless-static.conf", execute in "C:\Meine Daten\OpenVPN"; all important files reside in there! key + conf + bat). In case this sounds too confusing have a look here. Then start the app, a window should pop up with similar messages to the ones above (client side). If it pops up just for a second, something is not right. Maybe a typo? If you can't ping the win xp 'machine', maybe you activated its 'firewall'? Try plain old surfing, if the route is correct.
Be prepared for the most strangest phenomenons. Theoretically it should work, practically you're running windows. Perhaps getting a fresh cup of coffee will magically help.
Last but not least the corresponding server config file for a win xp client.
#### SERVER /etc/openvpn/wireless-static-winxp.conf #### dev tap port 1196 ifconfig 10.1.2.1 255.255.255.0 secret /etc/openvpn/wireless.key verb 3
Run the same tests as described above accordingly.
[top]
Using an encrypted Virtual Private Network is only one half of a secure WLAN integration into a private network. The other half is making sure that (almost) only traffic on the UDP connections can pass from the WLAN subnet into the private network. The whole thing shall still be usable with DHCP. That's where netfilter comes in.
First we have to make sure that traffic from/to tap/tun devices is not blocked.
Oh, and if you're using MonMotha's Firewall script, just add the following lines in appearing order to the end of the script so that each time the connection to your ISP gets reestablished, the whole WLAN stuff is not leaving a huge security hole in your system.
${IPTABLES} -A INPUT -i tun+ -j ACCEPT
${IPTABLES} -A FORWARD -i tun+ -j ACCEPT
${IPTABLES} -A INPUT -i tap+ -j ACCEPT
${IPTABLES} -A FORWARD -i tap+ -j ACCEPT
Now lets focus on eth1:1, 192.168.3.1, which is directly connected to the Access Point. We only want VPN traffic to pass, and some stuff necessary for DHCP, and an ordinary ping shall pass as well. That's what these netfilter rules are for.
${IPTABLES} -t nat -I PREROUTING -i eth1 -s 192.168.3.0/24 \
-j DROP
${IPTABLES} -t nat -I PREROUTING -i eth1 -s 192.168.3.0/24 \
-d 192.168.3.1 -p icmp --icmp-type echo-request -j ACCEPT
${IPTABLES} -t nat -I PREROUTING -i eth1 -s 192.168.3.0/24 \
-d 192.168.3.1 -p udp --dport 1195 -j ACCEPT
${IPTABLES} -t nat -I PREROUTING -i eth1 -s 192.168.3.0/24 \
-d 192.168.3.1 -p udp --dport 1196 -j ACCEPT
${IPTABLES} -t nat -I PREROUTING -i eth1 -p udp --source-port\
68 -d 255.255.255.255 --destination-port 67 -j ACCEPT
${IPTABLES} -t nat -I PREROUTING -i eth1 -p udp --source-port\
67 --destination-port 68 -j ACCEPT
${IPTABLES} -t nat -I PREROUTING -i eth1 -p udp --source-port\
67 --destination-port 67 -j ACCEPT
[top]
When you get a working static key setup, it's wise to make the next step towards using dynamic keys. I consider the setup described herein as absolute minimum, anything less is severe security malpractice.
A sidenote on the network setup. It's not necessary (and not wise too) to masquerade 192.168.3.0/24 (eth1:1) because it's solely used to integrate the Access Point and WLAN clients into the private network, hence it should be considered hostile. My corresponding netfilter rules listing:
#### SERVER #### root@hoth:~# iptables -L -t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination ACCEPT udp -- anywhere anywhere udp spt:bootps dpt:bootps ACCEPT udp -- anywhere anywhere udp spt:bootps dpt:bootpc ACCEPT udp -- anywhere 255.255.255.255 udp spt:bootpc dpt:bootps ACCEPT udp -- 192.168.3.0/24 hoth.rebelbase.local udp dpt:1196 ACCEPT udp -- 192.168.3.0/24 hoth.rebelbase.local udp dpt:1195 ACCEPT icmp -- 192.168.3.0/24 hoth.rebelbase.local icmp echo-request DROP all -- 192.168.3.0/24 anywhere Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- localnet/24 anywhere MASQUERADE all -- 10.0.0.0/8 anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination
That's pretty much it. I hope this little text helped you.
Still a work in progress...
[top]
[top]
Copyright © 2004 - 2010 markus reichelt.
If you want to contact me, send an email in plain text only to the address listed below; encrypted email is preferred. Have a look at my GnuPG Key Signing Policy.
Encrypted and anonymous message box available at https://privacybox.de/mareichelt.msg, or as Tor Hidden Service in case you prefer such a method of contact. Be advised that the subject will not be encrypted, only the text message itself. Also, in case you want a reply, please provide secure means of contact.
[top]
[ return to publications page ]
| markus reichelt <markus.reichelt@gmx.net>Last modified: 2006-05-01 | angstklausel - site policy - imprint | - Gegen Stasi 2.0 | - FSFE | - valid html | - valid CSS | - any browser |