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 n
A 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 ... rd-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: Select all
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
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: Select all
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
#####################################################
Let's get to the fun part.
The authentication script: vpn_auth
Code: Select all
#!/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.sh
Clientconnect.sh:
Code: Select all
#!/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
ClientDisconnect.sh is nearly the same:
Code: Select all
#!/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
The last script is for taking 1 VPN Minute from every users:
Code: Select all
#!/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
Code: Select all
* * * * * /etc/openvpn/server/vpntimeupdate &> /dev/null
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!