最近有个远程接入虚拟局域网的需求,简单的端口映射已经不能解决问题了,横向对比了一下GRE、PPTP、IPSEC、SSLVPN和OPENVPN,最后综合兼容性、易用性、跨平台性选择了OPENVPN的开源版本。
实验环境:
服务 |
版本 |
IP |
内网Ubuntu |
20.04.1 |
172.17.2.9 |
公网网关 |
Null |
10.30.68.10 |
公网Client |
Null |
10.30.68.69 |
实验目的:
- 使公网Client可以获取内网172.17.2.0/24上的资源
先决条件:
- 网关将UbuntuOVPN端口映射至UDP-10.30.68.10:1194上
- Ubuntu可以访问互联网
实验步骤:
一、更新apt源、安装所需软件
| ubuntu@ubuntu:~$ sudo apt update && sudo apt -y install openvpn easy-rsa openssl
|
二、建立公钥基础设施(根CA)
先将easy-rsa目录复制到/etc/openvpn下,这将确保更新软件包时不会丢失对脚本的任何更改。
| ubuntu@ubuntu:/etc/openvpn$ sudo mkdir /etc/openvpn/easy-rsa/ ubuntu@ubuntu:/etc/openvpn$ sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/
|
签发根CA证书:
| ubuntu@ubuntu:/etc/openvpn$ cd /etc/openvpn/easy-rsa/ ubuntu@ubuntu:/etc/openvpn/easy-rsa$ sudo ./easyrsa init-pki ubuntu@ubuntu:/etc/openvpn/easy-rsa$ sudo ./easyrsa build-ca nopass
|
三、签发服务器证书
| ubuntu@ubuntu:/etc/openvpn/easy-rsa$ sudo ./easyrsa build-server-full server nopass
|
这里同样会询问一些生成证书的常见问题
同样因为实验环境,均选择默认值即可。
所有证书和密钥均已在子目录/pki中生成,复制到/etc/openvpn/
| ubuntu@ubuntu:/etc/openvpn/easy-rsa$ sudo cp pki/{issued/server.crt,private/server.key,ca.crt} /etc/openvpn
|
生成DH参数:
| ubuntu@ubuntu:/etc/openvpn$ sudo openssl dhparam -out dh2048.pem 2048
|
生成tls-auth key
| ubuntu@ubuntu:/etc/openvpn$ sudo openvpn --genkey --secret /etc/openvpn/ta.key
|
四、签发客户端证书
VPN客户端也将需要证书来向服务器进行身份验证。通常,需要为每个客户端创建一个不同的证书。
| ubuntu@ubuntu:~$ cd /etc/openvpn/easy-rsa/ ubuntu@ubuntu:/etc/openvpn/easy-rsa$ sudo ./easyrsa build-client-full client1
|
使用安全方法将以下文件复制到客户端:
- /etc/openvpn/ta.key
- /etc/openvpn/easy-rsa/pki/ca.crt
- /etc/openvpn/easy-rsa/pki/issued/client1.crt
- /etc/openvpn/easy-rsa/pki/private/client1.key
由于客户端证书和密钥仅在客户端计算机上是必需的,因此应将其从服务器中删除。
五、配置服务端参数
将示例配置文件解压至目录
| ubuntu@ubuntu:/etc/openvpn$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/ ubuntu@ubuntu:/etc/openvpn$ sudo gzip -d /etc/openvpn/server.conf.gz
|
配置服务端参数:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| ubuntu@ubuntu:/etc/openvpn/server$ sudo vi server.conf # listen on? (optional) ;local a.b.c.d port 1194 proto udp #定义IP端口 dev tun #定义模式 ca ca.crt cert myserver.crt key myserver.key dh dh2048.pem #定义证书 server 10.8.0.0 255.255.255.0 #定义服务器与客户机隧道之间的ip段 ifconfig-pool-persist /var/log/openvpn/ipp.txt #定义与客户端虚拟ip的对应关系,冷启动可为客户分配与之前相同的ip push "route 172.17.2.0 255.255.255.0" #推送给客户机的路由条目 ;push "redirect-gateway def1 bypass-dhcp" #推送给客户机默认路由,令其全部流量均通过VPN ;duplicate-cn #如果不同客户会使用同样的证书登录,则需取消注释此行 keepalive 10 120 #10秒ping一次,共计120秒超时即强制断开 tls-auth ta.key 0 #通过takey创建"HMAC firewall"以帮助阻止DoS攻击和UDP端口泛洪 cipher AES-256-CBC #选择加密方式 persist-key persist-tun #persist选项将尝试避免在重新启动时访问某些资源,这些资源由于特权降级而可能不再可访问。
status /var/log/openvpn/openvpn-status.log verb 1 #日志输出等级 explicit-exit-notify 1 #通知客户端服务器重新启动后,它可以自动重新连接。
|
六、启动OpenVPN服务
注意:openvpn使用模板化的systemd jobs,如:openvpn@.
如果配置文件名为“server.conf”那么开启所需的命令应该像这样:
| ubuntu@ubuntu:/etc/openvpn$ systemctl start openvpn@server
|
如果上面创建的私钥使用了密码,那么还需要导入密码
| ubuntu@ubuntu:~$ sudo systemd-tty-ask-password-agent
|
检查OpenVPN是否创建了Tun0接口:
| ubuntu@ubuntu:~$/etc/openvpn# ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:0c:29:59:f2:34 brd ff:ff:ff:ff:ff:ff inet 172.17.2.25/24 brd 172.17.2.255 scope global dynamic ens160 valid_lft 67959sec preferred_lft 67959sec 3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100 link/none inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0 valid_lft forever preferred_lft forever
|
七、配置内核转发和防火墙参数
开启内核转发
| ubuntu@ubuntu:~$ sudo vi /etc/ufw/sysctl.conf #将以下行的注释取消 net/ipv4/ip_forward=1
|
开启ufw接收转发的包
| ubuntu@ubuntu:~$ sudo vi /etc/default/ufw #修改以下行的参数 DEFAULT_FORWARD_POLICY="ACCEPT"
|
添加openvpn的ufw app条目
| ubuntu@ubuntu:~$ sudo vi /etc/ufw/applications.d/openvpn [OpenVPN] title=OPENVPN description=OPENVPN ports. ports=1194/udp
|
这里通过添加源nat来实现路由转发。
在理解逻辑上可以看作VPN拨号的10.8.0.0/24网段是内网,而172.17.2.0/24为外网;而且给客户端push了172.17.2.0的外网路由。因此只开启源net即可实现网段互通。
| ubuntu@ubuntu:~$ sudo vi /etc/ufw/before.rules #在文件底部添加以下内容 *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.8.0.0/24 -o ens160 -j MASQUERADE #此处需要根据自身机器外网网卡名称修改 COMMIT
|
启动ufw
| ubuntu@ubuntu:~$ sudo ufw reload ubuntu@ubuntu:~$ sudo ufw allow OpenSSH ubuntu@ubuntu:~$ sudo ufw allow OpenVPN ubuntu@ubuntu:~$ sudo ufw enable
|
八、配置客户机参数
客户机参数可以参考/usr/share/doc/openvpn/examples/sample-config-files/client.conf
示例文件
也可使用https://github.com/graysky2/ovpngen
配置生成器生成ovpn.file
记得将客户机连接的ip换成映射后的ip和端口