OpenVPN server on Fedora 16 connecting Cyanogenmod (7.1) Android phone [bridged]
I have already posted about openVPN on Ubuntu but the config for Fedora is a little different so here’s a updated post. I did the following setup using
I’ve used this quite a lot and its been very stable 😀 Have to say OpenVPN is pretty awesome. Seems very stable even when transitioning between 2G & 3G.
There is a more up to date version of this topic [here]. It shows how to configure a routed connection but that is the recommended connection type unless you need bridged.
First of all we need to make sure we have bridge-utils and the OpenVPN package installed.
yum install -y openvpn bridge-utils
For this to work we need to create a logical bridge interface and then add physical interfaces to the bridge. So first we create a file
/etc/sysconfig/network-scripts/ifcfg-br0 and add the following:
DEVICE=br0 TYPE=Bridge ONBOOT=yes BOOTPROTO=static IPADDR=10.10.10.21 NETMASK=255.255.255.0 GATEWAY=10.10.10.21 DELAY=0 STP=off
Save the file and open the file
/etc/sysconfig/network-scripts/ifcfg-Wired_connection_1 (file names may vary depending on the setup of your machine). Basically we want to remove IP addressing and add it to the bridge group. Change this file accordingly (there’s no need to change the HWADDR info that’s already there)
HWADDR=BE:EF:BE:EF:BE:EF TYPE=Ethernet BOOTPROTO=none ONBOOT=yes BRIDGE=br0
Now we should be able to restart the network service and have full connectivity to/from the server.
service network restart
If you still can browse to/from the server as usual dont carry on any further something is b0rked. Check /etc/resolve.conf has valid DNS servers etc.
Now we need to generate certificates for our server to use. OpenVPN comes with some scripts to take most of the pain out of this. To keep things where I can find them I like to move these to
/etc/openvpn/easy-rsa. First off we make a new directory and copy the scripts into it.
mkdir /etc/openvpn/easy-rsa cd /etc/openvpn cp -R /usr/share/openvpn/easy-rsa/2.0/* easy-rsa/ cd easy-rsa
Edit the following in the vars file of this directory
export KEY_COUNTRY="UK" export KEY_PROVINCE="M0" export KEY_CITY="m00nieTown" export KEY_ORG="m00nie.co" export KEY_EMAIL="firstname.lastname@example.org"
Now just run the following commands
source ./vars ## execute your new vars file ./clean-all ## Setup the easy-rsa directory (Deletes all keys) ./build-dh ## takes a while consider backgrounding ./pkitool --initca ## creates ca cert and key ./pkitool --server server ## creates a server cert and key cd keys openvpn --genkey --secret ta.key ## Build a TLS key sudo cp server.crt server.key ca.crt dh1024.pem ta.key ../../ cd ../..
Create a directory and two files. One called ifup.sh and one called ifdown.sh. These will be used to control bringing the interfaces up/down and should contain the following.
mkdir /etc/openvpn/ifupdown touch /etc/openvpn/ifupdown/ifup.sh touch /etc/openvpn/ifupdown/ifdown.sh sudo chmod +x /etc/openvpn/ifupdown/ifup.sh /etc/openvpn/ifupdown/ifdown.sh
#!/bin/sh BR=$1 DEV=$2 MTU=$3 /sbin/ip link set "$DEV" up promisc on mtu "$MTU" /usr/sbin/brctl addif $BR $DEV
#!/bin/sh BR=$1 DEV=$2 /usr/sbin/brctl delif $BR $DEV /sbin/ip link set "$DEV" down
Now to edit the /etc/openvpn/server.conf file. Mine looks like the following
mode server tls-server local 10.10.10.21 ## ip/hostname of server port 12345 ## My Custom port proto udp #bridging directive dev tap0 ## If you need multiple tap devices, add them here up "/etc/openvpn/ifupdown/ifup.sh br0" down “/etc/openvpn/ifupdown/ifdown.sh br0″ persist-key persist-tun #certificates and encryption ca ca.crt cert server.crt key server.key # This file should be kept secret dh dh1024.pem tls-auth ta.key 0 # This file is secret cipher BF-CBC # Blowfish (default) comp-lzo #DHCP Information ifconfig-pool-persist ipp.txt server-bridge 10.10.10.21 255.255.255.0 10.10.10.240 10.10.10.250 push “dhcp-option DNS 188.8.131.52″ push “dhcp-option DOMAIN m00nie.com” max-clients 10 ## set this to the max number of clients that should be connected at a time #log and security user nobody group nogroup keepalive 10 120 status openvpn-status.log script-security 2 ## This needed added verb 4 ##Changed the logging level
You should be able to run the server with the following command and recieve no errors. If you do fix them first
openvpn --config server.conf --script-security 2
If it all looks good lets make OpenVPN run as a service and start when the server boots
systemctl start openvpn.service systemctl enable openvpn.service
We need to create some certificates for our client (the phone)
cd /etc/openvpn/easy-rsa source ./vars ## execute the vars file ./pkitool phone ## create a cert and key named "phone"
Now to make it easy to import to my phone I made a p12 file
cd keys openssl pkcs12 -export -in phone.crt -inkey phone.key -certfile ca.crt -out phone.p12 mv phone.p12 /var/www/html
Now browse to the file on your phone E.g
http://10.10.10.21/phone.p12. Your phone will then store the certificates into is credential store 🙂 Finally we configure the VPN under Settings > Wireless & networks > VPN settings > Add VPN like so
The main config:
Menu > Advanced OpenVPN Settings:
At the moment there is no gui setting to configure tls-auth but they did give us the Extra arguments option. In here I added (I used FTP to copy the ta.key file to the phone in a directory called VPN.
--tls-auth /mnt/sdcard/VPN/ta.key 1 --explicit-exit-notify 2
Time for some evil NAT. The basic syntax is
ip nat inside source static udp <fedora server IP> <server port> interface <outside address> <some port>
so mine was
ip nat inside source static udp 10.10.10.21 12345 interface dialer 0 12345
Now we can see the static translation:
m00nies_router#show ip nat translations Pro Inside global Inside local Outside local Outside global udp 192.168.1.1:12345 10.10.10.21:12345 --- ---
Now the port is forwarding to the OpenVPN server but my zone based firewall config is dropping the packets.
Apr 13 18:14:04.136: %FW-6-DROP_PKT: Dropping udp session 172.16.1.1 10.1.1.10:12345 on zone-pair out-in class class-default due to DROP action found in policy-map with ip ident 0
At the moment there is no explicit zone-pair for outside to inside so the default is deny all. Lets define one
m00nies_router#conf t Enter configuration commands, one per line. End with CNTL/Z. m00nies_router(config)#access-list 199 permit udp any any eq 12345 m00nies_router(config)#class-map type inspect match-all OPENVPN m00nies_router(config-cmap)# match access-group 199 m00nies_router(config-cmap)# exit m00nies_router(config)#policy-map type inspect OPENVPN_POLICY m00nies_router(config-pmap)#class type inspect OPENVPN m00nies_router(config-pmap-c)#pass log m00nies_router(config-pmap-c)#exit m00nies_router(config-pmap)#exit m00nies_router(config)#zone-pair security out-in source out-zone destination in-zone m00nies_router(config-sec-zone-pair)# service-policy type inspect OPENVPN_POLICY m00nies_router(config-sec-zone-pair)#^Z m00nies_router#
First off we classify the traffic we want the allow it to pass but log it. Next we apply that policy to a zone pair. Theres more info about configuring ZBFW [here]. Below we can see the default that catches all other traffic is still drop.
m00nies_router#show policy-map type inspect OPENVPN_POLICY Policy Map type inspect OPENVPN_POLICY Class OPENVPN Pass log Class class-default Drop
Now we can try our VPN access.
It passes the router ok
Apr 13 18:31:00.085: %FW-6-PASS_PKT: (target:class)-(out-in:OPENVPN) Passing udp pkt 172.16.1.1:52585 => 10.10.10.21:12345 with ip ident 0
And the OpenVPN server logs confirm it works ok too. Its been very stable on both 2 and 3G.