需求分析

openvpn在调研时不支持分流配置,需求是openvpn的开启不要影响现有的网络环境。在经过调研,发现 openvpn配置文件可以使用一些指令来指定访问某些地址的路由经过openvpn的设备,这样就可以实现了流量分流。

配置指令说明

这里主要用到了下面的参数

指令说明
dhcp-option添加额外的网络参数,可以是在客户端配置,或者服务端推送,这里有指定 DNS
redirect-gateway def1使用这个 def1 flag 可以使用0.0.0.0/1 and 128.0.0.0/1 来覆盖默认路由,这里的好处是不会擦除原有的默认网关
route可以在建立连接后,自动添加一些路由,并且在TUN/TAP设备关闭后,自动销毁
gateway默认来自 第二参数或者默认网关,第二参数为
vpn_gateway 指远端的vpn地址
net_gateway 指 per-existing IP默认网关
route-nopull当在客户端使用时,此选项有效禁止从Server将路由添加到客户端的路由表中,但是请注意,此选项仍然允许 Server 设置TCP/IP 客户端TUN/TAP接口的属性 (这里主要用作创建openvpn自己的网络接口)。
pull-filter忽略server端push 的资源,这些选项就是来自 —pul 或者其他选项的,例如其他选项 dhcp-option/route/gateway 等。

最终的配置为

text
 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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
client
proto udp
explicit-exit-notify
remote x.x.x.x 1149
dev tun
resolv-retry infinite
nobind
persist-key
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn login USERNAME password PASSWORD pin OTP
reneg-sec 0
persist-tun
remote-cert-tls server
verify-x509-name server_xxxxxxxxxxxxxxx name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
# # Prevent Windows 10 DNS leak
setenv opt block-outside-dns 
verb 3
static-challenge "Enter OTP: " 1
# 禁止服务端推送路由
route-nopull
# 配置静态路由
route x.x.x.x 255.255.255.255 vpn_gateway
route x.x.x.x 255.255.255.255 vpn_gateway
# 忽略服务器推送的 DNS 服务器
# Existing DNS settings
dhcp-option DNS 100.100.100.100
dhcp-option DNS 100.64.x.x
dhcp-option DNS 8.8.8.8
dhcp-option DNS 8.8.4.4
# Ignore server-pushed DNS to prioritize Tailscale's MagicDNS
pull-filter ignore "dhcp-option DNS"
pull-filter ignore "redirect-gateway" # Ignore server-pushed default route

auth-user-pass pass
<ca>
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----

-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----

-----END OpenVPN Static key V1-----
</tls-crypt>

在修改配置后的路由如下

bash
 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
Internet:
Destination        Gateway            Flags               Netif Expire
default            192.168.10.1       UGScg                 en0       
default            link#23            UCSIg               utun4       
8.8.4.4            link#23            UHWIig              utun4       
8.8.8.8            link#23            UHWIig              utun4       
8.210.206.245/32   10.8.0.1           UGSc                utun5           
vpn_ip/32          192.168.10.1       UGSc                  en0       
10.8/24            10.8.0.8           UGSc                utun5       
10.8.0.1           10.8.0.8           UH                  utun5       
x.x.x.x/32         10.8.0.1           UGSc                utun5      
x.x.x.x/32         10.8.0.1           UGSc                utun5          
100.64/10          link#23            UCS                 utun4       
100.64.x.x         link#23            UHWIi               utun4       
100.73.x.x         100.73.x.x         UH                  utun4       
100.100.100.100/32 link#23            UCS                 utun4       
100.100.100.100    link#23            UHWIi               utun4       
127                127.0.0.1          UCS                   lo0       
127.0.0.1          127.0.0.1          UH                    lo0       
169.254            link#16            UCS                   en0      !
192.168.10         link#16            UCS                   en0      !
192.168.10.1/32    link#16            UCS                   en0      !
192.168.10.1       3c:52:a1:34:17:ac  UHLWIir               en0   1182
192.168.10.129     5c:e9:1e:c1:ee:8f  UHLWI                 en0   1153
192.168.10.131     link#16            UHLWI                 en0      !
192.168.10.162/32  link#16            UCS                   en0      !
192.168.10.162     5c:e9:1e:c2:56:a9  UHLWI                 lo0       
192.168.10.224     46:95:6b:76:3c:6e  UHLWI                 en0    922
192.168.10.245     aa:ed:46:93:4f:88  UHLWIi                en0   1088
224.0.0/4          link#16            UmCS                  en0      !
224.0.0/4          link#23            UmCSI               utun4       
224.0.0.251        1:0:5e:0:0:fb      UHmLWI                en0       
239.255.255.250    1:0:5e:7f:ff:fa    UHmLWI                en0       
255.255.255.255/32 link#16            UCS                   en0      !
255.255.255.255/32 link#23            UCSI                utun4       

在不修改配置的路由表如下

bash
 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
$ netstat -nr            
Routing tables

Internet:
Destination        Gateway            Flags               Netif Expire
0/1                10.8.0.1           UGScg               utun6       
default            192.168.10.1       UGScg                 en0       
default            link#23            UCSIg               utun4       
8.8.4.4            link#23            UHWIig              utun4       
8.8.8.8            link#23            UHWIig              utun4       
8.210.206.245/32   10.8.0.1           UGSc                utun5           
vpn_ip/32          192.168.10.1       UGSc                  en0       
10.8/24            10.8.0.8           UGSc                utun5       
10.8.0.1           10.8.0.8           UH                  utun5       
x.x.x.x/32         10.8.0.1           UGSc                utun5      
x.x.x.x/32         10.8.0.1           UGSc                utun5          
100.64/10          link#23            UCS                 utun4       
100.64.x.x         link#23            UHWIi               utun4       
100.73.x.x         100.73.x.x         UH                  utun4       
100.100.100.100/32 link#23            UCS                 utun4       
100.100.100.100    link#23            UHWIi               utun4       
127                127.0.0.1          UCS                   lo0       
127.0.0.1          127.0.0.1          UH                    lo0       
169.254            link#16            UCS                   en0      !
192.168.10         link#16            UCS                   en0      !
192.168.10.1/32    link#16            UCS                   en0      !
192.168.10.1       3c:52:a1:34:17:ac  UHLWIir               en0   1182
192.168.10.129     5c:e9:1e:c1:ee:8f  UHLWI                 en0   1153
192.168.10.131     link#16            UHLWI                 en0      !
192.168.10.162/32  link#16            UCS                   en0      !
192.168.10.162     5c:e9:1e:c2:56:a9  UHLWI                 lo0       
192.168.10.224     46:95:6b:76:3c:6e  UHLWI                 en0    922
192.168.10.245     aa:ed:46:93:4f:88  UHLWIi                en0   1088
224.0.0/4          link#16            UmCS                  en0      !
224.0.0/4          link#23            UmCSI               utun4       
224.0.0.251        1:0:5e:0:0:fb      UHmLWI                en0       
239.255.255.250    1:0:5e:7f:ff:fa    UHmLWI                en0       
255.255.255.255/32 link#16            UCS                   en0      !
255.255.255.255/32 link#23            UCSI                utun4       

可以看到会多一条 0/1 路由。

有了这些参数就可以成功的模拟一个反向分流的配置

问题:和其他vpn一起使用时,无法解析dns

如下所示

bash
1
2
$ ping xx.xx.com
ping: cannot resolve xx.xx.com: Unknown host

这里以 MacOS 说明如何解决,使用 scutil 配置操作系统的dns解析

bash
1
2
3
4
5
6
7
8
$ sudo scutil
open
d.init
d.add SearchDomains * x.com x.top
d.add ServerAddresses * 100.100.100.100 100.64.x.x
d.add SupplementalMatchDomains * x.com x.top
set State:/Network/Service/openvpn/DNS
quit

查看 DNS 配置

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ scutil --dns
DNS configuration

resolver #1
search domain[0] : [tail769b0e.ts.net](http://tailasdas.ts.net/)
search domain[1] : [x.com](http://x.com/)
search domain[2] : x.top
nameserver[0] : 100.100.100.100
if_index : 23 (utun4)
flags    : Supplemental, Request A records, Request AAAA records
reach    : 0x00000003 (Reachable,Transient Connection)
order    : 100400

Reference

Reference manual for OpenVPN 2.6