Welcome dear visitor. I decided to share my network/openvpn configuration, I hope I can help with it.

Starting:
I'm using OpenVPN to share my internet connection through transparent proxies ( Squid ). I have a website "connected" to OpenVPN. Let's name an user,
"Bob". He will walk us through this HowTo.
So Bob wants an encrypted, safe, communication tunnel, he decided to use OpenVPN, "unfortunately" Bob has a Squid proxy in his network, but he still wants to play online games for example.
In this HowTo, at the end Bob can play with online games, let's see how...
Ingredients:I'm using Ubuntu Server.
I wanted to store my users in MySQL Database, where I can see everything about them. I wanted to have a good looking website, so I decided to combine this 2 stuff. I'm using Wordpress CMS and it's MySQL
wp_users table to authenticate my OpenVPN clients. I've read OpenVPN can
Renegotiate users, so I've decided to use this great option. First I added a column to the wp_users table, called:
vpn_ido ( this stores ammount of time what users can use the VPN connection ). The OpenVPN option is:
--reneg-sec nA cron script takes 1 minute from vpn_ido column in every minute. If that time drops to 0, in 30 minutes the VPN Connection stops ( because of the reneg-sec ).
If you want to setup a Wordpress CMS site and you want to authenticate users from it's database, you will have to use a Wordpress Plugin too, because in linux
mysql command can't use that encryption what wordpress storing the passwords. That plugin can be found here:
http://wordpress.org/extend/plugins/md5-password-hashes/ So I'm using MD5 passwords now, authentication can be done easily later.
OpenVPN client/server config files:Let's start with the server:
Code:
mode server
tls-server
port 443
proto tcp
dev tun
topology subnet
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpnserver.crt
key /etc/openvpn/server/vpnserver.key
dh /etc/openvpn/server/dh2048.pem
script-security 2
username-as-common-name
auth-user-pass-verify "/etc/openvpn/server/vpn_auth" via-file
tmp-dir "/etc/openvpn/server/"
client-connect /etc/openvpn/server/clientconnect
client-disconnect /etc/openvpn/server/clientdisconnect
up /etc/openvpn/server/tuzfal_all
server 10.80.0.0 255.255.255.0
push "redirect-gateway def1"
push "dhcp-option DNS 10.80.0.1"
push "dhcp-option WINS 10.80.0.1"
inactive 600
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /etc/openvpn/server/onlineusers.log 5
management 127.0.0.1 1195 /etc/openvpn/server/telnet.passwd
verb 3
mute 10
reneg-sec 1800
Okay, as you can see I'm using
TCP mode and
port 443, because of the squid proxy. The topology is subnet. I'm authenticating via file, that's the part, where OpenVPN ( or the auth script ) decides if
Bob can use the VPN Tunnel ( Does he have enough
VPN time?
Is his account enabled? etc. )
I'm using the
client-connect option to set an Iptables port forwarding rule, and
client-disconnect script to remove that rule.
The
--up option runs the firewall script, what sets the masquerading ( internet sharing ) + some other rules, etc.
Let's see the client's config:
Code:
http-proxy PROXY.IP.ADDRESS.HERE PORT[
http-proxy-retry
http-proxy-option AGENT Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
########################################################################
### You can set an Interface name for your TUN/TAP interface - Only on Windows ###
########################################################################
# dev-node "TUN0"
remote SERVER.IP.ADDRESS.HERE LISTENING-PORT
remote DOMAINNAME LISTENING-PORT
remote-random
client
dev tun
proto tcp
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert skyvpnclient.crt
key skyvpnclient.key
dh dh2048.pem
comp-lzo
verb 1
mute 5
auth-user-pass
ns-cert-type server
#####################################################
auth-user-pass ask for the client's Username ( his common-name ) and the password.
Let's get to the fun part. The authentication script:
vpn_authCode:
#!/bin/bash
### Database Informations
DBUSER='vpnadmin'
DBPASS='vpnadmin_jelszava'
DBHOST='localhost'
DBNAME='vpnusers'
### OpenVPN get's send the filename to the script, with the script's first parameter = $1
### The file contains 2 lines, Username and Password what the client sent to the server ( --auth-user-pass )
### When the script finished, the file will be removed
vpnnev=`head -n1 $1 | tail -1` # Get the First line -> Username
vpnjelszo=`head -n2 $1 | tail -1 ` # Get the Second line -> Password
### Name + Password, VPN Time and VPN Account verify ( Does Bob have any VPN Time left? Is his account enabled? )
sqlnev=`mysql -u $DBUSER -p$DBPASS -h $DBHOST --skip-column-name -e "SELECT users.nev FROM users WHERE ( (users.vpnido > 0) AND (users.aktiv = 'yes') AND (users.nev = '$vpnnev') AND (users.jelszo = PASSWORD('$vpnjelszo')) );" $DBNAME`
### If the MySQL Query failed, the "sqlnev" variable contains nothing! If the "sqlnev" contains Bob's username,
## we are good to go! If this script exit with errorcode 0, that means the script is successful, OpenVPN will
## let Bob to use the VPN Tunnel, he is Authenticated.
## If the exit code IS NOT "0", Bob wont be authenticated, OpenVPN will destroy the tunnel.
##
if [ "$sqlnev" == "$vpnnev" ]; then
exit 0
else
exit 1
fi
I have 2 another event scripts called:
clientconnect.sh and
clientdisconnect.shClientconnect.sh:
Code:
#!/bin/bash
IPTABLES='/sbin/iptables'
### Adatbázis Adatok
DBUSER='vpnadmin'
DBPASS='vpnadmin_jelszava'
DBHOST='localhost'
DBNAME='vpnusers'
PORT=`mysql -u $DBUSER -p$DBPASS -h $DBHOST -e "SELECT users.port FROM users WHERE ( users.nev = '$common_name' )" --skip-column-name $DBNAME`
$IPTABLES -A FORWARD -p udp -i eth0 -d $ifconfig_pool_remote_ip --dport $PORT -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth0 -d $ifconfig_pool_remote_ip --dport $PORT -j ACCEPT
$IPTABLES -t nat -A PREROUTING -p udp -i eth0 --dport $PORT -j DNAT --to $ifconfig_pool_remote_ip:$PORT
$IPTABLES -t nat -A PREROUTING -p tcp -i eth0 --dport $PORT -j DNAT --to $ifconfig_pool_remote_ip:$PORT
It's an easy PortForwarding Rule. Every user has 1 Forwarded port. The port number can be found in the MySQL Database too ( users.port )
ClientDisconnect.sh is nearly the same:
Code:
#!/bin/bash
IPTABLES='/sbin/iptables'
### Adatbázis Adatok
DBUSER='vpnadmin'
DBPASS='vpnadmin_jelszava'
DBHOST='localhost'
DBNAME='vpnusers'
PORT=`mysql -u $DBUSER -p$DBPASS -h $DBHOST -e "SELECT users.port FROM users WHERE ( users.nev = '$common_name' )" --skip-column-name $DBNAME`
$IPTABLES -D FORWARD -p udp -i eth0 -d $ifconfig_pool_remote_ip --dport $PORT -j ACCEPT
$IPTABLES -D FORWARD -p tcp -i eth0 -d $ifconfig_pool_remote_ip --dport $PORT -j ACCEPT
$IPTABLES -t nat -D PREROUTING -p udp -i eth0 --dport $PORT -j DNAT --to $ifconfig_pool_remote_ip:$PORT
$IPTABLES -t nat -D PREROUTING -p tcp -i eth0 --dport $PORT -j DNAT --to $ifconfig_pool_remote_ip:$PORT
These are removing the portforwarding firewall rules.
The last script is for taking 1 VPN Minute from every users:
Code:
#!/bin/bash
### Adatbázis Adatok
DBUSER='vpnadmin'
DBPASS='vpnadmin_jelszava'
DBHOST='localhost'
DBNAME='vpnusers'
### Csak azon kliensek idejét csökkentjük 1-el, akik aktívak.
mysql -u $DBUSER -p$DBPASS -h $DBHOST -e "UPDATE users SET users.vpnido = users.vpnido - 1 WHERE ( users.vpnido > 0 ) AND ( users.aktiv = 'yes' )" $DBNAME
This can be easily done, with a cronjob:
Code:
* * * * * /etc/openvpn/server/vpntimeupdate &> /dev/null
Some advices:You can sharing internet connection with iptables, Search the OpenVPN's documentation ( or google ). In these scripts mysql commands are just examples, you have to create your own database, with your own table rows and colums! ( Wordpress is very easy, just add more colums, and you are good to go )
I hope you like this short howto, please take a Vote and feel free to post a comment!