For a number of years now when on insecure network connections I have been routing my computer to the Internet through secure tunnels and VPNs, but I’ve been interested in trying out different types of VPN software lately so I can more easily help secure friends who ask of it. This would mainly include ease of installation and enabling, which partly requires no extra software for them to install.
Unfortunately, Windows 7 and Android (and probably most other software) only support PPTP and L2TP/IPSEC out of the box. While these protocols are good for what they do, everything I have read says OpenVPN is superior to them as a protocol. I was very frustrated to find out how little support OpenVPN actually has today as a standard in the industry, which is to say, you have to use third party clients and it is rarely, if ever, included by default in OSes. The OpenVPN client and server aren’t exactly the easiest to set up either for novices.
So on to the real point of this post. The sample client and server configurations for OpenVPN were set up just how I needed them except they did not include two important options for me: User authentication and full client Internet forwarding/tunneling/gateway routing. Here is how to enable both.
To set up username/password authentication on the server, an authorization script is needed that receives the username/password and returns whether the login information was successful (0) or failed (1). The steps to set up this process are as follows:
#!/usr/bin/php -q
<?
//Configuration
$ValidUserFile='users.txt'; //This file must be in htpasswd SHA1 format (htpasswd -s)
$Method='via-env'; //via-file or via-env (see auth-user-pass-verify configuration above for more information)
//Get the login info
if($Method=='via-file') //via-file method
{
$LoginInfoFile=trim(file_get_contents('php://stdin')); //Get the file that contains the passed login info from stdin
$LoginInfo=file_get_contents($LoginInfoFile); //Get the passed login info
file_put_contents($LoginInfoFile, str_repeat('x', strlen($LoginInfo))); //Shred the login info file
$LoginInfo=explode("\n", $LoginInfo); //Split into [Username, Password]
$UserName=$LoginInfo[0];
$Password=$LoginInfo[1];
}
else //via-env method
{
$UserName=$_ENV['username'];
$Password=$_ENV['password'];
}
//Test the login info against the valid user file
$UserLine="$UserName:{SHA}".base64_encode(sha1($Password, TRUE)); //Compile what the user line should look like
foreach(file($ValidUserFile, FILE_IGNORE_NEW_LINES) as $Line) //Attempt to match against each line in the file
if($UserLine==$Line) //If credentials match, return success
{
print "Logged in: $UserName\n";
exit(0);
}
//Return failure
print "NOT Logged in: $UserName\n";
exit(1);
?>