無料で構築するVPN(OpenVPN) Part.2

2013年5月22日

Part.1からの続きです。

TLS認証鍵をOpenVPN設定ファイル格納ディレクトリへ作成

# openvpn --genkey --secret /etc/openvpn/ta.key

OpenVPN設定ファイルをサンプルよりコピー

# cp -p /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf /etc/openvpn/

 OpenVPN設定ファイル編集

# vi /etc/openvpn/server.conf
---------------------------------------------------------
dev tun ←VPNインタフェースとしてTUNを指定(デフォルト)

server 10.8.0.0 255.255.255.0 ←VPNクライアント割当てアドレス範囲として10.8.0.0/24を指定(デフォルト)

;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
push "route 192.168.253.0 255.255.255.0" ←追加(ルーティング)

;push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway def1" ←追加(通信のGWをVPN経由にする)

push "dhcp-option DNS 192.168.1.1" ←追加(DHCPにてIP配布時にDNS情報を付与)

duplicate-cn ←コメント外す(同じ証明書で複数人接続可能とする)

tls-auth ta.key 0 # This file is secret ←行頭の";"を削除してコメント解除(TLS認証有効化)

user nobody ←行頭の";"を削除してコメント解除(OpenVPN実行権限を下げる)
group nobody ←行頭の";"を削除してコメント解除(OpenVPN実行権限を下げる)

status /var/log/openvpn-status.log ←追加(ログ)
log /var/log/openvpn.log ←追加(ログ)

management localhost 7505 ←最終行に追加(管理インターフェースの有効化)

crl-verify crl.pem ←最終行へ追加(証明書廃止リストの有効化) 
---------------------------------------------------------

証明書認証ではなく、ID/PW認証を行う場合は以下を追加

script-security 2
client-cert-not-required
username-as-common-name
auth-user-pass-verify /etc/openvpn/script/auth.php via-file

尚、ID/PW認証に利用するauth.phpは以下の内容となる。
今回はMySQLに格納したID/PWと認証を行う。
認証成功で"0″を返し、失敗であれば"1″を返す。
ちなみにクライアントが接続すると、平文で1行目にユーザ名、2行目にパスワードが流れる。
※駄作プログラムでよろしければお使いください。

 

#!/usr/bin/php
<?php
error_reporting(1);
define('DB_HOST','localhost');
define('DB_NAME','openvpn');
define('DB_USER','openvpn');
define('DB_PASS','********');
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASS);
if($conn == FALSE){ print("DB CONNECT FAILED"); exit;}
mysql_selectdb(DB_NAME);
mysql_query('SET NAMES utf8;');
$fp = @fopen("$argv[1]","r");
$count = 0;
while(!feof($fp)){
$tmp[$count] = fgets($fp);
$count++;
}
fclose($tmp);
$username = rtrim($tmp[0]);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($tmp[1]);
$password = hash('sha256',$password);
// User Auth
$str = "
select * from user_tbl
where
username = '$username' and password = '$password' and active = '1'
";
$res = mysql_query($str);
$num = @mysql_num_rows($res);
if($num != 0){
       echo "[OpenVPN] User: $username \n";
       echo "[OpenVPN] Authentication ok. \n";
       exit(0);
}else{
       echo "[OpenVPN] User: $username \n";
       echo "[OpenVPN] Authentication failed. \n";
       exit(1);
}
?>

 

ついでにユーザ作成とかパスワード変更とかプログラム(user.php)を作ってみた。

 

#!/usr/bin/php
<?php
error_reporting(1);
define('DB_HOST','localhost');
define('DB_NAME','openvpn');
define('DB_USER','openvpn');
define('DB_PASS','********');
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASS);
if($conn == FALSE){ print("DB CONNECT FAILED"); exit;}
mysql_selectdb(DB_NAME);
mysql_query('SET NAMES utf8;');
$mode = $argv[1];
if(!$mode){
        echo basename(__FILE__).": {add|passwd|active|del|email|list} \n";
}
switch ($mode){
        case "add":
                $username = mysql_real_escape_string($argv[2]);
                if(!$username){
                        echo("ユーザ名を入力してください \n");
                }else{
                        $str = "
                        select * from user_tbl
                         where
                          username = '$username'
                        ";
                        $res = mysql_query($str);
                        $num = @mysql_num_rows($res);
                        if($num == 0){
                                echo("パスワードを入力してください:");
                                $password1 = fgets(STDIN,1024);
                                echo("もう一度入力してください:");
                                $password2 = fgets(STDIN,1024);
                                if($password1 == $password2){
                                        $password = mysql_real_escape_string($password1);
                                        $password = hash('sha256',$password);
                                        $str = "
                                        insert into user_tbl
                                        (username,password)
                                        values
                                        ('$username','$password')
                                        ";
                                        $res = mysql_query($str);
                                        if(!res){
                                                echo("ユーザ追加にエラーが発生しました \n");
                                        }else{
                                                echo("ユーザ追加に成功しました \n");
                                        }
                                }else{
                                        echo("パスワードが一致しません \n");
                                        echo("もう一度行ってください \n");
                                }
                        }else{
                                echo("$username は既に存在します \n");
                        }
                }
        break;
        case "passwd":
                $username = mysql_real_escape_string($argv[2]);
                if(!$username){
                        echo("ユーザ名を入力してください \n");
                }else{
                        $str = "
                        select * from user_tbl
                         where
                          username = '$username'
                        ";
                        $res = mysql_query($str);
                        $num = @mysql_num_rows($res);
                        if($num != 0){
                                echo("パスワードを入力してください:");
                                $password1 = fgets(STDIN,1024);
                                echo("もう一度入力してください:");
                                $password2 = fgets(STDIN,1024);
                                if($password1 == $password2){
                                        $password = mysql_real_escape_string($password1);
                                        $password = hash('sha256',$password);
                                        $row = @mysql_fetch_assoc($res);
                                        $user_id = $row['user_id'];
                                        $str = "
                                        update user_tbl
                                        set
                                        password = '$password'
                                        where
                                        user_id = '$user_id'
                                        ";
                                        $res = mysql_query($str);
                                        if(!res){
                                                echo("パスワード変更にエラーが発生しました \n");
                                        }else{
                                                echo("パスワード変更に成功しました \n");
                                        }
                                }else{
                                        echo("パスワードが一致しません \n");
                                        echo("もう一度行ってください \n");
                                }
                        }else{
                                echo("$username は存在しません \n");
                        }
                }
        break;
        case "active":
                $username = mysql_real_escape_string($argv[2]);
                if(!$username){
                        echo("ユーザ名を入力してください \n");
                }else{
                        $str = "
                        select * from user_tbl
                         where
                          username = '$username'
                        ";
                        $res = mysql_query($str);
                        $num = @mysql_num_rows($res);
                        if($num != 0){
                                $row = @mysql_fetch_assoc($res);
                                $user_id = $row['user_id'];
                                $str = "
                                update user_tbl
                                set
                                active = '1'
                                where
                                user_id = '$user_id'
                                ";
                                $res = mysql_query($str);
                                if(!res){
                                        echo("ユーザ有効化処理にエラーが発生しました \n");
                                }else{
                                        echo("ユーザ有効化処理に成功しました \n");
                                }
                        }else{
                                echo "ユーザが存在しません \n";
                        }
                }
        break;
        case "del":
                $username = mysql_real_escape_string($argv[2]);
                if(!$username){
                        echo("ユーザ名を入力してください \n");
                }else{
                        $str = "
                        select * from user_tbl
                         where
                          username = '$username'
                        ";
                        $res = mysql_query($str);
                        $num = @mysql_num_rows($res);
                        if($num != 0){
                                $row = @mysql_fetch_assoc($res);
                                $user_id = $row['user_id'];
                                $str = "
                                update user_tbl
                                set
                                active = '0'
                                where
                                user_id = '$user_id'
                                ";
                                $res = mysql_query($str);
                                if(!res){
                                        echo("ユーザ無効化処理にエラーが発生しました \n");
                                }else{
                                        echo("ユーザ無効化処理に成功しました \n");
                                }
                        }else{
                                echo("ユーザが存在しません \n");
                        }
                }
        break;
        case "list":
                $str = "select * from user_tbl";
                $res = mysql_query($str);
                $num = @mysql_num_rows($res);
                if($num != 0){
                        echo "user_id \t username \t active \n";
                        while($row = @mysql_fetch_assoc($res)){
                                echo("$row[user_id] \t\t $row[username] \t $row[active] \n");
                        }
                }else{
                        echo("ユーザは存在しません \n");
                }
        break;
        case "email":
                $username = mysql_real_escape_string($argv[2]);
                if(!$username){
                        echo("ユーザ名を入力してください \n");
                }else{
                        $str = "
                        select * from user_tbl
                         where
                          username = '$username'
                        ";
                        $res = mysql_query($str);
                        $num = @mysql_num_rows($res);
                        if($num != 0){
                                echo("E-Mailアドレスを入力してください:");
                                $email1 = fgets(STDIN,1024);
                                echo("もう一度入力してください:");
                                $email2 = fgets(STDIN,1024);
                                if($email1 == $email2){
                                        $email = trim($email1);
                                        $email = mysql_real_escape_string($email);
                                        $row = @mysql_fetch_assoc($res);
                                        $user_id = $row['user_id'];
                                        $str = "
                                        update user_tbl
                                        set
                                        email = '$email'
                                        where
                                        user_id = '$user_id'
                                        ";
                                        $res = mysql_query($str);
                                        if(!res){
                                                echo("E-Mailアドレス変更にエラーが発生しました \n");
                                        }else{
                                                echo("E-Mailアドレス変更に成功しました \n");
                                        }
                                }else{
                                        echo("E-Mailアドレスが一致しません \n");
                                        echo("もう一度行ってください \n");
                                }
                        }else{
                                echo("$username は存在しません \n");
                        }
                }
        break;
}
?>

また記事が長くなってしまったので、Part.3へ続く。