配置多个openvpn client连接到同一个openvpn server

现在有这样一个需求:在不同地点,有多个openvpn client(RT-AC68U)同时连接到openvpn server(RT-AX89U)。每个路由器都有一个内网,要求内网直接能互访。(现在server端和每个client端的内网能互访。client端之间的内网也可以互访。)

openvpn server通过客户端证书中的common name(CN)来区分不同的openvpn client。而华硕和梅林固件自带的客户端证书只有一个,客户端证书中的 common name(CN) 是“client”。如果每个openvpn client都用同一个客户端证书,就没有办法通过客户端证书中的 CN 区分不同的openvpn client,从而针对每个client设置不同的路由。

华硕官方固件和梅林固件在openvpn上是有一些区别的:

  1. 华硕只能配置一个openvpn server,梅林可以配置2个openvpn server。
  2. 华硕的openvpn server配置中,导入新的ca.crt/server.crt/server.key无效,但是dh1024.pem是可以成功导入的。 梅林中导入ca.crt/server.crt/server.key/dh1024.pem都可以。

在华硕官方固件上制作新的客户端证书

因为固件中 /tmp/etc/openvpn/server1 已经有ca.key/ca.crt和server.key/server.crt等文件了,不用再生成ca和server证书,只需要生成新的客户端证书即可。生成客户端证书需要ca.key和ca.crt。 /tmp/etc/openvpn/server1 中的文件具体如下:

admin@RT-AX89U:/tmp/etc/openvpn/server1# ls -ltr
-rw-------    1 admin    root          1704 Jun 25 22:58 server.key   # server端的key
-rw-------    1 admin    root          1659 Jun 25 22:58 server.crt
-rwx------    1 admin    root           195 Jun 25 22:58 fw.sh
-rw-------    1 admin    root           248 Jun 25 22:58 dh.pem       # dh1024.pem
-rw-rw-rw-    1 admin    root           787 Jun 25 22:58 config.ovpn
-rw-rw-rw-    1 admin    root          5152 Jun 25 22:58 client.ovpn
drwx------    2 admin    root             0 Jun 25 22:58 ccd
-rw-------    1 admin    root          1704 Jun 25 22:58 ca.key
-rw-------    1 admin    root          1525 Jun 25 22:58 ca.crt
-rw-rw-rw-    1 admin    root             0 Jun 25 22:58 client_status
-rw-------    1 admin    root          1050 Jun 25 23:26 status

在路由器中生成新的客户端证书。路由器的rom中有easy-rsa软件,可以直接用 /rom/easy-rsa 中的软件。路由器上如果没mount u盘,可以在 /tmp 目录下生成新证书,生成后copy到本地,以免路由器重启后丢失证书。

mkdir -p /tmp/mnt/Albert/cert

cp -r /rom/easy-rsa /tmp/mnt/Albert/cert/

cd /tmp/mnt/Albert/cert/easy-rsa

参考merlin官方的 https://github.com/RMerl/asuswrt-merlin.ng/wiki/Generating-OpenVPN-keys-using-Easy-RSA

编辑vars文件中的相关变量。dh用1024即可,2048bit长度的生成速度会非常慢。没有必要用2048bit的。

vi vars
export KEY_COUNTRY="CN"
export KEY_PROVINCE="XX"
export KEY_CITY="XXX"
export KEY_ORG="AlbertInc"
export KEY_EMAIL="hq@albert.com"
#export KEY_CN=changeme
#export KEY_NAME=changeme
#export KEY_OU=changeme

执行vars文件,让变量生效。

source ./vars

初始化环境,其实就是把keys目录删掉重建。

./clean-all

把路由器中openvpn的 ca.crt和ca.key copy到 /tmp/mnt/Albert/cert/easy-rsa/keys 中。

cp -p /tmp/etc/openvpn/server1/ca.* /tmp/mnt/Albert/cert/easy-rsa/keys

生成新的客户端证书。生成时会提示输入必要的信息。

admin@RT-AX89U:/tmp/mnt/Albert/cert/easy-rsa# ./build-key pc
Generating a RSA private key
......+++++
.............+++++
writing new private key to 'pc.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [TW]:CN
State or Province Name (full name) [TW]: XX
Locality Name (eg, city) [Taipei]:XX
Organization Name (eg, company) [ASUS]:PC
Organizational Unit Name (eg, section) [ASUS]:PC
Common Name (eg, your name or your server's hostname) [pc]:
Name [EasyRSA]:
Email Address [me@myhost.mydomain]:pc@albert.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /tmp/mnt/Albert/cert/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :PRINTABLE:'XX'
localityName          :PRINTABLE:'XX'
organizationName      :PRINTABLE:'PC'
organizationalUnitName:PRINTABLE:'PC'
commonName            :PRINTABLE:'pc'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'pc@albert.com'
Certificate is to be certified until Jun 23 14:53:52 2030 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

客户端pc会生成 pc.key、pc.crt、pc.csr、04.pem 这几个文件。我们只要 pc.crt和pc.key 就可以了。

admin@RT-AX89U:/tmp/mnt/Albert/cert/easy-rsa/keys# ls -tlr
-rw-------    1 admin    root          1704 Jun 25 21:29 server.key
-rw-------    1 admin    root          1659 Jun 25 21:29 server.crt
-rw-------    1 admin    root          1704 Jun 25 21:29 ca.key
-rw-------    1 admin    root          1525 Jun 25 21:29 ca.crt
-rwxrwxrwx    1 admin    root             3 Jun 25 22:53 serial.old
-rwxrwxrwx    1 admin    root           363 Jun 25 22:53 index.txt.old
-rwxrwxrwx    1 admin    root            21 Jun 25 22:53 index.txt.attr.old
-rw-------    1 admin    root           916 Jun 25 22:53 pc.key
-rwxrwxrwx    1 admin    root           688 Jun 25 22:53 pc.csr
-rwxrwxrwx    1 admin    root             3 Jun 25 22:53 serial
-rwxrwxrwx    1 admin    root          4336 Jun 25 22:53 pc.crt
-rwxrwxrwx    1 admin    root            21 Jun 25 22:53 index.txt.attr
-rwxrwxrwx    1 admin    root           468 Jun 25 22:53 index.txt
-rwxrwxrwx    1 admin    root          4336 Jun 25 22:53 04.pem

修改client.ovpn中的如下内容:

<cert>
-----BEGIN CERTIFICATE-----
pc.crt的内容
-----END CERTIFICATE-----

</cert>

<key>
-----BEGIN PRIVATE KEY-----
pc.key的内容
-----END PRIVATE KEY-----

</key>

然后把client.ovpn导入客户端路由器。步骤如下:

vpn -> VPN客户端 -> 导入.ovpn文件 -> 点击“浏览”按钮 -> 上传client.ovpn -> 点击“上传”按钮 -> 几秒钟后文件上传成功 -> Start with WAN 选择“是” ,确保openvpn client在路由器重启后能自动启动 -> 增加用户名/密码 -> 点击“应用本页配置”

openvpn server配置

  1. 修改“服务器通信端口”

    不用默认的 1194 端口,改为其他端口,如 1196

  2. 加密密码 选择 “AES-256-CBC”
  3. RSA Encryption 选择 “2048bit”
  4. 允许客户端访问 LAN 选择 “是”
  5. 允许客户端访问互联网 选择 “否”

    如果某个客户端需要通过路由器上外网,可以在client.ovpn中加入 redirect-gateway def1 ,在openvpn client连接到server后,自动把默认路由改为路由器。

  6. 管理客户端专项 选择 “是”
  7. 允许客户端<->客户端 选择 “是”

    即配置文件中增加 "client-to-client"

  8. Allowed Clients 增加:

    CN:pc1,子网:192.168.2.0,Mask:255.255.255.0,推送:否。点击“加号”

    CN:pc2,子网:192.168.3.0,Mask:255.255.255.0,推送:否。点击“加号”

    增加后,openvpn server端可以访问到client端的内网。

  9. 自定义设置中增加:

    “push "route 192.168.2.0 255.255.255.0"”

    “push "route 192.168.3.0 255.255.255.0"”

    把2个openvpn client的内网网段推送给每个客户端,这样客户端就有了到其他客户端的路由。