企业中,必不可少的应用就是VPN了,它可以帮助员工在外网中访问公司内网,常见开源实现方案有OpenVPN和jumpserver。
  OpenVPN是采用了端口转发的原理实现,是基于IP+端口的4层代理机制,一般是用于出差员工访问公司内部ERP系统等使用,而jumpserver是7层代理,所以功能更加强大却也更加复杂,一般适合运维人员管理维护企业内部服务器。对于中小公司日常使用,OpenVPN就已经完全足够了,当然,也可用于科学,你懂得。本文将对linux环境下(CentOS),OpenVPN的安装配置做一个详细的介绍。

部署OpenVPN

部署OpenVPN服务器

下载安装OpenVPN

  OpenVPN的rpm包可以在epel源中直接下载安装,所以我们需要先配置epel源,推荐选用阿里的epel源,CentOS67命令如下:

1
2
3
4
5
6
7
8
cat > /etc/yum.repos.d/aliyunepel.repo << "END"
[aliyun-epel]
name=aliyun-epel
baseurl=https://mirrors.aliyun.com/epel/$releasever/$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-$releasever
enabled=1
END

  CentOS8路径有所变化,命令如下:

1
2
3
4
5
6
7
8
cat > /etc/yum.repos.d/aliyunepel.repo << "END"
[aliyun-epel]
name=aliyun-epel
baseurl=https://mirrors.aliyun.com/epel/$releasever/Everything/$basearch/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-$releasever
enabled=1
END

  或者直接安装官方的epel源(6、7、8通用)。

1
yum install epel-release -y

  配置好epel源之后,直接yum安装服务器端软件和证书管理工具就可以了。

1
2
yum install openvpn -y #openvpn服务端
yum install easy-rsa -y #证书管理工具

OpenVPN配置

  将模版配置文件及证书管理工具复制到指定目录

1
2
3
cp /usr/share/doc/openvpn-2.4.8/sample/sample-config-files/server.conf /etc/openvpn/  #openvpn server 配置文件
cp -r /usr/share/easy-rsa/ /etc/openvpn/easyrsa-server #证书管理工具
cp /usr/share/doc/easy-rsa-3.0.6/vars.example /etc/openvpn/easyrsa-server/3/vars

  配置文件模版如果没有,那可能是在路径为/usr/share/doc/openvpn/sample/sample-config-files/server.conf,easy-rsa如果CentOS8yum安装不上,只能去github上https://github.com/OpenVPN/easy-rsa下载,将里面的easyrsa3目录复制出来就是证书管理工具,并且不需要复制vars.example文件,里面已经有了,改个名字就可以。

1
cp -r easyrsa3 /etc/openvpn/easyrsa-server

  先进入证书管理工具目录(若github上下载的则是cd /etc/openvpn/easyrsa-server/,之后则都没有3的子目录,或者也创建一个3的子目录保持一致性)

1
cd /etc/openvpn/easyrsa-server/3

  若easyrsa为github下载的话,目录结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@aws-host easyrsa-server]#tree
.
├── easyrsa
├── openssl-easyrsa.cnf
├── vars.example
└── x509-types
├── ca
├── client
├── code-signing
├── COMMON
├── email
├── server
└── serverClient

1 directory, 10 files
[root@aws-host easyrsa-server]#

  OpenVPN的server端配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vim /etc/openvpn/server.conf
local 172.18.200.101 #本机监听IP,写公网IP
port 1194 #端口
# TCP or UDP server?
proto tcp #协议,指定OpenVPN创建的通信隧道类型
#proto udp
#dev tap:创建一个以太网隧道,以太网使用tap
dev tun:创建一个路由IP隧道,互联网使用tun一个TUN设备大多时候,被用于基于IP协议的通讯。一个TAP设备允许完整的以太网帧通过Openvpn隧道,因此提供非ip协议的支持,比如IPX协议和AppleTalk协议
#dev-node MyTap #TAP-Win32适配器。非windows不需要
#topology subnet #网络拓扑,不需要配置
server 10.8.0.0 255.255.255.0 #客户端连接后分配IP的地址池,服务器默认会占用第一个IP 10.8.0.1
#ifconfig-pool-persist ipp.txt #为客户端分配固定IP,不需要配置
#server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 #配置网桥模式,不需要
push "route 10.20.0.0 255.255.0.0" #给客户端生成的静态路由表,下一跳为openvpn服务器的10.8.0.1,地址段为openvpn服务器后的公司内部网络,可以是多个网段
push "route 172.31.0.0 255.255.248.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 #运行外部脚本,创建不同组的iptables 规则,不配置
;push "redirect-gateway def1 bypass-dhcp" #启用后,客户端所有流量都将通过VPN服务器,因此不需要配置
#;push "dhcp-option DNS 208.67.222.222" #推送DNS服务器,不需要配置
#;push "dhcp-option DNS 208.67.220.220"
#client-to-client #允许不同的client通过openvpn server直接通信,不开启
#;duplicate-cn #多个用户共用一个账户,一般用于测试环境,生产环境都是一个用户一个证书
keepalive 10 120 #设置服务端检测的间隔和超时时间,默认为每 10 秒 ping一次,如果 120 秒没有回应则认为对方已经 down

  所以最终配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
local 172.18.32.71    #写公网IP,测试环境无所谓
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 10.8.0.0 255.255.255.0 #默认设置,不需要修改
push "route 10.0.0.0 255.255.255.0" #内网网段,不需要修改,科学上网则为 push "redirect-gateway def1 bypass-dhcp"
client-to-client
keepalive 10 120
cipher AES-256-CBC
max-clients 100
user nobody
group nobody
persist-tun
status openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 9
mute 20

搭建CA并签发证书

  初始化pki环境

1
./easyrsa init-pki #生成pki目录用于保存证书

  创建CA签发机构,然后直接回车

1
./easyrsa build-ca nopass #创建ca并不使用密码

  创建服务端证书(私钥),直接回车

1
./easyrsa gen-req server nopass #生成server证书且不使用密码

  然后使用自建ca签发服务器证书,即生成服务端crt公钥。crt公钥后期将用户发送给客户端,从而实现与openvpnserver端加密传输数据。

1
./easyrsa sign server server #签发服务端证书,备注信息为server

  然后输入yes输入。

创建非对称秘钥对

  还在easyrsa-server目录下,生成秘钥,这可能会花费一段时间。

1
./easyrsa gen-dh

  到此服务端证书环境配置完成,下面是配置客户端证书配置

创建客户端证书及配置文件

  证书还是使用easyrsa工具,(github下载的也还是那个目录easyrsa3,不需要复制vars.example文件,改个名字就可以)

1
2
cp -r /usr/share/easy-rsa/ /etc/openvpn/easyrsa-client/
cp /usr/share/doc/easy-rsa-3.0.6/vars.example /etc/openvpn/easyrsa-client/3/vars
1
2
cd /etc/openvpn/easyrsa-client/3
./easyrsa init-pki

  例如员工为Mice,则创建名为Mice的证书

1
./easyrsa gen-req Mice nopass #客户证书为Mice,没有设置密码

  然后直接回车,便生成了Mice的证书申请和私钥。进入easyrsa的server目录中,(注意,一定要进入easyrsa-server目录,否则会报错),导入证书申请并给客户端的证书请求签发证书,记得输入yes确认。

1
2
./easyrsa import-req /etc/openvpn/easyrsa-client/3/pki/reqs/Mice.req Mice
./easyrsa sign client Mice

  复制证书到server目录:

1
2
3
4
5
6
mkdir /etc/openvpn/certs
cd /etc/openvpn/certs/
cp /etc/openvpn/easyrsa-server/3/pki/dh.pem .
cp /etc/openvpn/easyrsa-server/3/pki/ca.crt .
cp /etc/openvpn/easyrsa-server/3/pki/issued/server.crt .
cp /etc/openvpn/easyrsa-server/3/pki/private/server.key .

  创建客户端配置文件

1
2
mkdir /etc/openvpn/client/Mice/
vim /etc/openvpn/client/Mice/client.ovpn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
client #声明自己是个客户端
dev tun #接口类型,必须和服务端保持一致
proto tcp #使用的协议,必须和服务端保持一致
remote 172.18.32.71 1194 #server端的ip和端口,可以写域名但是需要可以解析成IP
resolv-retry infinite #如果是写的server端的域名,那么就始终解析,如果域名发生变化,会重新连接到新>的域名对应的IP
nobind #本机不绑定监听端口,客户端是随机打开端口连接到服务端的1194
persist-key #
persist-tun
ca ca.crt
cert Mice.crt
key Mice.key
remote-cert-tls server #指定采用服务器校验方式
#tls-auth ta.key 1
cipher AES-256-CBC
verb 3

  对签发的客户端证书及配置文件进行归档,并打包发送给客户端主机。

1
2
3
4
5
cd /etc/openvpn/client/Mice/
cp /etc/openvpn/easyrsa-server/3/pki/ca.crt .
cp /etc/openvpn/easyrsa-server/3/pki/issued/Mice.crt .
cp /etc/openvpn/easyrsa-client/3/pki/private/Mice.key .
tar czvf Mice.tar.gz *

配置防火墙转发规则

  开启路由转发功能:

1
2
3
# vim /etc/sysctl.conf
# sysctl -p
net.ipv4.ip_forward = 1

  先清除现有防火墙策略以免发生干扰,如果CentOS7/8或Redhat7/8没有iptables命令就yum install -y iptables-services安装一个,之后设置IP伪装需要用到。
  清空已有规则

1
2
3
4
5
6
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
iptables -t nat -X
iptables -t nat -Z

  创建iptables 规则:

1
2
3
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE #此IP是server端默认ip,不要改
iptables -A INPUT -p TCP --dport 1194 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

  CentOS6/7的话可以用保存iptables规则(适用未安装iptables-services,俩方式选一个就好):

1
service iptables save

  显示OK说明保存成功

1
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

  如果用的services,则systemctl enable --now iptables(会自动从/etc/sysconfig/iptables文件中读取防火墙策略)

  创建日志目录并授权:

1
2
mkdir /var/log/openvpn
chown nobody.nobody /var/log/openvpn

启动OpenVPN服务

  启动openvpn服务

1
systemctl enable --now openvpn@server

  如果没有openvpn@server.service文件,那就自己编写一个吧

1
vim /usr/lib/systemd/system/openvpn@.service
1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
Type=notify
PrivateTmp=true
ExecStart=/usr/sbin/openvpn --cd /etc/openvpn/ --config %i.conf

[Install]
WantedBy=multi-user.target

  验证日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
tail /var/log/openvpn/openvpn.log
Tue Nov 19 13:27:27 2019 Socket Buffers: R=[87380->87380] S=[16384->16384]
Tue Nov 19 13:27:27 2019 Listening for incoming TCP connection on
[AF_INET]172.18.32.71:1194
Tue Nov 19 13:27:27 2019 TCPv4_SERVER link local (bound):
[AF_INET]172.18.32.71:1194
Tue Nov 19 13:27:27 2019 TCPv4_SERVER link remote: [AF_UNSPEC]
Tue Nov 19 13:27:27 2019 GID set to root
Tue Nov 19 13:27:27 2019 UID set to root
Tue Nov 19 13:27:27 2019 MULTI: multi_init called, r=256 v=256
Tue Nov 19 13:27:27 2019 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Tue Nov 19 13:27:27 2019 MULTI: TCP INIT maxclients=4096 maxevents=4100
Tue Nov 19 13:27:27 2019 Initialization Sequence Completed

OpenVPN客户端

  官方客户端下载地址: https://openvpn.net/community-downloads/
  非官方地址:https://sourceforge.net/projects/securepoint/files/
  如果是默认安装路径的话,保存证书到openvpn 客户端安装目录:C:\Program Files\OpenVPN\config
  之后就可以直接启动OpenVPN。此时就可以用浏览器直接访问内网IP或者直接ssh登陆内部服务器了。


关于科学上网

  经过本人尝试多次,使用OpenVPN做代理转发来实现科学上网,还是有点难度。理论上简单可行的东西,搞了好几次都没成功。
  本人有亚马逊的海外云主机,在上面搭建了OpenVPN之后怎么也没法成功,甚至云主机都登陆不上了。开始以为是GW将数据包拦截了,导致云主机被封掉。后来使用其他海外主机直接连接均无法连接失联的云主机,使用端口检查工具发现,那个云主机的所有端口都被关闭了。猜测应该是被亚马逊给封掉了,无奈之下只能释放实例,重新搭建服务器。弄了数次发现,结局均以实例被封告终。猜测亚马逊应该是检查到异常流量,直接把实例的数据连接都断掉了(据说OpenVPN的收费版本不会被封掉),绝望之下,尝试了下UDP协议来代替TCP协议,将客户端设置和服务端设置都改为UPD,竟然发现可以访问外网了,而且服务器至今也平安无事~有需求的小伙伴可以尝试UDP协议。另外附上我云主机的server端配置,希望对大家有所帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
grep ^[a-Z] /etc/openvpn/server.conf
local 0.0.0.0
port 11094
proto udp
dev tun
ca /etc/openvpn/certs/ca.crt
cert /etc/openvpn/certs/server.crt
key /etc/openvpn/certs/server.key
dh /etc/openvpn/certs/dh.pem
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
cipher AES-256-CBC
max-clients 10
user openvpn
group openvpn
persist-key
persist-tun
status openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20
explicit-exit-notify 1

  本文写得很简略,发现有小伙伴对相关问题很有兴趣,欢迎留言讨论。


一个低调的男人