系统环境
[root@vpn ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
一. 准备工作
[root@vpn ~]# yum -y install openssl-devel openssl pam pam-devel lzo lzo-devel pkcs11-helper pkcs11-helper-devel
二. 安装OpenVPN服务
1. 下载openvpn源码包
[root@vpn ~]# wget http://oss.aliyuncs.com/aliyunecs/openvpn-2.2.2.tar.gz
2. 使用 rpmbuild 将源码包编译成rpm包来进行安装
[root@vpn ~]# rpmbuild -tb openvpn-2.2.2.tar.gz
如果没有rpmbuild命令:yum install -y rpm-build
执行这条命令以后就会正常开始编译了,编译完成以后会在 /root/rpmbuild/RPMS/x86_64 目录下生成 openvpn-2.2.2-1.x86_64.rpm 安装包。
3. 安装rpm包
[root@vpn ~]# rpm -ivh openvpn-2.2.2-1.x86_64.rpm
三. 证书生成
1. 初始化PKI
[root@vpn ~]# cd /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0
[root@vpn 2.0]# cp vars vars.bak
[root@vpn 2.0]# vim vars #在最后修改
export KEY_COUNTRY=CN
export KEY_PROVINCE=BJ
export KEY_CITY=BJ
export KEY_ORG="bj-openvpn"
export KEY_EMAIL="xx@gmail.com"
2. 先清除key下的所有key
[root@vpn 2.0]#ln -s openssl-1.0.0.cnf openssl.cnf
[root@vpn 2.0]#source ./vars
[root@vpn 2.0]#./clean-all
3. 生成ca私钥和证书
[root@vpn 2.0]#./build-ca
一直默认回车即可
4. 为 vpn服务器签发证书
[root@vpn 2.0]#./build-key-server server //server为自定义证书名,为了下面配置方便,这里就用server
一直回车,Common Name处填入自定义的证书名字,再回车,最后会有两次交互,输入y
5. 为 vpn客户端签发证书
[root@vpn 2.0]#./build-key client //client自定义证书名
一直回车,Common Name处填入自定义的证书名字,再回车,最后会有两次交互,输入y
6. 创建密钥协商文件 迪菲·赫尔曼密钥
[root@vpn 2.0]#./build-dh //生成dh参数文件 dh1024.pem,高版本是dh2048.pem
四. 配置VPN
1. 先查看上面所生成的秘钥
[root@vpn 2.0]# ll keys/
01.pem ca.key server.key client.key index.txt.attr serial
02.pem server.crt client.crt dh1024.pem index.txt.attr.old serial.old
ca.crt server.csr client.csr index.txt index.txt.old
将key拷贝到/etc/openvpn中
[root@vpn 2.0]# cp keys/* /etc/openvpn
2. server.conf 配置
[root@svn 2.0]# cp /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf /etc/openvpn
[root@svn 2.0]# vim /etc/openvpn/server.conf
local 0.0.0.0 #专有网络填私网ip,经典网络填公网ip
port 9094
proto tcp
dev tun
;username-as-common-name #等会用户密码验证开启
;auth-user-pass-verify /etc/openvpn/check.sh via-env #检查脚本
ca ca.crt
cert server.crt #上面自定义所生成的证书,如果server.conf与证书不在同一目录要注意路径
key server.key
dh dh1024.pem #dh参数文件,注意是dh1024还是dh2048
server 10.8.0.0 255.255.255.0 #给vpn-client分配的子网,防火墙要设置从内网通子网
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "route 172.18.0.0 255.255.255.0" #内网网段
push "dhcp-option DNS 119.29.29.29"
push "dhcp-option DNS 114.114.114.114"
client-to-client
keepalive 10 120
comp-lzo #压缩
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log openvpn.log
verb 3
3. 路由转发
[root@vpn ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@vpn ~]# sysctl -p
4. 防火墙设置
CentOS7是firewalld,先关闭firewalld再安装iptables
systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld
安装iptables
yum install iptables-services
service start iptables
设置iptables规则
iptables -A INPUT -p tcp -m tcp --dport 9094 -m comment --comment openvpn -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE #内网网段
iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -j SNAT --to-source 172.18.xxx.xxx #内网ip
service iptables save
如果设置iptables规则后没有在/etc/sysconfig/iptables中显示,则直接使用重定向>生成到/etc/sysconfig/iptables配置文件中,再保存。
5. 启动vpn
[root@vpn ~]# systemctl restart openvpn
[root@vpn ~]# /sbin/chkconfig openvpn on
[root@vpn ~]# ps -ef | grep openvpn
[root@vpn ~]# netstat -antp | grep 9094
启动失败则查看日记:tail -f /etc/openvpn/openvpn.log
五. Windows客户端配置
下载地址:
https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.2-I601.exe
将vpn服务器上的ca.crt、client.key、client.crt 、client.csr证书拷贝到windows客户端安装的C:\Program Files\OpenVPN\config目录中,这是默认安装的路径,若自定义则拷贝到对应目录,
再到C:\Program Files\OpenVPN\sample-config目录拷贝client.conf到C:\Program Files\OpenVPN\config目录中,配置如下:
client
dev tun
proto tcp
remote 47.xxx.xxx.xxx 9094 #公网ip
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
ns-cert-type server
comp-lzo
verb 3
配置好之后以管理员方式运行,再点击图标连接,也可直接查看日记
连接成功后会多生成一块虚拟网卡
登陆ip.cn查看连接ip
六. Linux客户端配置
linux端vpn客户端连通后会获取vpn的子网IP,这时就之前的服务器公网IP就不通了,注意使用
先登录到server端给client签发证书,也可以使用之前签发客户端的证书
[root@vpn ~]# cd /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0
[root@vpn 2.0]# ./build-key linux-client //自定义名字
Common Name (eg, your name or your server's hostname) []:linux-client
客户端安装openvpn,跟上面服务端安装一样,这里就不重复了
从服务器端拷贝生产的证书到客户端的/etc/openvpn下,拷贝如下文件
scp ca.crt linux-client.crt linux-client.key root@ip:/etc/openvpn
编辑客户端文件
vim /etc/openvpn/client.conf
client
dev tun
proto udp
remote 47.xxx.xxx.xxx 9094 #VPNserver 地址,公网地址
nobind
user nobody
group nobody
persist-key
persist-tun
ca ca.crt
cert linux-client.crt
key linux-client.key
;auth-user-pass #账号密码验证要开启
comp-lzo
verb 3
mute 20
systemctl restart openvpn
或 openvpn --daemon --config /etc/openvpn/client.ovpn --cd /etc/openvpn
测试是否可以ping 通内网的机器 ping xxx.xxx.xxx.xxx
如果是虚拟机内网搭建的vpn可以测试,我这里是ecs搭建的,连接上来后获取了vpn分配的子网ip,立即掉线了,到管理台重启服务器才能继续操作。
阿里云工单给出的解决办法是:
通过控制台登陆客户端,删除两条路由
0.0.0.0 mask 128.0.0.0 下一跳VPN网关
128.0.0.0 mask 128.0.0.0 下一跳VPN网关
七. 实现账号密码验证
服务端server.conf添加如下两行:
username-as-common-name #等会用户密码验证开启
auth-user-pass-verify /etc/openvpn/check.sh via-env #检查脚本
check.sh 脚本主要是用来检测用户密码
[root@svn openvpn]# cat check.sh
#!/bin/sh
###########################################################
PASSFILE="/etc/openvpn/openvpnfile" #用户密码文件
LOG_FILE="/var/log/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
用户密码文件输入用户为test,密码为test123;用户密码文件格式如下,多个用户依次添加即可
[root@svn openvpn]# cat openvpnfile
test test123
修改server.conf后重启openvpn
systemctl restart openvpn
客户端client.conf文件添加如下一行:
auth-user-pass #账号密码验证要开启
重启openvpn,输入openvpnfile中设置的账号密码。