【原創】Openvpn 在windows下使用使用者名稱/密碼驗證方式
阿新 • • 發佈:2019-01-30
網上找了很久,很少寫windows服務端下的情況。
搗鼓半天,終於在windows下測試通過,把過程寫在這裡,方便大家或自己以後查閱
首先,客戶端能通過證書成功連線到伺服器;這個網上很多,也很詳細,大家可以自己Google(非必須條件,此文只是在這個基礎上做的修改)
下面,開始;
首先,修改服務端配置檔案 server.ovpn,在檔案中加入
username-as-common-name
client-cert-not-required
script-security 3 system
auth-user-pass-verify checkpsw.exe via-env
注意 “auth-user-pass-verify checkpsw.exe via-env”中的checkpsw.exe根據自己的檔案作修改。
然後,修改客戶端配置檔案 client.ovpn ,在檔案中加入
auth-user-pass
並將 證書和金鑰行註釋掉,
;cert client.crt
;key client.key
注意,不要註釋了ca證書行。
上面使用的checkpsw.exe程式,原始碼如下 ,(這是網上找的,只是原作者寫的有點bug,在我的機子上沒有測試通過,我改了下,)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1024
int checkpsw(char *username, char *password)
{
FILE *f;
char user[MAX + 2], pass[MAX + 2], active[MAX + 2];
/* printf(“%s,%s\n”,username,password); */
if (!(f = fopen("userpwd", "r")))
{
perror("Open PASSWORD file error");
printf("The password file not found\n");
return -1;
}
while (!feof(f))
{
fscanf(f, "%s %s %s\n", user, pass, active);
//printf("user:%s pass:%s active:%s\n",user, pass, active);
if (strcmp(username, user)==0 && strcmp(password, pass)==0 && strcmp(active, "1")==0)
{
fclose(f);
return 0 ;
//驗證通過應該返回0;
}
}
fclose(f);
return 1;
}
int main()
{
int status;
/* printf(“%s,%s”,getenv(“USERNAME”),getenv(“PASSWORD”)); */
status = checkpsw(getenv("USERNAME"), getenv("PASSWORD"));
return status;
}
使用者名稱密碼檔案 userpwd格式:
使用者名稱 密碼 是否啟用(0/1) 中間用空格隔開
Username Password Enable
示例格式(一行一個):
Hslim 123456 1
Hslim2 123456 0
編譯後得到exe檔案,
將checkpsw.exe和userpwd放到config中,完工,測試通過!
Openvpn程式版本:2.3.6
另外,還可以連線到資料庫中,基本都一樣,附網上的一個Mysql資料庫的驗證程式原始碼:
int checkpsw(char *vpnuser, char *vpnpass)
{
char host[] = "localhost";
char username[] = "root";
char password[] = "";
char database[] = "openvpn";
MYSQL_RES * res_set;
unsigned int rownum;
conn = mysql_init(NULL);
if(mysql_real_connect(conn,
host,
username,
password,
database,
0, NULL, 0) != NULL)
;
else return(1);
string querywhat;
querywhat = querywhat+"select username from user where username= '"+vpnuser+"' and password = '"+vpnpass+ "' and active ='1' ";
if(mysql_query(conn,querywhat.c_str()))
return(0);
res_set = mysql_store_result(conn);
rownum=mysql_num_rows(res_set);
if (rownum==1)
return(0);
else return(1);
mysql_close(conn);
}
寫個主函式呼叫即可.