openvpn server端与client端简单搭建

openvpn server端与client端简单搭建

Scroll Down

openvpn server信息:
服务器版本:centos6/7
openvpn server版本:openvpn-2.4.7
easy-rsa 版本:3.0.6
openvpn client版本:2.4.7

1、编译方式安装openvpn

◆ 下载地址:

通过这个链接可以下载源码包和exe包
https://openvpn.net/community-downloads/
image.png

◆ 下载依赖包

# yum install -y openssl openssl-devel  lzo lzo-devel c++  gcc-c++   pam-devel

◆ 解压源码包

# tar xvf openvpn-2.4.7.tar.gz

◆ 编译

# cd openvpn-2.4.7
#./configure --prefix=/usr/local/openvpn-2.7.4

# –prefix指定编译到某个位置,可根据自己需求选择,需要记住自己的编译路径,后续添加环境变量的时候会遇到

◆ 编译完成

1.png

◆ 安装

# make && make install 

◆ 配置环境变量

# echo "export PATH=/usr/local/openvpn-2.7.4/sbin/:$PATH" >> /etc/profile
# source /etc/profile

2、生成证书

2.1 生成server端证书

◆ 下载easy-rsa工具

下载地址:https://github.com/OpenVPN/easy-rsa/releases

可以直接下载tar包,也可以下载源码包编译安装(建议直接用tar包)

◆ 解压

由于此工具用于生成服务器端证书和客户端证书,为了方便区分和配置,将tar包分别解压到2个不同的目录

mkdir /root/{server_key,client_key}
tar xvf EasyRSA-unix-v3.0.6.tgz -C ./server_key
tar xvf EasyRSA-unix-v3.0.6.tgz -C ./client_key

◆ 初始化

cd server_key/EasyRSA-v3.0.6/
./easyrsa init-pki

3.png

◆ 生成根证书

生成根证书可以选择设置密码,如果设置密码。需要记住此密码(wo设置的123456789),启动VPN服务的时候会用到
Common Name中可以设置一个名称,也可以留空

./easyrsa build-ca

image.png

◆ 创建server端证书和private key

可以使用nopass选项不加密private key,建议添加密码(wo设置的123456789)

./easyrsa gen-req server

image.png

◆ 给证书做签名

确认之前设置的信息,Confirm request details出输入  yes  并输入根证书的密码(wo设置的123456789)(注意不是服务器证书的密码,服务器证书可以不加密)

./easyrsa sign server server 

image.png

◆ 设置Diffie-Hellman密钥交换协议

./easyrsa gen-dh

7

2.2 生成client端证书

◆ 初始化

cd client_key/EasyRSA-v3.0.6/
./easyrsa init-pki

8.png

◆ 创建client端证书和private key

可以使用nopass选项不加密private key,建议添加一个密码(wo设置的123456789)

./easyrsa gen-req client

image.png

◆ 对client端证书做签名
Confirm request details 处输入 yes  输入根证书的密码(客户端证书也可以不加密)

./easyrsa sign client client

10.png

2.3 拷贝server证书到统一位置

由于openvpn 配置文件中要指定证书位置,所以将所有的证书存放到一起,方便管理

◆ 创建目录

mkdir -p /etc/openvpn2.7.4/keys/

◆ 拷贝证书(实际操作的时候可能路径会不一样,但是 证书文件名称 是一样的)

cp -p /root/server_key/EasyRSA-v3.0.6/pki/ca.crt    /etc/openvpn2.7.4/keys/
cp -p /root/server_key/EasyRSA-v3.0.6/pki/dh.pem    /etc/openvpn2.7.4/keys/
cp -p /root/server_key/EasyRSA-v3.0.6/pki/private/server.key    /etc/openvpn2.7.4/keys/
cp -p /root/server_key/EasyRSA-v3.0.6/pki/issued/server.crt    /etc/openvpn2.7.4/keys/

1.png

在移动客户端(如安卓)连接的时候,如果不开启tls_auth认证,就会报错如下:
image.png

所以我们要开启tls_auth认证,需要
◆ 生成证书

openvpn --genkey --secret /etc/openvpn2.7.4/keys/tls-crypt.key
2.3 创建客户端传入密码验证脚本和用户列表文件

这一步首先创建一个文件用来存放连接时使用的账户密码等数据,然后创建脚本文件用来检查 客户端连接时输入的账户密码 与 上一步文件种的账户密码是否一致

◆ 创建密码验证脚本

# vim /etc/openvpn2.7.4/checkpsw.sh
#!/bin/sh
PASSFILE="/etc/openvpn2.7.4/psw-file"
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
# 这个awk的作用是:
# !/^;/表示匹配非^开头的行,!/^#/表示匹配非#开头的行,$1=="'${username}'"表示拿${PASSFILE}变量文件中的第一个字段与${username}字段相对比,${username}字段是客户端连接时传递来的数据
# 整个awk作用就是当客户端输入账号密码进行连接时,脚本检查客户端输入的与用户列表文件中的是否一致
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

◆ 给脚本添加执行权限

chmod +x checkpsw.sh

◆ 创建用户列表文件 ( 此文件是在脚本中定义的 PASSFILE 变量的值 )
文件格式如下:

用户名1    密码1

用户名2    密码2

# cat psw-file 
test 123456789
admin 123456789

◆ 设置用户列表文件权限

chmod 400 /etc/openvpn2.7.4/psw-file
2.4 修改server端配置文件

◆ 拷贝示例配置文件到证书目录
注意:示例文件在下载的压缩包文件中,而不是编译安装的目录

cp /root/openvpn-2.4.7/sample/sample-config-files/server.conf /etc/openvpn2.7.4/

◆ 修改配置文件,如下( ;开头的也表示注释 ):

# sed -r '/^[ \t]*(#|$)/d' server.conf 
;local a.b.c.d
local 0.0.0.0     #监听地址
port 1194        #监听端口
;proto tcp       #监听协议
proto tcp       
;dev tap
dev tun           #采用路由隧道模式
;dev-node MyTap
ca /etc/openvpn2.7.4/keys/ca.crt      #ca证书路径
cert /etc/openvpn2.7.4/keys/server.crt       #服务器证书路径
key /etc/openvpn2.7.4/keys/server.key  #服务器秘钥路径
dh /etc/openvpn2.7.4/keys/dh.pem       #秘钥交换协议文件路径
;topology subnet
server 10.8.0.0 255.255.255.0       #给客服端分配的地址池(注:不能和服务器内网ip一个网段)
ifconfig-pool-persist ipp.txt
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
;server-bridge
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
;learn-address ./script
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"      #dhcp分配dns的DNS服务器地址
push "dhcp-option DNS 114.114.114.114"     #dhcp分配dns的DNS服务器地址
;client-to-client
;duplicate-cn
keepalive 10 120          #存活时间
tls-auth /etc/openvpn2.7.4/keys/tls-crypt.key 0 # This file is secret
cipher AES-256-CBC
;compress lz4-v2
;push "compress lz4-v2"
comp-lzo           #传输数据压缩
max-clients 1000       #客户端最大连接数
;user nobody
;group nobody
persist-key
persist-tun
status /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/append-openvpn.log
verb 3
auth-user-pass-verify /etc/openvpn2.7.4/checkpsw.sh via-env   #客户端密码验证脚本位置
username-as-common-name
script-security 3
client-cert-not-required
;mute 20

◆ 启动openVPN服务
注意:如果对server端证书设置了密码,需要使用 --askpass 参数输入密码

openvpn   --daemon --config /etc/openvpn2.7.4/server.conf  --askpass

如果报错,根据/var/log/openvpn.log日志查找报错原因。

◆ 添加流量转发
# 个人理解:云服务器主网卡接口绑定的是弹性IP地址,此时如果有新的网卡或虚拟网卡需要访问公网的话,需要为其做nat映射

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

3、客户端连接

windows客户端可以按照文章头部的地址下载客户端安装,然后定义客户端配置文件,并将服务器上的client证书给拿下来,还需要一个tls证书文件--就是那个tls-crypt.key文件

openvpn客户端时应需要先关闭代理软

修改配置文件:(如果不行可以自己编写一个config.opvn的文件,导入就行)

image.png

image.png

image.png

image.png
最后输入的私钥密码是之前设置的证书密码

4、总结遇坑

① 刚开始不熟悉的时候,不知道账号密码怎么设置,感觉官方脚本有问题

解决办法:看下2.3部分的密码校验脚本和用户列表文件部分就可以了

② 安卓移动端连接报错tls error

解决:如文中所讲。开启tls认证,并生成tls证书文件,服务端一份,客户端一份,注意配置文件书写方式不一样,server端为1,client端为0

③ 服务器监听地址设置的主网卡、lo地址均不可访问

解决:监听的tcp的0.0.0.0地址

还有啥坑来着,我给忘了

5、server 、client 配置文件详解

server 配置文件:

#通讯协议,可以选择TCP或者UDP,UDP更适合于在丢包率较大的环境使用
proto tcp  
#端口号
port 1194
#使用tun或者tap设备
dev tun 
#实现/24子网掩码换算,最大客户端有255个
topology subnet 
#设置子网,默认是10.8.0.0/24
server 10.8.0.0 255.255.255.0 
#认证算法
auth SHA256 
#加密算法
cipher AES-256-CBC 
#使用LZO压缩
comp-lzo adaptive 
#告知客户端通讯将采用LZO压缩
push "comp-lzo adaptive" 
#此处是全局路由选项,即告知客户端将所有流量通过VPN隧道发送,一般是不使用
push "redirect-gateway def1 bypass-dhcp" 
#推送DNS信息,下同
push "dhcp-option DNS 1.1.1.1" 
push "dhcp-option DNS 8.8.8.8"
#服务器CA证书路径
ca /etc/openvpn/cert/ca.crt 
#diffie hellman密钥路径
dh /etc/openvpn/cert/dh1024.pem 
#服务器证书路径
cert /etc/openvpn/cert/server.crt 
#服务器密钥路径
key /etc/openvpn/cert/server.key 
#在SSL/TLS握手包的基础上增加额外的签名以提高安全性。
tls-auth /etc/openvpn/cert/ta.key 
#此选项使VPN在重连时不重新读取key且不会将tun设备关闭
persist-key 
persist-tun
#通过yum安装的,可将其配置为以openvpn用户和组运行,增加安全性
user openvpn
group openvpn
#openvpn账号密码认证脚本
auth-user-pass-verify /etc/openvpn/openvpn3config/checkpsw.sh via-env
#使用客户端提供的用户名作为common name
username-as-common-name
#不要求客户端提供证书
client-cert-not-required
#脚本运行级别为3,否则无法认证用户名密码
script-security 3
#客户端配置文件,可以配置客户端的IP
client-config-dir /etc/openvpn/ccd
#生成日志
log /var/log/openvpn.log
log-append /var/log/openvpn.log
#将最大客户端设置为255
max-clients 255
#该选项允许客户端直接通讯而在路由上不经过网关
client-to-client
#10秒钟ping一次对端以确定对方是否在线,60秒未响应则断开连接,适合客户端在NAT后使用
keepalive 10 60
nice 3
#日志级别设置
verb 4
mute 10

client 配置文件:

#声明为客户端
client
#使用tun/tap设备,必须与服务端一直
dev tun
#连接协议,必须与服务端一直
proto tcp
#远程服务器的地址和端口号,可以是域名也可以是IP地址
remote IP or Domain name Portnum
#在服务器中断后自动连接
resolv-retry infinite
#不指定网卡
nobind
#以下同服务端说明
persist-key
persist-tun
auth SHA256
cipher AES-256-CBC
comp-lzo adaptive
nice 0
verb 3
mute 10
#认证文件,即用户名密码,下次无需再输入
auth-user-pass pass.txt
#ca证书路径,也可使用<ca></ca>的形式直接将证书粘贴于此
ca ca证书路径
#key应该与服务器一致 
tls-auth ta.key