红联Linux门户
Linux帮助

OpenVPN使用“用户名/密码”登录验证

发布时间:2014-11-29 15:14:16来源:linux网站作者:gxjluck

使用这种方法在客户端需要"ca.crt、ta.key"和配置文件。
服务端需要"dh1024.pem、openvpn-auth-pam.so、ca.crt"服务端的证书和私钥以及配置文件。
服务端也并不需要ca.key,生成证书时需要。

openvpn-auth-pam.so由OpenVPN的plugin/auth-pam/目录下的文件生成。
ta.key使用OpenVPN生成:openvpn --genkey --secret keys/ta.key。是为了防止恶意攻击(如DoS、UDP port flooding),生成的一个"HMAC firewall"。

别的文件都是由easy-rsa目录下的脚本生成的(都是使用openssl生成的)。
dh1024.pem:Diffie-Hellman文件,SSL/TLS server需要使用的一个文件。脚本:build-dh。

证书的有效期我的试验是最长30年。
./build-key-server 设100年出来的是1970年,设50年出来的是"Bad time value"设40年,出来的是13年,设20年,正确;30年正确;35年13年


Server端配置

首先检查pam-devel包是否安装,否则从系统盘安装改软件包
[root@vpn ~]# rpm -qa | grep pam
pam_smb-1.1.7-3.1
pam-0.77-40
pam_krb5-2.0.10-1
pam-devel-0.77-40
[root@vpn ~]#

检查Mysql是否安装,确认mysql-devel包已经安装,否则从系统盘安装改软件包
[root@vpn ~]# rpm -qa | grep mysql
mysql-3.23.58-9
mysql-server-3.23.58-9
mysql-devel-3.23.58-9
[root@vpn ~]#


安装
在"添加或删除软件包"中选上"SQL数据库服务器"的全部内容,安装,用rpm -qa | grep mysql查询,无mysql-devel包。
mysql-devel包在RedHat 9.0第二张光盘上,RedHat/RPMS/mysql-devel-3.23.54a-11.i386.rpm。

为了能使用OpenVPN的PAM验证插件,我们安装pam_mysql使用MySQL数据库存储用户数据,其它数据库可以找相应的PAM验证模块
[root@vpn ~]# wget
[root@vpn ~]# tar -zxvf pam_mysql-0.5.tar.gz
[root@vpn ~]# cd pam_mysql
[root@vpn ~]# ./configure
[root@vpn ~]# make
[root@vpn ~]# cp pam_mysql.so /lib/security/
我下载的是pam_mysql-0.7RC1.tar.gz。
make时md5.h报错。
解决方法是
./configure --with-openssl
pam_mysql.so在.libs目录下,.libs为隐藏目录。


配置数据库
以管理员身份登录数据库:
mysql> create database vpn;
创建数据库vpn。
mysql> GRANT ALL ON vpn.* TO vpn@localhost IDENTIFIED BY 'vpn123';
授权localhost上的用户vpn(密码vpn123)有对数据库vpn的所有操作权限。
mysql> flush privileges;
更新sql数据库的权限设置。
mysql> use vpn;
使用刚创建的的vpn数据库。
mysql> CREATE TABLE vpnuser (
-> name char(20) NOT NULL,
-> password char(128) default NULL,
-> active int(10) NOT NULL DEFAULT 1,
-> PRIMARY KEY (name)
-> );
mysql> insert into vpnuser (name,password) values('elm',password('elm'));

命令解释:
#创建vpn用户,对vpn这个database有所有操作权限,密码为vpn123
#active不为1,无权使用VPN
#增加用户 用户名:elm 密码:elm

输入mysql报:
ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
/etc/rc.d/init.d/mysqld status会告诉mysql的运行状态,如果没有运行,执行下列命令:
/ect/rc.d/init.d/mysqld start
测试: mysql
如果成功,屏幕显示
>mysql
上面两条命令也可以是:
service mysqld status
service mysqld start
/etc/init.d/是指向/etc/rc.d/init.d的符号链接。
这一目录下的文件是脚本文件。
也可以使用"系统设置/服务器设置/服务"来设置。
自动启动mysqld,运行chkconfig把MySQL添加到系统的启动服务组里面去。
# /sbin/chkconfig --del mysqld
# /sbin/chkconfig --add mysqld
都可以使用可视化界面来配置。


配置pam_mysql模块
创建/etc/pam.d/openvpn文件,文件内容如下:
CUT Here
auth sufficient pam_mysql.so user=vpn passwd=vpn123 host=localhost db=vpn \
table=vpnuser usercolumn=name passwdcolumn=password \
where=active=1 sqllog=0 crypt=2
account required pam_mysql.so user=vpn passwd=vpn123 host=localhost db=vpn \
table=vpnuser usercolumn=name passwdcolumn=password \
where=active=1 sqllog=0 crypt=2
Cut Here
crypt(0) -- Used to decide to use MySQL's PASSWORD() function or crypt()
0 = No encryption. Passwords in database in plaintext. NOT recommended!
1 = Use crypt
2 = Use MySQL PASSWORD() function
下面可以测试pam_mysql是否工作正常,先检查saslauthd是否安装:
[root@vpn ~]# rpm -qa | grep sasl
cyrus-sasl-plain-2.1.18-2
cyrus-sasl-md5-2.1.18-2
cyrus-sasl-devel-2.1.18-2
cyrus-sasl-2.1.18-2
[root@vpn ~]#
有cyrus-sasl-2.1.18-2应该就可以了,如果没有请安装相应的软件包,不安装也行,可以通过其它方法测试

[root@vpn ~]# saslauthd -a pam
[root@vpn ~]# testsaslauthd -u elm -p elm -s openvpn
0: OK "Success."
[root@vpn ~]#
恭喜,pam_mysql工作正常了,下面可以开始配置OpenVPN服务器了。

输入testsaslauthd,报:command not found.。
SASL (Simple Authentication Security Layer),The Cyrus project is the implementation of an enterprise mail system by the Carnegie Mellon University Computing Services Department.
下载cyrus-sasl-2.1.22.tar.gz
解压./configure --with-saslauthd= /var/run/saslauthd; cd saslauthd; make testsaslauthd; cp testsaslauthd /usr/sbin
执行saslauthd -a pam; testsaslauthd -u elm -p elm -s openvpn 口令验证不成功。
执行如下命令验证成功:
/etc/init.d/saslauthd start 或 service saslauthd start
testsaslauthd -u 系统用户名 -p '对应的密码'
0: OK "Success."
在/etc/my.cnf的[mysql]后添加log=/tmp/mysql.log

/etc/pam.d/openvpn文件后加上如下内容:
auth optional pam_stack.so service=system-auth
auth optional pam_nologin.so
password required pam_stack.so service=system-auth
验证成功。

以下内容同wenzk兄的文章没有改变。


配置VPN Server:
[root@vpn /usr/src/RedHat/RPMS/i386]# cd
[root@vpn ~]# cp -r /usr/share/openvpn/easy-rsa/ /etc/openvpn/
[root@vpn ~]# cd /etc/openvpn/easy-rsa/
[root@vpn /etc/openvpn/easy-rsa]# vi vars
修改vars 文件
-----------------------------------------
# 定义你所在的国家,2个字符
export KEY_COUNTRY=CN
# 你所在的省份
export KEY_PROVINCE=Liaoning
# 你所在的城市
export KEY_CITY=Shenyang
# 你所在的组织
export KEY_ORG="ELM OpenVPN ORG"
# 你的邮件地址
export KEY_EMAIL="elm@elm.freetcp.com"
-----------------------------------------

#使修改的环境变量生效
[root@vpn /etc/openvpn/easy-rsa]# . vars
NOTE: when you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

#初始化keys目录
[root@vpn /etc/openvpn/easy-rsa]# ./clean-all

#生成Root CA证书,用于签发Server和Client证书,请保护好keys/ca.key文件。
[root@vpn /etc/openvpn/easy-rsa]# ./build-ca
Generating a 1024 bit RSA private key
........................++++++
.............++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]: #如果无需修改,直接回车
State or Province Name (full name) [Liaoning]:
Locality Name (eg, city) [Shenyang]:
Organization Name (eg, company) [ELM OpenVPN ORG]:
Organizational Unit Name (eg, section) []: OpenVPN Service
Common Name (eg, your name or your server's hostname) []:OpenVPN Root CA
Email Address [elm@elm.freetcp.com]:

#查看生成的keys
[root@vpn /etc/openvpn/easy-rsa]# ls keys
ca.crt ca.key index.txt serial

#我们可以看到ca.crt ca.key文件已经生成了。

#下面我们为服务器生成 Diffie-Hellman 文件
#TLS server 需要使用的一个文件
[root@vpn /etc/openvpn/easy-rsa]# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
..+..............................................................+.................
...................................................+....+........+.........+.......
.............................................+.+...................................
...................................................................................
............................................+......................................
.+.................................+.............+.................................
................................................+..................................
.....................+.............................++*++*++*

#创建并签发VPN Server使用的CA
# 'server' 为创建后的文件名,分别为server.crt server.key
[root@vpn /etc/openvpn/easy-rsa]# ./build-key-server server
Generating a 1024 bit RSA private key
......................++++++
...............++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [Liaoning]:
Locality Name (eg, city) [Shenyang]:
Organization Name (eg, company) [ELM OpenVPN ORG]:
Organizational Unit Name (eg, section) []:OpenVPN Service
Common Name (eg, your name or your server's hostname) []:Server No.1
Email Address [elm@elm.freetcp.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'CN'
stateOrProvinceName :PRINTABLE:'Liaoning'
localityName :PRINTABLE:'Shenyang'
organizationName :PRINTABLE:'ELM OpenVPN ORG'
organizationalUnitName:PRINTABLE:'OpenVPN Service'
commonName :PRINTABLE:'Server No.1'
emailAddress :IA5STRING:'elm@elm.freetcp.com'
Certificate is to be certified until Feb 26 14:43:44 2015 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

#为防止恶意攻击(如DOS、UDP port flooding),我们生成一个"HMAC firewall"
[root@vpn /etc/openvpn/easy-rsa]# openvpn --genkey --secret keys/ta.key

#Server使用的配置文件server.conf
----------------CUT Here-------------
port 1194
;proto tcp
proto udp
;dev tap
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.0.0
ifconfig-pool-persist ipp.txt
;client-to-client
;duplicate-cn
keepalive 10 120
tls-auth ta.key 0
plugin ./openvpn-auth-pam.so openvpn
client-cert-not-required
username-as-common-name
comp-lzo
;max-clients 100
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
;log /var/log/openvpn.log
;log-append openvpn.log
verb 4
;mute 20
--------------Cut Here-----------------

;client-to-client #如果让Client之间可以相互看见,去掉本行的注释掉,否则Client之间无法相互访问
;duplicate-cn #是否允许一个User同时登录多次,去掉本行注释后可以使用同一个用户名登录多次
plugin ./openvpn-auth-pam.so openvpn #说明使用的插件,openvpn为插件的参数,使用pam的servicesname
client-cert-not-required #不请求客户的CA证书,使用User/Pass验证
username-as-common-name #使用客户提供的UserName作为Common Name

把server.conf文件保存到/etc/opennvpn目录中,并把使用easy-rsa下的脚本什成的key都复制到/etc/openvpn目录下,命令如下:
[root@vpn /etc/openvpn/easy-rsa]# cp keys/ca.crt ../
[root@vpn /etc/openvpn/easy-rsa]# cp keys/server.crt ../
[root@vpn /etc/openvpn/easy-rsa]# cp keys/server.key ../
[root@vpn /etc/openvpn/easy-rsa]# cp keys/dh1024.pem ../
[root@vpn /etc/openvpn/easy-rsa]# cp keys/ta.key ../
[root@vpn /etc/openvpn/easy-rsa]# cp /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so ../

#立即启动openenvpn
[root@vpn /etc/openvpn/easy-rsa]# /etc/init.d/openvpn start

#接下来配置客户端的配置文件client.conf:
#Linux或Unix下使用扩展名为.conf Windows下使用的是.ovpn,并把需要使用的文件复制到配置文件所在目录ca.crt ta.key
-------------Cut Here---------------------
client
;dev tap
dev tun
;proto tcp
proto udp
remote 61.1.1.2 1194
;remote my-server-2 1194
remote-random
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
auth-user-pass
ns-cert-type server
tls-auth ta.key 1
route 192.168.0.0 255.255.252.0
comp-lzo
verb 4
;mute 20
------------Cut Here-----------------------

auth-user-pass #询问用户名和密码

Linux下Client的OpenVPN的安装方法一样,只是配置文件和keys上的不同,只要把client.conf ca.crt ta.key复制到/etc/openvpn目录即可启动VPN。
Win下OpenVPN的安装,WIN下有图形界面的OpenVPN-GUI程序。

这里使用的是TUN设备,主要考虑到Client客户多,VPN的效率和广播的问题,选用TUN设备,因为客户端可能是Windows系统,Win系统TUN设备获得的IP地址将会是/30的地址,所以有3*Client个地址浪费,所以地址池设置得比较大。

这样你每次使用VPN登录的时候,程序会自动询问你得用户名和密码,输入正确后就可以连接上VPN了,
连接VPN后所有访问内网(192.168.0.0/22)的数据都从VPN经过。
如果Win的Client比较多,可以试着把ca.crt ta.key client.ovpn打包到安装包程序里,具体操作方法参见:
 

FAQ:

一开始装了个openvpn-2.2.2.tar.gz,不管怎么弄认证都无法通过,后来费了好大工夫,在网上查找,原来是这个版本编译出来的openvpn-auth-pam.so这个文件不行,下载了一个 openvpn-2.0.9.tar.gz,从新编译openvpn-auth-pam.so这个文件替换原来的,问题解决。

在安装openvpn时很多人说找不到openvpn-auth-pam.so文件,其实这个文件是要自己make出来的
 cd /usr/src/openvpn/openvpn-2.0.9/plugin/auth-pam/
 make
生成openvpn-auth-pam.so文件