[Closed] Authenticating OpenVPN clients from Wordpress database

OpenVPN tutorials ranging from configuration to hacks to compilation will be posted here.
Locked
Gorkhaan
OpenVPN User
Posts: 11
Joined: Wed Mar 03, 2010 11:28 am

[Closed] Authenticating OpenVPN clients from Wordpress database

Post by Gorkhaan » Sun Jun 02, 2013 2:55 pm

Hello there.

Let me share my project's setup, what I decided to cancel due to low interest from my old clients. :)

How does it works?
  • Clients will be authenicated via username/password, what are actually stored in Wordpress.
  • We add 2 fields to "wp_users" table to enable vpncredit system. Meaning every client will have a field what contain a number. This number is decreased by one in every minute, using crontab. Let's call this vpncredits.
  • We will use a command line php script, to check the OpenVPN Username/Password with the corresponding fields in the Wordpress database.
  • There is a bash script what helps to solve this. (you can rewrite this to only PHP if you wish)
  • We will set up crontab to decrease vpncredits in every minute
  • This setup is based on TCP connection. But you can reconfigure it to UDP if needed. I set it up as TCP for Proxy capabilities.
  • Plus a few tips and files at the end.
This was the old setup, I changed a few things:
topic3158.html?hilit=wordpress

Changelog:
  • Using latest Wordpress
  • Wordpress password hash is not modified like it was before (to MD5). So it's more secure now.
  • Only two colums had to be added to "wp_users" table, to enable "credit system"
  • Easier to understand and set up
  • More places where monitoring and logging can be set up
  • Comments and this step-by-step howto
HOW TO
  • Install and set up Wordpress:
  • Install OpenVPN + creating Certs:
    • apt-get install openvpn
    • cd /etc/openvpn
    • cp -ra /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/easy-rsa
    • cd easy-rsa
    • <EDIT "vars" FILE>
    • ln -s openssl-1.0.0.cnf openssl.cnf
    • source ./vars
    • ./clean-all
    • ./build-ca
    • ./build-key-server vpnserver
    • ./build-key vpnclient
    • ./build-dh dh2048.pem # 2048 if you set this up in "vars"
    Copying keys, setting up config dir structure:
    • cd /etc/openvpn
    • mkdir {vpnserver,vpnclient}
    • cp easy-rsa/keys/ca.crt easy-rsa/keys/vpnserver.key easy-rsa/keys/vpnserver.crt easy-rsa/keys/dh2048.pem vpnserver
    • cp easy-rsa/keys/ca.crt easy-rsa/keys/vpnclient.crt easy-rsa/keys/vpnclient.key vpnclient/
    • That's how it should look like for now:

      Code: Select all

      root@skyvpn:/etc/openvpn# tree vpnserver/ vpnclient/
      vpnserver/
      ├── ca.crt
      ├── dh2048.pem
      ├── vpnserver.crt
      └── vpnserver.key
      vpnclient/
      ├── ca.crt
      ├── vpnclient.crt
      └── vpnclient.key
    • Copy "vpnserver.conf" to "/etc/openvpn/vpnserver/vpnserver.conf"

      Code: Select all

      mode server
      tls-server
      port 443
      # local x.x.x.x # We can bind to a specific address
      proto tcp
      dev tun
      
      topology subnet 
      
      ca /etc/openvpn/vpnserver/ca.crt
      cert /etc/openvpn/vpnserver/vpnserver.crt
      key /etc/openvpn/vpnserver/vpnserver.key
      dh /etc/openvpn/vpnserver/dh1024.pem
      
      script-security 2
      username-as-common-name
      auth-user-pass-verify "/etc/openvpn/vpnserver/vpnauth-helper.sh" via-file
      tmp-dir "/etc/openvpn/vpnserver/"
      
      up "/etc/openvpn/vpnserver/firewall-nat.sh up"
      down "/etc/openvpn/vpnserver/firewall-nat.sh down"
      
      server 10.90.0.0 255.255.255.0
      push "redirect-gateway def1"	# Redirecting all traffic to VPN
      push "dhcp-option DNS 8.8.8.8"
      # push "dhcp-option DOMAIN mydomain.ltd"
      
      #push "shaper 1310720"
      #shaper 1310720
      
      #port-share x.x.x.x 3128	# Port share for 443 HTTPS data
      
      inactive 600
      tcp-nodelay
      
      keepalive 10 120
      comp-lzo
      
      persist-key
      persist-tun
      
      status /etc/openvpn/vpnserver/onlineusers.log 5
      status-version 1
      ifconfig-pool-persist /etc/openvpn/vpnserver/fixip.txt 0
      #management 127.0.0.1 1195 /etc/openvpn/vpnserver/telnet.passwd
      
      verb 3
      mute 10
      reneg-sec 1800
      
    • Copy "vpnclient.ovpn" to "/etc/openvpn/vpnclient/vpnclient.ovpn"
    • Generate a badass ASCI Art text :) : http://patorjk.com/software/taag/#p=dis ... ig&t=MyVPN

      Code: Select all

      ######################################
      #  __  __    __      _______  _   _  #
      # |  \/  |   \ \    / /  __ \| \ | | #
      # | \  / |_   \ \  / /| |__) |  \| | #
      # | |\/| | | | \ \/ / |  ___/| . ` | #
      # | |  | | |_| |\  /  | |    | |\  | #
      # |_|  |_|\__, | \/   |_|    |_| \_| #
      #          __/ |                     #
      #         |___/                      #
      ######################################
      
      #### Proxy ####
      # http-proxy 111.111.111.111	3128
      # http-proxy-retry 
      # http-proxy-option AGENT Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1) 
      
      #
      # If you would like to use autologin
      # comment out "auth-user-pass" and
      # uncomment "auth-user-pass autologin.txt".
      # Then fill "autologin.txt" with your credentials.
      # See example in "autologin.txt"
      #
      
      auth-user-pass
      
      #### AUTO LOGIN ####
      # auth-user-pass autologin.txt
      
      
      #################################
      ## DO NOT MODIFY THESE OPTIONS ##
      #################################
      remote vpnserver1.mydomain.ltd 443
      #remote vpnserver2.mydomain.ltd 443
      #remote vpnserver2.mydomain.ltd 443
      
      #remote-random
      
      client
      dev tun
      proto tcp
      resolv-retry infinite
      nobind
      persist-key 
      persist-tun 
      ca ca.crt 
      cert vpnclient.crt 
      key vpnclient.key
      comp-lzo no 
      verb 1 
      mute 5
      ns-cert-type server
      mute-replay-warnings
      script-security 2
      #################################
      #################################
      
  • Modify Wordpress "wp_users" table to enable credit system (vpncredits).
    • Use phpMyAdmin or CLI and run this query:

      Code: Select all

      ALTER TABLE  `wp_users` ADD  `vpn_credit` INT NOT NULL DEFAULT  '0',
      ADD  `vpn_enabled` BOOLEAN NOT NULL DEFAULT  '1'
  • Copy "vpnauth-helper.sh" to "/etc/openvpn/vpnserver/vpnauth-helper.sh"

    Code: Select all

    #!/bin/bash
    
    #
    # vpnauth.php helper bash script. -- Dorian Ocsovszki (2013-05-27)
    #
    #
    # It reads openvpn tempfile for username and password
    # and sends it to php script. This script can send back 3 results:
    #
    #	 "xOKx" or "xWRONGUSERx" or "xWRONGPASSx"
    #
    # "xOKx" tells OpenVPN that the user can proceed with the connection,
    #  while the other results will disconnect the user
    #
    # Keep this "vpnauth-helper.sh" and "vpnauth.php" in one directory!
    #
    #################
    ### Variables ###
    #################
    
    TMPFILE="${1}"			# OpenVPN temp file
    WPPATH="/var/www-sites/skyvpn"	# Use full path here, _without_ last slash "/"
    
    #################
    
    # Get basedir for "vpnauth.php"
    BASEDIR=$(dirname $0)
    
    VPNUSER="`head -n1 ${TMPFILE} | tail -n1`" # first line
    VPNPASS="`head -n2 ${TMPFILE} | tail -n1`" # second line
    
    # Getting results from PHP script
    RESULT="`php5 ${BASEDIR}/vpnauth.php "${WPPATH}" "${VPNUSER}" "${VPNPASS}"`"
    
    #echo "$RESULT"
    
    # Decision and Logging/Monitoring
    if [ "${RESULT}" == "xOKx" ]; then
    	# logging or monitoring here?
    	# Connect
    	exit 0
    fi
    
    if [ "${RESULT}" == "xWRONGUSERx" ]; then
    	# logging or monitoring here?
    	# Disconnect
    	exit 1
    fi
    
    if [ "${RESULT}" == "xWRONGPASSx" ]; then
    	# logging or monitoring here?
    	# Disconnect
    	exit 1
    fi
    
    
    # No usable ${RESULT}?
    # Probably an error, let's disconnect
    # logging or monitoring here?
    exit 1
    
    
  • Copy "vpnauth.php" to "/etc/openvpn/vpnserver/vpnauth.php" (The Magic!)

    Code: Select all

    <?php
    
    //==================================================================
    // OpenVPN username, password and vpn-credit based authentication
    //		Dorian Ocsovszki (2013-05-27)
    //==================================================================
    //
    // VPN Credits are minutes.
    // A script decreases "vpn_credit" by 1, if "vpn_enabled" is TRUE
    //
    //
    // This is how it works:
    //
    //	IF ( (user exists == true) AND (vpn_enabled == true) AND (vpn_credit > 0) ) THEN
    //		Connecting to VPN is authorized
    //	ELSE
    //		Connection to VPN is not authorized
    //
    //
    // Extend "wp_users" table to use "VPN Capabilities"
    //
    // ALTER TABLE  `wp_users` ADD  `vpn_credit` INT NOT NULL DEFAULT  '0', ADD  `vpn_enabled` BOOLEAN NOT NULL DEFAULT  '1'
    //
    //==================================================================
    
    //set_time_limit( 0 );
    //ini_set( "memory_limit", "64M" );
    $_SERVER['HTTP_HOST'] = 'wp_'; 	  // apache and table prefix: "wp_" is the default
    
    ob_start();
    
    // Getting variables arguments
    $wordpressdir = $argv[1];
    $openvpn_user = $argv[2];
    $openvpn_pass = $argv[3];
    
    
    require_once( $wordpressdir . '/wp-load.php' ); // you need to adjust this to your path
    //require_once( '/var/www/mysite/wp-load.php' ); // you need to adjust this to your path
    
    
    // If the query returns username, this user can connect to VPN AFTER PASSWORD CHECK. That's next.
    $userresult = $wpdb->get_var( "SELECT user_login FROM wp_users WHERE ( (vpn_credit > 0) AND (vpn_enabled = 1) AND (user_login = '$openvpn_user') );" );
    
    
    // If not empty
    if ($userresult) {
    	$user = get_user_by('login', "$userresult");
    
    	if ( wp_check_password( "$openvpn_pass", $user->data->user_pass, $user->ID) )
    	   // Password match
    	   echo "xOKx";
    	else
    	  // Wrong password
    	   echo "xWRONGPASSx";
    
    	} else {
    	// Woops. User not found
    	echo "xWRONGUSERx";
    }
    
    ?>
    
    
  • Modify permissions:
    • chmod +x /etc/openvpn/vpnserver/vpnauth-helper.sh /etc/openvpn/vpnserver/vpnauth.php
  • Copy "vpn-credit-update.sh" to "/etc/openvpn/vpnserver/vpn-credit-update.sh"
    • Code: Select all

      #!/bin/bash
      
      #
      # Decreasing "vpn_credit" field value by one every minute using crontab
      #
      
      DBUSER='mywordpressuser'
      DBPASS='mywordpressuserpassword'
      DBHOST='localhost'
      DBNAME='mywordpressdb'
      
      mysql -u $DBUSER -p$DBPASS -h $DBHOST -e "UPDATE wp_users SET vpn_credit = vpn_credit - 1 WHERE ( vpn_credit > 0 ) AND ( vpn_enabled = '1' )" $DBNAME
      
    • Adjust permissions: (We store db password here!)
    • chmod 700 /etc/openvpn/vpnserver/vpn-credit-update.sh
    • Set up a cronjob to run "vpn-credit-update.sh"
    • crontab -e

      Code: Select all

      SHELL=/bin/bash
      PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
      
      # Decreasing credits every minute
      * * * * * /etc/openvpn/skyvpnserver/vpn-credit-update.sh &> /dev/null
      
  • Copy "firewall-nat.sh" to "/etc/openvpn/vpnserver/firewall-nat.sh"
    • Code: Select all

      #!/bin/bash
      
      TODO="${1}"
      
      if [ "${TODO}x" == "upx" ]; then
      	echo "1" > /proc/sys/net/ipv4/ip_forward
      	iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o eth0 -j MASQUERADE
      fi
      
      if [ "${TODO}x" == "downx" ]; then
      	iptables -t nat -D POSTROUTING -s 10.90.0.0/24 -o eth0 -j MASQUERADE
      fi
      
    • Adjust permissions:
    • chmod 764 /etc/openvpn/vpnserver/firewall-nat.sh
  • That's how it should look like now:

    Code: Select all

    root@skyvpn:/etc/openvpn# tree vpnserver/ vpnclient/
    vpnserver/
    ├── ca.crt
    ├── dh1024.pem
    ├── firewall-nat.sh
    ├── onlineusers.log
    ├── skyvpnserver.conf
    ├── skyvpnserver.crt
    ├── skyvpnserver.key
    ├── vpnauth-helper.sh
    ├── vpnauth.php
    └── vpn-credit-update.sh
    vpnclient/
    ├── ca.crt
    ├── vpnclient.crt
    ├── vpnclient.key
    └── vpnclient.ovpn
    
How to connect and test:
  • Update "wp_users" table, add vpncredits to users
  • Try to connect. Be aware that you use good connection informations in client config.
  • Enjoy

Few ideas: Enjoy!

#
# My Blog: http://ocsovszki-dorian.blogspot.co.uk/
#

arielhangad
OpenVpn Newbie
Posts: 4
Joined: Tue Mar 24, 2015 12:17 pm

Re: Authenticating OpenVPN clients from Wordpress database

Post by arielhangad » Tue Mar 24, 2015 3:39 pm

Hi Gorkhaan is this working right now? Can you teachme how to do that, specially setup, install and creating openvpn config tcp 433 port for free internet browsing in windows, ios and android, please help me. This is my email address: arielhangad15@gmail.com

paule3d
OpenVpn Newbie
Posts: 1
Joined: Mon Feb 13, 2017 1:34 pm

Re: Authenticating OpenVPN clients from Wordpress database

Post by paule3d » Mon Feb 13, 2017 1:36 pm

This seems to be working, each step works, but OpenVPN is not authing.

If I change the scripts and put the variables manually and run it from command line, a result is echoed.

But when I try to log in via OpenVPN client, I am not authorised.

I know the script is running and being passed username (and presumably password) as I can monitor MysqL and see the query being run and the username being used.

Any ideas please?

Thanks

User avatar
TinCanTech
OpenVPN Protagonist
Posts: 2828
Joined: Fri Jun 03, 2016 1:17 pm

Re: Authenticating OpenVPN clients from Wordpress database

Post by TinCanTech » Tue Feb 14, 2017 2:22 pm

This thread is old and there is an error:
SERVER
script-security 3
This is required for the --auth-user-pass-verify script.

Locked