CentOS 7.1部署OpenVPN服务器
1、安装openvpn、easy-rsa
[root@10-255-0-163 etc]# yum -y install openvpn easy-rsa
2、安装依赖包
[root@10-255-0-163 etc]# yum install -y openssl openssl-devel lzo lzo-devel pam pam-devel automake pkgconfig makecache
3、配置easy-rsa-3.0
[root@10-255-0-163 etc]# cp -r /usr/share/easy-rsa/ /etc/openvpn/easy-rsa
[root@10-255-0-163 etc]# cd /etc/openvpn/easy-rsa/
[root@10-255-0-163 easy-rsa]# cd 3.0.3/
[root@10-255-0-163 3.0.3]# find / -type f -name "vars.example" | xargs -i cp {} . && mv vars.example vars
4、生成服务端证书
[root@10-255-0-163 3.0.3]# pwd
/etc/openvpn/easy-rsa/3.0.3 #注意路径
创建PKI
[root@10-255-0-163 3.0.3]# ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/easy-rsa/3.0.3/pki
创建CA
[root@10-255-0-163 3.0.3]# ./easyrsa build-ca nopass
Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
..........+++
.......+++
writing new private key to '/etc/openvpn/easy-rsa/3.0.3/pki/private/ca.key.0NpyB8RlNe'
-----
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:回车
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/easy-rsa/3.0.3/pki/ca.crt
创建服务端证书
[root@10-255-0-163 3.0.3]# ./easyrsa gen-req server nopass
Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
..............................................+++
.............................................................................................+++
writing new private key to '/etc/openvpn/easy-rsa/3.0.3/pki/private/server.key.Brzh0IopBz'
-----
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.
-----
Common Name (eg: your user, host, or server name) [server]:回车
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/3.0.3/pki/reqs/server.req
key: /etc/openvpn/easy-rsa/3.0.3/pki/private/server.key
签约服务端证书
[root@10-255-0-163 3.0.3]# ./easyrsa sign server server
Note: using Easy-RSA configuration from: ./vars
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 3650 days:
subject=
commonName = server
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from ./openssl-1.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'server'
Certificate is to be certified until Aug 13 01:47:24 2028 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /etc/openvpn/easy-rsa/3.0.3/pki/issued/server.crt
创建Diffie-Hellman
[root@10-255-0-163 3.0.3]# ./easyrsa gen-dh
创建ta.key #用于防御DoS、UDP淹没等恶意攻击
[root@10-255-0-163 openvpn]#openvpn --genkey --secret ta.key
5、创建客户端证书
复制文件
[root@10-255-0-163 openvpn]# cp -r /usr/share/easy-rsa/ /etc/openvpn/client/easy-rsa
[root@10-255-0-163 3.0.3]# pwd
/etc/openvpn/client/easy-rsa/3.0.3 #注意路径 !!!!!!!!!!!!!!!!!!!!!!
[root@10-255-0-163 3.0.3]# find / -type f -name "vars.example" | xargs -i cp {} . && mv vars.example vars
创建PKI
[root@10-255-0-163 3.0.3]# ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/client/easy-rsa/3.0.3/pki
[root@10-255-0-163 3.0.3]# ./easyrsa gen-req esop01 nopass #创建客户证书名为esop01,没有密码
Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
....................................................................................................................................................+++
...............................+++
writing new private key to '/etc/openvpn/client/easy-rsa/3.0.3/pki/private/esop01.key.ULyi4FqZjH'
-----
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.
-----
Common Name (eg: your user, host, or server name) [esop01]:回车
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/client/easy-rsa/3.0.3/pki/reqs/esop01.req
key: /etc/openvpn/client/easy-rsa/3.0.3/pki/private/esop01.key
签约客户端证书
[root@10-255-0-163 3.0.3]# cd /etc/openvpn/easy-rsa/3.0.3/
[root@10-255-0-163 3.0.3]# ./easyrsa import-req /etc/openvpn/client/easy-rsa/3.0.3/pki/reqs/esop01.req esop01
Note: using Easy-RSA configuration from: ./vars
The request has been successfully imported with a short name of: esop01
You may now use this name to perform signing operations on this request.
[root@10-255-0-163 3.0.3]# ./easyrsa sign client esop01
Note: using Easy-RSA configuration from: ./vars
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 3650 days:
subject=
commonName = esop01
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from ./openssl-1.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'esop01'
Certificate is to be certified until Aug 13 02:12:20 2028 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /etc/openvpn/easy-rsa/3.0.3/pki/issued/esop01.crt
6、整理证书
服务端证书
[root@10-255-0-163 openvpn]# mkdir /etc/openvpn/certs
[root@10-255-0-163 openvpn]# cd certs/
[root@10-255-0-163 certs]# cp /etc/openvpn/easy-rsa/3.0.3/pki/dh.pem .
[root@10-255-0-163 certs]# cp /etc/openvpn/easy-rsa/3.0.3/pki/ca.crt .
[root@10-255-0-163 certs]# cp /etc/openvpn/easy-rsa/3.0.3/pki/issued/server.crt .
[root@10-255-0-163 certs]# cp /etc/openvpn/easy-rsa/3.0.3/pki/private/server.key .
客户端证书
[root@10-255-0-163 openvpn]# mkdir /etc/openvpn/client/esop01
[root@10-255-0-163 openvpn]# cd /etc/client/esop01/
[root@10-255-0-163 esop01]# cp /etc/openvpn/easy-rsa/3.0.3/pki/ca.crt .
[root@10-255-0-163 esop01]# cp /etc/openvpn/easy-rsa/3.0.3/pki/issued/esop01.crt .
[root@10-255-0-163 esop01]# cp /etc/openvpn/client/easy-rsa/3.0.3/pki/private/esop01.key .
7、服务器配置文件
[root@10-255-0-163 openvpn]#chmod 644 server.conf
[root@10-255-0-163 openvpn]# vi /etc/openvpn/server.conf
port 1194
proto tcp
dev tun
ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/server.crt
key /etc/openvpn/certs/server.key # This file should be kept secret
dh /etc/openvpn/certs/dh.pem
server 172.30.25.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.255.0.0 255.255.0.0"
push "route 192.168.20.0 255.255.255.0"
keepalive 10 120
#cipher AES-256-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append openvpn.log
verb 3
tls-auth /etc/openvpn/ta.key 0 # This file is secret
auth-user-pass-verify /etc/openvpn/scripts/checkpsw.sh via-env
username-as-common-name
script-security 3
#mute 20
8、创建密码脚本
[root@10-255-0-163 openvpn]#mkdir scripts
[root@10-255-0-163 openvpn]#chmod 755 scripts/
[root@10-255-0-163 scripts]# vi /openvpn/scripts/checkpsw.sh
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/scripts/pwd-file"
LOG_FILE="/etc/openvpn/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
[root@10-255-0-163 scripts]# vi pwd-file
[root@10-255-0-163 scripts]# cat pwd-file
esop01 123456 #写入用户名/密码,用空格隔开
[root@10-255-0-163 scripts]# chown nobody.nobody checkpsw.sh
[root@10-255-0-163 scripts]# chmod +x checkpsw.sh
[root@10-255-0-163 scripts]# chmod 400 pwd-file
[root@10-255-0-163 scripts]# chown nobody.nobody pwd-file
[root@10-255-0-163 openvpn]# touch openvpn-password.log #用于将来查看日志排错
[root@10-255-0-163 openvpn]# chmod 666 openvpn-password.log #赋写入权限
9、配置网络
[root@10-255-0-163 /]#iptables -t nat -A POSTROUTING -s 172.30.25.0/24 -o eth0 -j SNAT --to-source 192.168.0.27
[root@10-255-0-163 /]#iptables -A INPUT -p TCP --dport 33219 -j ACCEPT
[root@10-255-0-163 /]#iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@10-255-0-163 /]#service iptables save
[root@10-255-0-163 /]#service iptables restart
开启转发
[root@10-255-0-163 /]# vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@10-255-0-163 /]# sysctl -p
测试连通性
[root@10-255-0-163 /]#nc -v 116.85.50.244 1194
10、配置本地客户端
[root@10-255-0-163 openvpn]# sz -r XXXXX
/etc/openvpn/client/esop01路径下的ca.crt、esop01.crt、esop01.key下载到C:\Program Files\OpenVPN\config
[root@10-255-0-163 openvpn]# sz ta.key #下载ta.key
[root@10-255-0-163 openvpn]# chmod 600 ta.key #下载完,将权限改回来
[root@10-255-0-163 openvpn]# cp /usr/share/doc/openvpn-2.4.6/sample/sample-config-files/client.conf /etc/openvpn/client.ovpn #将client.conf重命名成client.ovpn下载到C:\Program Files\OpenVPN\config
[root@10-255-0-163 openvpn]# chmod -R 700 client/
client.ovpn内容
client
dev tun
proto tcp
remote 116.85.50.244 1194
resolv-retry infinite
nobind
#user root
#group root
persist-key
persist-tun
ca "C:\\Program Files\\OpenVPN\\config\\ca.crt"
cert "C:\\Program Files\\OpenVPN\\config\\esop01.crt"
key "C:\\Program Files\\OpenVPN\\config\\esop01.key"
#remote-cert-tls server
#cipher AES-256-CBC
comp-lzo
verb 3
# Silence repeating messages
;mute 20
auth-user-pass
tls-auth ta.key 1
11、启动服务器端openvpn
[root@10-255-0-163 openvpn]# systemctl start openvpn@server
[root@10-255-0-163 openvpn]#systemctl restart openvpn@server #用于修改server.conf后重启服务
12、排错
/etc/openvpn/openvpn.log #openvpn日志
/etc/openvpn/openvpn-password.log #查看登录情况日志
client->view log #客户端查看日志
13、开机自启动
vim /etc/rc.local
iptables -t nat -A POSTROUTING -s 172.30.25.0/24 -o eth0 -j SNAT --to-source 192.168.0.27
iptables -A INPUT -p TCP --dport 33219 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@zqyz194 ~]# systemctl enable openvpn@server
常见错误
/sbin/ip route del 10.8.0.0/24 #VPN地址与内网地址冲突
openvpn ’ssl3_get_client_certificate:peer did not return a certificate’ #客户端证书路径不对,没有正常返回
Failed running command (--auth-user-pass-verify): external program exited with error status: 1 # 兼容性 server.conf 有问题
ERROR: could not read Auth username/password/ok/string from management interface
查看openvpn/scripts的权限 赋755
抓包 #用于查看通过VPN客户端访问VPN server外服务器,数据传输方向
[root@zqyz194 scripts]# tcpdump -nnn -s 10000|grep -i icmp
三种网络实现方式
1、#改网关
route add default gw 192.168.0.27
route del default gw 192.168.0.27
2、#添加路由 #需要配置每台连进VPN的服务器
route add -net 172.30.25.0/24 gw 192.168.0.27
#配置静态路由
3、#NAT映射 目前最简单,只在VPN server做调整即可
/etc/init.d/iptables stop
iptables -t nat -A POSTROUTING -s 172.30.25.0/24 -o eth0 -j SNAT --to-source 192.168.0.27
172.30.25.0/24 源地址 192.168.0.27目的地址 VPN server的ip
iptables -t nat -A POSTROUTING -s 172.30.25.0/24 -o eth0 -j MASQUERADE 对应动态目的地址
iptables -t nat -D POSTROUTING -s 172.30.25.0/24 -o eth0 -j SNAT --to-source 192.168.0.27 #删除规则
如果保存,启动防火墙后发现ping不通,查看一下防火墙策略
4、添加客户端新证书
./build-key-pass XXX名称
5、证书吊销
cd /etc/openvpn/client/easy-rsa/3.0.3/pki/private 进入后删除!
cd /etc/openvpn/client/easy-rsa/3.0.3/pki/reqs 进入后删除!
cd /etc/openvpn/easy-rsa/3.0.3
./easyrsa revoke 证书名
6、批量添加客户端证书脚本
后续维护难免批量添加客户,具体方法如下:
创建openvpn.sh在/etc/openvpen下,脚本内容如下:
#!/bin/bash
for i in "$@"
do
name=$i
cd /etc/openvpn/client/easy-rsa/3.0.3
./easyrsa gen-req $name nopass
cd /etc/openvpn/easy-rsa/3.0.3/
./easyrsa import-req /etc/openvpn/client/easy-rsa/3.0.3/pki/reqs/$name.req $name
./easyrsa sign client $name
mkdir /etc/openvpn/client/$name
cd /etc/openvpn/client/$name
cp /etc/openvpn/easy-rsa/3.0.3/pki/ca.crt .
cp /etc/openvpn/easy-rsa/3.0.3/pki/issued/$name.crt .
cp /etc/openvpn/client/easy-rsa/3.0.3/pki/private/$name.key .
done
批量添加VPN用户命令
[root@zqyz194 scripts]# sh openvpn.sh user1 user2 user3