此前一直使用CentOS运行OpenVPN多客户端程序,并在RouterOS将远程子网路由到此机器上,配置上有点复杂,也可能存在性能问题。

因此,这次打算直接在我所使用的网关RouterOS上配置。

0、简述环境

简单描述一下网络坏境,假设现在有两个网段,一个为家庭内网,一个为公司内网。

家庭网络拥有网关权限,所以可以将OpenVPN服务端部署在家庭网关上。这也是这次主要调整的地方。

在此之前,服务端部署在家庭内网中的一台CentOS中,和客户端模式一致。这需要在网关配置路由,将OpenVPN的流量路由到CentOS,多了几次跳转。

而公司内网因为没有网关的配置权限,所以仍然延续此前的模式。

网络拓扑说明,懒得画图,将就一下,自行脑部出画面就好。

  • 192.168.88.0/24 家庭网络

    • 内网卡:lan1,外网卡:wan1
    • 运行服务端
    • 服务运在网关:192.168.88.1
    • 隧道地址:10.10.10.1
    • 路由:192.168.1.0/24 -> 10.10.10.1
  • 192.168.1.0/24 公司网络

    • 内网卡:eth0
    • 运行客户端
    • 服务运行在非网关:192.168.1.110
    • 隧道地址:10.10.10.2
    • 路由:192.168.88.0/24 -> 10.10.10.1

1、连接RouterOS

本篇采用RouterOS的命令行工具进行操作,可以通过telnet亦或ssh连接到你的网关。

如果使用WinBox,也可以在左侧菜单中点击New Terminal打开终端进行操作。

使用终端操作的好处的命令便于复制,无需截图。喜欢用RouterOS的朋友们相对都有一些网络基础,应该习惯使用终端操作。

2、使用RouterOS内置证书管理工具创建证书

为了便于操作,首先切换到/certificate上下文,创建证书大部分操作都在这里,如果不特别说明,此步骤的命令均在此上下文进行操作。

[admin@RouterOS] > /certificate
[admin@RouterOS] /certificate> 

下面的命令依次创建CA根证书,OpenVPN的Server端证书,一个OpenVPN的客户端证书。

add name=ovpn-ca \
common-name=ovpn-ca \
days-valid=3650 \
key-size=2048 \
key-usage=crl-sign,key-cert-sign

add name=ovpn-server \
common-name=ovpn-server \
days-valid=3650 \
key-size=2048 \
key-usage=digital-signature,key-encipherment,tls-server

add name=client1 \
common-name=client1 \
days-valid=3650 \
key-size=2048 \
key-usage=tls-client
如果有多个客户端,重复第三条命令,注意须保证每个客户端证书的common-name唯一。

接下来给证书进行签名。

sign ovpn-ca name=ovpn-ca

sign ovpn-server name=ovpn-server ca=ovpn-ca

sign client1 name=client1 ca=ovpn-ca
如果有多个客户端,重复第三条指令对每个客户端的证书进行签名。后续步骤凡涉及多客户端的,均需要类似操作,不再赘述。

2、为OpenVPN分配IP地址池

创建一个IP地址池用于为客户端分配IP,需要给服务端预留地址,服务端地址不能在此范围内。

/ip pool add name=ovpn-pool ranges=10.10.10.100-10.10.10.199

3、创建OpenVPN配置文件

创建一个配置文件,服务器地址为10.10.10.1,远程分配地址为刚刚创建的地址池。dns-server可以设置也可以忽略。

/ppp profile add name=ovpn-profile \
use-encryption=yes \
local-address=10.10.10.1 \
remote-address=opvpn-pool \
change-tcp-mss=yes \
use-compression=yes \
use-ipv6=no

创建一个密码,用于OpenVPN用户验证,name表示用户名,password为密码,profile为上一步创建的配置文件,service选择ovpn。

/ppp secret add name=simaek \
password=simaek.com \
profile=ovpn-profile \
ervice=ovpn

4、配置OpenVPN接口

配置OpenVPN接口,默认配置文件使用上一步创建的,证书选择第一步创建的服务端证书,启用客户端证书验证,验证方法选择sha1,加密算法全部选上。

/interface ovpn-server server set \
default-profile=ovpn-profile \
protocol=tcp \
netmask=24 \
mode=ip \
port=1194 \
certificate=ovpn-server \
require-client-certificate=yes \
auth=sha1 \
cipher=aes128,aes192,aes256 \
enabled=yes 

5、配置防火墙

在防火墙input链中增加一条过滤规则,放行OpenVPN的数据。需要关注protocol选项,取决你使用tcp或者udp模式。

/ip firewall filter add chain=input \
protocol=tcp \
dst-port=1194 \
action=accept \
place-before=0 \
comment="Allow OpenVPN"

6、导出CA证书和客户端证书

将第1步签名后的证书导出到文件,export-passphrase可以为证书设置密码,为了方便,此处CA证书设置为空表示不需要密码。客户端使用密码,否则后续无法提取密钥key。

/certificate export-certificate ovpn-ca export-passphrase=""
/certificate export-certificate client1 export-passphrase=12345678

导出的文件在Files菜单中,需要使用Winbox下载到本地电脑。

cert_export_client1.crt
cert_export_client1.key
cert_export_ovpn-ca.crt

7、去除客户端证书密码(可选)

考虑到在客户端作为服务自动运行,启动需要密码不太方便,此处可以去掉密码.

这一部需要使用到Linux或者类Unix系统,使用大部分系统都会自带的openssl进行操作。

对于Windows系统,可以通过终端模拟器来完成,例如Cygwin、GitBash。

openssl rsa -in cert_export_client1.key -out client1.key

在出现提示后,输入上一步导出key时设置的密码,即可得到不需要密码的key了。

8、编写客户端配置文件

使用如下脚本将证书导入配置文件,客户端证书使用无密码的证书。

cat > client1.ovpn << EOF
client
nobind
pull
persist-key
persist-tun
dev tun
proto tcp-client
remote-cert-tls server
remote ovpn.simaek.com
port 1194
auth SHA1
auth-user-pass
auth-nocache
cipher AES-256-CBC
#redirect-gateway def1
resolv-retry infinite
reneg-sec 0
verb 3
 
<ca>
$(cat cert_export_ovpn-ca.crt)
</ca>
 
<cert>
$(cat cert_export_client1.crt)
</cert>
 
<key>
$(cat client1.key)
</key>
EOF

使用此配置文件启动客户端,测试网络连通性,在客户端ping服务端。

ping 10.10.10.1

在服务端(RouterOS)ping客户端。此时还没有配置固定IP,所以可能会有出入,根据实际客户端获取到的IP来测试。

ping 10.10.10.2

同时在RouterOS的/interface列表中也能看到当前连接的用户。

/interface/print

Flags: D - DYNAMIC; X, R - RUNNING
Columns: NAME, TYPE, ACTUAL-MTU, MAC-ADDRESS
#    NAME           TYPE     ACTUAL-MTU  MAC-ADDRESS      
0  R lan1           ether          1500  00:0C:29:34:3C:73
1  R wan1           ether          1484  2C:F0:5D:D6:BE:E5
2 DR <ovpn-simaek>  ovpn-in        1360                   

9、子网间路由

用户接口绑定

OpenVPN连接之后,生成的接口名称是动态的,不利于配置。可以在此设置接口绑定,这在配置防火墙、路由规则的时候非常有用。

/interface/ovpn-server add name=tun-company user=simaek

这会添加添加一个名为company的接口,表示到公司的隧道,绑定到用户simaek的连接上,然后在防火墙等需要配置接口的地方,便可以使用company作为接口进行配置。即使更改了用户,只需要在绑定记录上更新用户名,其他配置都不需要进行变更了。

服务端子网路由

配置OpenVPN最佳用途是连接两个子网,RouterOS无法通过cdd那样的方式来给客户端配置静态IP,推送路由信息。但好在RouterOS也是支持固定IP分配的,通过用户名密码配置指定远端(相对于服务端来说就是客户端)的IP地址,以及此用户路由的网段。

/ppp secret edit simaek remote-address
/ppp secret edit simaek routes

在出现的交互式文本编辑器中,输入指定的IP,例如:10.10.10.2,以及指定路由的网段,例如:192.168.1.0/24。

默认情况下,当成功建立连接一条OpenVPN隧道时,RouterOS会自动生成动态路由,例如按照上述的配置来说,simaek用户获得的IP时10.10.10.2,查看RouterOS路由表,会有一条10.10.10.2/32 -> <ovpn-simaek>的路由,和一条我们指定网段的路由192.168.1.0/24 -> <ovpn-simaek>

当然如果设置了接口绑定,那么此处显示为绑定的接口名称:10.10.10.2/32 -> <tun-company>

/ip route print

Flags: D - DYNAMIC; A - ACTIVE; c, s, v, y - COPY
Columns: DST-ADDRESS, GATEWAY, DISTANCE
#     DST-ADDRESS      GATEWAY       DISTANCE
0  As 0.0.0.0/0        192.168.30.1         1
  DAc 10.10.10.2/32    tun-company          0
  DAv 192.168.1.0/24   tun-company          1
  DAc 192.168.30.0/24  wan1                 0
  DAc 192.168.88.0/24  lan1                 0

为了便于客户端访问服务端局域网内主机,需要对tun-company出口的数据,以及lan出口的数据进行源地址伪装。

/ip firewall nat add chain=srcnat out-interface=tun-company action=masquerade
/ip firewall nat add chain=srcnat out-interface=lan1 action=masquerade

可在客户端OpenVPN实例上ping服务端内网IP,测试连通性。例如:

ping 192.168.88.88

客户端子网路由

由于无法从客户端获取到路由,所以在客户端需要额外做两件事情。以CentOS为例。

  1. 将服务端网段(可以是任何需要路由的网段)路由到OpenVPN网关地址。可以在客户端配置文件中写明路由的网段。这样服务启停会自动添加删除路由信息。无需手动配置。可以配置多条路由,另起一行即可。
route 192.168.88.0 255.255.255.0
route 192.168.89.0 255.255.255.0
  1. 给客户端lan接口以及OpenVPN的tun接口配置源地址伪装,便于访问局域网内主机。以iptables为例。
iptables -t nat A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
iptables -t nat A POSTROUTING -s 10.10.10.0/24 -o tun0 -j MASQUERADE
iptables -t nat -nL
service iptables save

由于没有网关访问权限,所以客户端内网如果想要访问服务端内网,需要将客户端内网机器的网关改为部署了OpenVPN的那台机器的地址。

最终效果

服务端任意主机上ping通客户端任意主机。

客户端手动配置为OpenVPN客户端IP的机器,可以ping通服务端任意主机。

10、结语

RouterOS内置的OpenvpnVPN支持的特性不是很全,一些新特性不支持,不过足够稳定使用了。

后续打算在客户端也运行RouterOS,使用内置的OpenVPN客户端进行连接。

最后修改:2022 年 01 月 30 日
如果觉得我的文章对你有用,请随意赞赏