当前位置: > Linux服务器 > VPN >

OpenVPN使用User/Pass验证登录

时间:2016-05-26 02:07来源:chinaunix.net 作者:chinaunix
OpenVPN使用User/Pass验证登录 

在之前的OpenVPN+CA中已经介绍了使用CA验证登录的方式,详见: 
http://bbs.chinaunix.net/forum/viewtopic.php?t=503434&show_type=new 

本文主要介绍使用Username/Password方式验证登录VPN的方法,虽然使用的是User/Pass 
方式登录,但是在Server端仍然需要证书,这样的VPN和web的HTTPs方式有点类似(不能等同), 
只需Server端有证书,Client可以不提供自己的证书,Client只需验证Server的合法性即可, 
所以Client端只需ca.crt(根证书)即可。当然,由于Client不是使用证书验证的,所以安全 
性方面必然有所下降,但是省去了烦琐的CA管理,我们可以通过用户名和密码来登录VPN, 
这样使得VPN可以很容易和论坛、邮件系统或者其他统一验证系统结合,使用现成的管理界面。 

关于VPN的一些初步认识,可以从下面这个URL获得:(E文的) 
http://blog.chinaunix.net/resserver.php?blogId=2389&resource=OpenVPN%20and%20the%20SSL%20VPN%20Revolution.pdf 
原文出自: 
http://www.giac.org/certified_professionals/practicals/gsec/3985.php 
文中觉得很有意义的语句是: A VPN is a site-to-site tunnel. Let me say that one more time, a VPN is a site-to-site tunnel. 
这篇文章介绍了OpenVPN1.x,也简单介绍了OpenVPN 2.x的一些新特性,同时也简单的介绍了 
其他VPN以及不同方式实现的VPN产品、软件,有时间看看是很有必要的。 

关于VPN比较通俗的理解,在OpenVPN的FAQ中找到的: 
Imagine you had a direct physical wire (i.e. a long cable) connecting two computers (A and B) at different locations. On each computer there would be a /dev/longcable which would be a network device. You could route IP traffic over it, and do everything you could normally do with a network device. 

下面开始介绍VPN的安装和配置: 

环境: 
OS: FC2 (在公司网络出口处,作路由或者是NAT设备使用) 
eth0: 61.1.1.2 (外网地址,直接与Internet相连) 
eth1: 192.168.0.1 (内网地址,连接公司内部,假设公司内部使用192.168.0.0/22这4个C地址) 

Client端硬件及网络环境配置: 
OS: Windown 2000 XP 为主,部分Linux (配置文件通用) 
单网卡,IP地址不固定 

需要达到的目的: 
VPN Client可以随处通过User/Pass登录VPN,访问内网资源。 

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 ~]# 


检查lzo包是否有安装,如果没有,可以到http://rpmfind.net去找 
[root@vpn ~]# rpm -qa | grep lzo 
[root@vpn ~]# wget ftp://rpmfind.net/linux/dag/fedora/2/en/i386/dag/RPMS/lzo-1.08-3.1.fc2.dag.i386.rpm 
[root@vpn ~]# rpm -ivh lzo-1.08-3.1.fc2.dag.i386.rpm 
[root@vpn ~]# wget ftp://rpmfind.net/linux/dag/fedora/2/en/i386/dag/RPMS/lzo-devel-1.08-3.1.fc2.dag.i386.rpm 
[root@vpn ~]# rpm -ivh lzo-devel-1.08-3.1.fc2.dag.i386.rpm 
[root@vpn ~]# rpm -qa | grep lzo 
lzo-devel-1.08-3.1.fc2.dag 
lzo-1.08-3.1.fc2.dag 
[root@vpn ~]# 

下面开始编译安装OpenVPN 
[root@vpn ~]# wget http://mesh.dl.sourceforge.net/sourceforge/openvpn/openvpn-2.0_rc16.tar.gz  
[root@vpn ~]# rpmbuild -tb openvpn-2.0_rc16.tar.gz 
[root@vpn ~]# cd /usr/src/redhat/RPMS/i386/ 
[root@vpn /usr/src/redhat/RPMS/i386]# rpm -ivh openvpn-2.0_rc6-1.i386.rpm 

为了能使用OpenVPN的PAM验证插件,我们安装pam_mysql使用MySQL数据库存储用户数据,其它数据库可以找相应的PAM验证模块 
[root@vpn ~]# wget http://internap.dl.sourceforge.net/sourceforge/pam-mysql/pam_mysql-0.5.tar.gz 
[root@vpn ~]# tar -zxvf pam_mysql-0.5.tar.gz 
[root@vpn ~]# cd pam_mysql 
[root@vpn ~]# make 
[root@vpn ~]# cp pam_mysql.so /lib/security/ 

配置数据库 
以管理员身份登录数据库: 
mysql>; create database vpn; 
mysql>; GRANT ALL ON vpn.* TO vpn@localhost IDENTIFIED BY 'vpn123'; 
mysql>; flush privileges; 
mysql>; use 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 

配置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服务器了。 

配置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="[email]elm@elm.freetcp.com[/email]" 
----------------------------------------- 

#使修改的环境变量生效 

[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 [[email]elm@elm.freetcp.com[/email]]:  

#查看生成的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 [[email]elm@elm.freetcp.com[/email]]:  

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:'[email]elm@elm.freetcp.com[/email]'  
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程序,下载地址http://openvpn.se 

这里使用的是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打包到安装包程序里,具体操作方法参见: 

http://openvpn.se/files/howto/openvpn-howto_roll_your_own_installation_package-Rev1.1.html 

然后发布改软件包即可,最好小心保管ta.key文件(防止Dos攻击)。 

#首先要把系统的Forward打开 
[root@vpn /etc]# vi sysctl.conf 
修改 
# Controls IP packet forwarding 
net.ipv4.ip_forward = 1 

#IPTABLES的配置文件 
[root@vpn /etc/sysconfig]# cat iptables 
# Generated by iptables-save v1.2.1a on Tue Nov  6 19:50:51 2001 
*nat 
:PREROUTING ACCEPT [0] 
:POSTROUTING ACCEPT [0] 
:OUTPUT ACCEPT [0] 
-A POSTROUTING -s 192.168.0.0/255.255.252.0 -o eth0 -j SNAT --to-source 61.1.1.2 
COMMIT 
*filter 
:INPUT DROP [0] 
:FORWARD ACCEPT [0] 
:OUTPUT ACCEPT [0] 
:BLOCK - [0] 
:ANTIVIRUS - [0] 
# block internal ip address 
-A INPUT -i lo -j ACCEPT 
-A INPUT -j BLOCK 
-A INPUT -j ANTIVIRUS 

-A BLOCK -s 192.168.0.0/16 -d 0/0 -j RETURN 
-A BLOCK -s 172.16.0.0/12 -d 0/0 -j REJECT 
-A BLOCK -s 10.0.0.0/8 -d 0/0 -j RETURN 
-A BLOCK -s 127.0.0.0/8 -d 0/0 -j REJECT 
-A BLOCK -s 0.0.0.0/8 -d 0/0 -j REJECT 
-A BLOCK -s 169.254.0.0/16 -d 0/0 -j REJECT 
-A BLOCK -s 192.0.2.0/24 -d 0/0 -j REJECT 
-A BLOCK -s 204.152.64.0/23 -d 0/0 -j REJECT 
-A BLOCK -s 224.0.0.0/3 -d 0/0 -j REJECT 

-A INPUT -p icmp -j ACCEPT 

# OSPFD 
-A INPUT -d 224.0.0.0/24 -j ACCEPT 

# sync time 
-A INPUT -p udp -m udp --sport 123 -j ACCEPT 

# accept dns 
-A INPUT -p udp -m udp --sport 53 -j ACCEPT 

# accept ssh from any 
-A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT 

# accept dhcp request 
-A INPUT -p udp -m udp --dport 67 -j ACCEPT 

# OpenVPN 1194_UDP 
-A INPUT -p udp -m udp --dport 1194 -j ACCEPT 

# www 
-A INPUT -p tcp -m tcp --dport 80 --syn -j ACCEPT 

# keep stats 
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -m state --state INVALID -j DROP 

# Reject all packet to me 
-A INPUT -p tcp -m tcp --syn -j REJECT --reject-with tcp-reset 
-A INPUT -p udp -m udp -j REJECT 

-A FORWARD -j ANTIVIRUS 

-A ANTIVIRUS -p tcp -m tcp --dport 135:139 -j DROP 
-A ANTIVIRUS -p tcp -m tcp --dport 445 -j DROP 
-A ANTIVIRUS -p udp -m udp --dport 69 -j DROP 
-A ANTIVIRUS -p udp -m udp --dport 135:139 -j DROP 
-A ANTIVIRUS -p udp -m udp --dport 1434 -j DROP 

COMMIT 
[root@vpn /etc/sysconfig]# 
(责任编辑:IT)
------分隔线----------------------------