Wireguard

简介

  • WireGuard 是由 Jason Donenfeld 等人用 C 语言编写的一个开源 VPN 协议,被视为下一代 VPN 协议,旨在解决许多困扰 IPSec/IKEv2、OpenVPN 或 L2TP 等其他 VPN 协议的问题。它与 Tinc 和 MeshBird 等现代 VPN 产品有一些相似之处,即加密技术先进、配置简单。
  • 从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着大多数 Linux 发行版的用户将拥有一个开箱即用的 WireGuard。
  • WireGuard 作为一个更先进、更现代的 VPN 协议,比起传统的 IPSec、OpenVPN 等实现,效率更高,配置更简单,并且已经合并入 Linux 内核,使用起来更加方便。

常见VPN方法比较

  • wireguard 精簡、速度極快:
    • 只有 4000 行程式碼,是最精簡的 VPN 協議。对比下 OpenVPN,大约有 10 万行代码。
  • WireGuard 利用内核空间处理来提升性能(更高吞吐和更低延迟),同时避免了不必要的内核和用户空间频繁上下文切换开销。

Wireguard客户端连接Debug

  • 首先,服务端的ip或者域名能ping通
  • 其次端口确定开放> nc -z -v -u 4.shaojiemike.top 51822,wg是udp
  • 修改wg客户端配置文件,限制ip为wg设置的内网段,AllowedIPs = 192.168.31.0/24,10.0.233.1/24.然后ping 192.168.31.1测试
  • 如果还不行,判断为wg的VPN包被中间网关识别并丢弃

配置文件

配置详解参考中文文档

PersistentKeepalive

  • 一端位于 NAT 后面,另一端直接通过公网暴露
  • 这种情况下,最简单的方案是:通过公网暴露的一端作为服务端,另一端指定服务端的公网地址和端口,然后通过 persistent-keepalive 选项维持长连接,让 NAT 记得对应的映射关系。
    • [peer]里设定字段 PersistentKeepalive = 25,表示每隔 25 秒发送一次 ping 来检查连接。

AllowedIPs

虽然AllowedIPs = 0.0.0.0/0AllowedIPs = 0.0.0.0/1, 128.0.0.0/1包含的都是全部的ip。

但是前者在iptable里为default dev wg1,后者为两条0.0.0.0/1 dev wg1128.0.0.0/1 dev wg1

由于路由的ip匹配遵循最长前缀匹配规则,如果路由表里原本有一条efault dev eth0。使用前者会导致混乱。但是使用后者,由于两条的优先级会更高,会屏蔽掉原本的default规则。

前者的iptable修改如下:(macbook上)

1
2
3
4
5
6
7
8
> ip route
default via link#18 dev utun3
default via 192.168.233.1 dev en0
10.0.233.5/32 via 10.0.233.5 dev utun3
224.0.0.0/4 dev utun3 scope link
224.0.0.0/4 dev en0 scope link
255.255.255.255/32 dev utun3 scope link
255.255.255.255/32 dev en0 scope link

后者的iptable修改如下

1
2
3
4
5
6
7
8
9
10
> ip route
0.0.0.0/1 dev utun3 scope link
default via 192.168.233.1 dev en0
default via link#18 dev utun3
10.0.233.5/32 via 10.0.233.5 dev utun3
128.0.0.0/1 dev utun3 scope link
224.0.0.0/4 dev en0 scope link
224.0.0.0/4 dev utun3 scope link
255.255.255.255/32 dev en0 scope link
255.255.255.255/32 dev utun3 scope link

原理

建议看WireGuard 教程:WireGuard 的工作原理WireGuard 基础教程:wg-quick 路由策略解读,详细解释了wg是如何修改路由表规则的。

wireguard 运行原理以及配置文件

默认会产生51840的路由table,ip rule优先级较高。可以通过配置文件中添加PostUp来修改最后一个default的路由规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@snode6:/etc/wireguard# cat wg0.conf
[Interface]
Address = 192.168.253.5/32,fd00::aaaa:5/128
PrivateKey = eGj5skRAGJu8d………………1PVfu0lY=
# PublicKey = VWe0wBVztgX………………xd7/kZ2CVJlEvS51c=

#Table必须有,不然默认的还是会修改ip rule
Table = 51820
#DNS = 1.1.1.1 #指定DNS服务器

#启动时运行: %i 是指wg的路由, 默认修改default, metric 一般不用指定
PostUp = /sbin/ip -4 route replace default dev %i table default metric 1
PostUp = /sbin/ip -6 route replace default dev %i table default metric 1
#down后运行
PostDown = /sbin/ip -4 route delete default dev %i table default metric 1
PostDown = /sbin/ip -6 route delete default dev %i table default metric 1

PostUp会产生下面的规则

1
2
root@snode6:/staff/shaojiemike# ip ro show table default
default dev wg0 scope link metric 1

OpenVPN原理

OpenVPN原理通过在main添加all规则来实现

1
2
3
# shaojiemike @ node5 in ~ [22:29:05]
$ ip route show table main
0.0.0.0/1 via 192.168.255.5 dev tun1

clash TUN模式

Macbook上的应用上的ClashX Pro的增强模式类似, 会添加如下配置,将基本所有流量代理(除开0.0.0.0/8

1
2
3
4
5
6
7
8
9
10
> ip route
1.0.0.0/8 via 198.18.0.1 dev utun3
2.0.0.0/7 via 198.18.0.1 dev utun3
4.0.0.0/6 via 198.18.0.1 dev utun3
8.0.0.0/5 via 198.18.0.1 dev utun3
16.0.0.0/4 via 198.18.0.1 dev utun3
32.0.0.0/3 via 198.18.0.1 dev utun3
64.0.0.0/2 via 198.18.0.1 dev utun3
128.0.0.0/1 via 198.18.0.1 dev utun3 #前面接受所有的ip,然后转换成198.18.0.1
198.18.0.1/32 via 198.18.0.1 dev utun3 #接受转换后的198.18.0.1,由于最长前缀匹配

明显有代理死循环问题,如何解决???

1
2
3
4
5
6
shaojiemike@shaojiemikedeMacBook-Air ~/github/hugoMinos (main*) [10:59:32]
> ip route get 198.18.0.42
198.18.0.42 via 198.18.0.1 dev utun3 src 198.18.0.1
shaojiemike@shaojiemikedeMacBook-Air ~/github/hugoMinos (main*) [10:59:38]
> ip route get 198.18.0.1
198.18.0.1 dev utun3 src 198.18.0.1

Wireguard 环境配置

wireguard-go: 安装客户端 wg-quick up config
wireguard-tools: 安装服务端 wg

Wireguard 常见命令

  • 启动wg-quick up wg1
  • 关闭wg-quick down wg1
  • 查看状态 wg显示全部,或者wg show wg1显示wg1

wireguard开机启动

1
systemctl enable wg-quick@wg1 --now

使用wireguard 代理ipv6请求

  • WireGuard 也支持 IPv6。OpenWRT 服务端,当然要allowed ip fd00::aaaa:5/128
  • 注意:这是伪需求,为什么ipv6的流量需要走ipv6,不走wg,每个机器可以获得独立的公网ipv6,对于PT做种是很好的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
brainiac1# cat wg-tsj.conf
[Interface]
PrivateKey = xxx
ListenPort = 51828
Address = 10.0.233.7/32, fd00::aaaa:5/128
Table = 51820
#DNS = 1.1.1.1

# 使用iptable修改ipv6的路由规则
PostUp = /sbin/ip -4 route replace default dev %i table default metric 1
PostUp = /sbin/ip -6 route replace default dev %i table default metric 1
PostDown = /sbin/ip -4 route delete default dev %i table default metric 1
PostDown = /sbin/ip -6 route delete default dev %i table default metric 1

[Peer]
#AllowedIPs = 0.0.0.0/0,::/0
PublicKey = xxx
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
Endpoint = 4.shaojiemike.top:51822
PersistentKeepalive = 30

两次wireguard上网

修改sysctl.conf文件的net.ipv4.ip_forward参数。其值为0,说明禁止进行IP转发;如果是1,则说明IP转发功能已经打开。

需要执行指令sysctl -p 后新的配置才会生效。

两台机器的wireguard配置

注意中间需要NAT转换, 相当于把kunpeng机器的请求,隐藏成snode6的请求。在后一次wireguard转发时,就不会被过滤掉。

1
2
PostUp   = iptables -t nat -A POSTROUTING -s 10.1.0.0/24 ! -o %i -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.1.0.0/24 ! -o %i -j MASQUERADE || true

机器(Nas)使用Wireguard上网

问题场景

由于换了wg服务端,导致nas变成闭环的网络了。最后是通过群晖助手(Synology Assistant / Web Assistant)的设置静态ip才连接上机器,但是iptable被设置乱了。

Synology Assistant can not find nas

静态连接上机器,首先在网页管理页面切换成DHCP(静态ip的DNS解析有误),iptable变成如下

1
2
3
4
5
6
7
sh-4.4# ip ro
default via 222.195.90.254 dev eth0 src 222.195.90.2
10.0.233.0/24 dev wg1 proto kernel scope link src 10.0.233.3
222.195.90.0/24 dev eth0 proto kernel scope link src 222.195.90.2

sh-4.4# ip ro s t eth0-table
222.195.90.0/24 via 222.195.90.2 dev eth0

注意iptable的修改是实时生效的。

思路

为了让nas上网我们需要满足两点

  1. 本地ssh eth0的222.195.90.2能访问机器(优先级更高)
  2. 其余网络走wg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 重要项如下
sh-4.4# ip rule
3: from 222.195.90.2 lookup eth0-table (ping 和 ssh ip 222.195.90.2的会使用这个规则)
32766: from all lookup main (ping 和 ssh 其余ip 比如wg的10.0.233.3的会使用这个规则)

# 1. 设置本地ssh eth0的222.195.90.2的高优先级,不至于开启wg断开ssh
# 使用命令添加: ip ro add default via 222.195.90.254 dev eth0 table eth0-table
sh-4.4# ip route show table eth0-table
default via 222.195.90.254 dev eth0
222.195.90.0/24 via 222.195.90.2 dev eth0

# 2. 为了使得除开本地ssh网络走wg,需要删除屏蔽default的wg的DHCP(如果提前删,导致机器ssh连接不上了,重新插拔网线,让DHCP重新配置):
# 使用命令添加:ip ro d default via 222.195.90.254 dev eth0 src 222.195.90.2 table main,
# 3. 防止服务端重启,Nas的wg客户端失联
# 使用命令添加:ip ro a 114.214.233.0/24 via 222.195.90.254 dev eth0 src 222.195.90.2 table main
# 4. 测试: ping域名能正常运行

# 其余方法:为了使得除开本地ssh网络走wg,也可以不删除,在DHCP的前面添加wg的网络通路
# 使用命令添加: ip ro add default dev wg1 proto kernel scope link src 10.0.233.3 table main
sh-4.4# ip r s t main
default dev wg1 proto kernel scope link src 10.0.233.3

使用wg1配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sh-4.4# cat /etc/wireguard/wg1.conf
[Interface]
PrivateKey = xxx
ListenPort = xxx
Address = 10.0.xxx.xxx/24

Table = 51820
PostUp = /sbin/ip -4 route replace default dev %i table default metric 1
PostDown = /sbin/ip -4 route delete default dev %i table default metric 1

[Peer]
PublicKey = xxx
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
Endpoint = 114.xxx.xxx.xxx:xxx
PersistentKeepalive = 25

问题:服务端重启,Nas的wg客户端失联

要保留没有wg的时候访问服务端的eth0(114.214.233.xxx)的通路

1
2
3
4
sh-4.4# ip ro s t main
···
114.214.233.0/24 via 222.195.90.254 dev eth0 src 222.195.90.2
···

来自eth0的ssh与ping请求原路返回

源地址为自身IP的包走学校的路由器

目的:需要ssh和ping ipv4成功

修改netplan的配置文件

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
# shaojiemike @ node5 in ~ [22:29:11]
$ cat /etc/netplan/acsa.yaml
network:
version: 2
renderer: networkd
ethernets:
eno0:
dhcp4: false
dhcp6: false
accept-ra: false
addresses:
- 202.38.73.217/24
- 2001:da8:d800:730::217/64
gateway4: 202.38.73.254
gateway6: 2001:da8:d800:730::1
nameservers:
addresses:
- 202.38.64.1
routing-policy:
- from: 202.38.73.217
table: 1
priority: 2
routes:
- to: 0.0.0.0/0
via: 202.38.73.254
table: 1

$netplan apply

routing-policy会产生

1
2
3
4
5
6
7
8
9
10
# shaojiemike @ node5 in ~ [22:30:33]
$ ip rule
0: from all lookup local
2: from 202.38.73.217 lookup 1
32766: from all lookup main
32767: from all lookup default
# 也可以手动添加
ip rule add from 202.38.73.217 table 1 pref 2
或者
ip rule add from 202.38.73.217 lookup 1 pref 2

由于2优先级高,使得ping和ssh的返回信包(源地址为自身机器IP的包)走table1 规则,而不是走

routes使得所有的table1都会走学校的路由器(202.38.73.254)

1
2
3
4
$ ip route show table 1
default via 202.38.73.254 dev eno0 proto static
# 也可以通过`ip route add`
$ ip route add default via 202.38.73.254 dev eno0 proto static table 1

衍生问题:网络请求的源地址不是自己吗?怎么确定的

开启wg后,网络请求源地址变成了10.0.33.2。不是202.38.73.217

1
2
root@node5:/home/shaojiemike# ip ro
10.0.33.0/24 dev wg2 proto kernel scope link src 10.0.33.2

但是外界ping的是202.38.73.217。返回包交换所以会产生源地址为202.38.73.217的包

wireguard 实现翻墙

  • WireGuard 在国内网络环境下会遇到一个致命的问题:UDP 封锁/限速。虽然通过 WireGuard 可以在隧道内传输任何基于 IP 的协议(TCP、UDP、ICMP、SCTP、IPIP、GRE 等),但 WireGuard 隧道本身是通过 UDP 协议进行通信的,而国内运营商根本没有能力和精力根据 TCP 和 UDP 的不同去深度定制不同的 QoS 策略,几乎全部采取一刀切的手段:对 UDP 进行限速甚至封锁。
  • 虽然对 UDP 不友好,但却无力深度检测 TCP 连接的真实性。
  • 将 UDP 连接伪装成 TCP 连接不就蒙混过关了。目前支持将 UDP 流量伪装成 TCP 流量的主流工具是 udp2raw,但是有一款更强大的新工具: Phantun

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

WireGuard 基础教程:使用 Phantun 将 WireGuard 的 UDP 流量伪装成 TCP

https://nordvpn.com/zh-tw/blog/vpn-xieyi/

https://blog.mozcp.com/wireguard-usage/

OpenVPN in Docker

在接触wireguard之前,网络返校的方案是自己在有公网IP的机器上搭建OpenVPN。而使用docker比裸机配置OpenVPN方便多了。

OpenVPN Image

ARM

我們使用 kylemanna/docker-openvpn 來實作,因為 dockerhub 上只有 x86 image,如果是 arm 平台則需要自己 build(x86 可跳過)

clone repo 後,直接 build

1
2
3
$ git clone https://github.com/kylemanna/docker-openvpn
$ cd docker-openvpn
$ docker build -t kylemanna/openvpn -f Dockerfile.aarch64 .

如果發生找不到 aarch64/alpine:3.5 的錯誤,修改 Dockerfile 中的 base image 為

1
FROM alpine:3.15.4

或更新的 alpine 版本即可

相关的中文教程

http://blog.gdb.wiki/2020/03/19/Docker-OpenVPN%E9%95%9C%E5%83%8F%E9%85%8D%E7%BD%AE/#kylemanna-openvpn%E8%BF%99%E4%B8%AA%E9%95%9C%E5%83%8F%E5%B0%86%E5%A4%A7%E9%83%A8%E5%88%86%E7%9A%84%E4%B8%80%E9%94%AE%E5%8C%96%E8%87%AA%E5%8A%A8%E8%84%9A%E6%9C%AC%E8%BF%9B%E8%A1%8C%E6%95%B4%E5%90%88%EF%BC%8C%E9%80%9A%E8%BF%87docker-run%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE

https://koding.work/10-minutes-build-open-vpn-server/

https://taichunmin.idv.tw/blog/2018-05-23-docker-openvpn.html

Quick Start

以README为主

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
# shaojiemike @ node5 in ~ [23:53:42] C:125
$ export OVPN_DATA="ovpn-data-tsj"

# shaojiemike @ node5 in ~ [23:54:10]
$ docker volume create --name $OVPN_DATA
ovpn-data-example

# shaojiemike @ node5 in ~ [23:54:11]
$ docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://node5.xydustc.me
Unable to find image 'kylemanna/openvpn:latest' locally
latest: Pulling from kylemanna/openvpn
188c0c94c7c5: Pull complete
e470f824352c: Pull complete
d6ed0c7c142e: Pull complete
74586f3c5cd4: Pull complete
cb26244a2b2a: Pull complete
Digest: sha256:643531abb010a088f1e23a1c99d44f0bd417a3dbb483f809caf4396b5c9829a0
Status: Downloaded newer image for kylemanna/openvpn:latest
Processing PUSH Config: 'block-outside-dns'
Processing Route Config: '192.168.254.0/24'
Processing PUSH Config: 'dhcp-option DNS 8.8.8.8'
Processing PUSH Config: 'dhcp-option DNS 8.8.4.4'
Processing PUSH Config: 'comp-lzo no'
Successfully generated config
Cleaning up before Exit ...

CA(certificate authority.)的私钥密码

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
# shaojiemike @ node5 in ~ [23:55:47]
$ docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/pki


Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020

Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus (2 primes)
.........+++++
...................+++++
e is 65537 (0x010001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:tsj-node5

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/pki/ca.crt

Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
......................+.......................+..........................................................+........................................................................................................+........................................+...................................................................................................................................+.....................................................................................................................+......................................................................................................................................................................................................................................+......++*++*++*++*

DH parameters of size 2048 created at /etc/openvpn/pki/dh.pem


Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020
Generating a RSA private key
.......................................+++++
.........................................+++++
writing new private key to '/etc/openvpn/pki/easy-rsa-73.EeNnaB/tmp.jhHaaF'
-----
Using configuration from /etc/openvpn/pki/easy-rsa-73.EeNnaB/tmp.LGnDjB
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'node5.xydustc.me'
Certificate is to be certified until Jan 1 15:58:37 2025 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020
Using configuration from /etc/openvpn/pki/easy-rsa-148.CDCEmf/tmp.iJCIGL
Enter pass phrase for /etc/openvpn/pki/private/ca.key:

An updated CRL has been created.

1194貌似有人用了

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
# shaojiemike @ node5 in ~ [0:02:06]
$ sudo lsof -i UDP:1194
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
openvpn 1834 nobody 6u IPv4 56802 0t0 UDP node5:openvpn

/usr/sbin/openvpn --status /run/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf

sudo vim /etc/openvpn/server/server.conf

改成7194等端口

# shaojiemike @ node5 in ~ [0:02:10]
$ sudo service openvpn status
● openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2022-04-19 18:42:24 CST; 5 months 11 days ago
Main PID: 1715 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 154181)
Memory: 0B
CGroup: /system.slice/openvpn.service

Apr 19 18:42:24 node5 systemd[1]: Starting OpenVPN service...
Apr 19 18:42:24 node5 systemd[1]: Finished OpenVPN service.

# shaojiemike @ node5 in ~ [0:15:49] C:125
$ sudo service openvpn stop

# shaojiemike @ node5 in ~ [0:16:30]
$ sudo kill -9 1834

在1195启动服务失败,还是1194

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# shaojiemike @ node5 in ~ [0:16:46]
$ docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
cb0f7e78f389f112c3c3b230d20d2b50818f6cf59eea2edfaa076c7e8fad7128

# shaojiemike @ node5 in ~ [0:06:01]
$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c716b27b3f1 kylemanna/openvpn "ovpn_run" 49 seconds ago Up 48 seconds 1194/udp, 0.0.0.0:1195->1195/udp, :::1195->1195/udp charming_zhukovsky

# 上面是错误的

# shaojiemike @ node5 in ~ [0:16:50]
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb0f7e78f389 kylemanna/openvpn "ovpn_run" About a minute ago Up About a minute 0.0.0.0:1194->1194/udp, :::1194->1194/udp pedantic_euler

产生客户端证书,和ovpn文件

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
# shaojiemike @ node5 in ~ [0:07:27] C:2
$ docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full tsj-node5-client nopass
Using SSL: openssl OpenSSL 1.1.1g 21 Apr 2020
Generating a RSA private key
...............+++++
...............................+++++
writing new private key to '/etc/openvpn/pki/easy-rsa-1.olaINa/tmp.MfohAO'
-----
Using configuration from /etc/openvpn/pki/easy-rsa-1.olaINa/tmp.EMkEHF
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
139775495048520:error:28078065:UI routines:UI_set_result_ex:result too small:crypto/ui/ui_lib.c:905:You must type in 4 to 1023 characters
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'tsj-node5-client'
Certificate is to be certified until Jan 1 16:08:23 2025 GMT (825 days)

Write out database with 1 new entries
Data Base Updated


# shaojiemike @ node5 in ~ [0:08:24]
$ docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient tsj-node5-client > tsj-node5-client.ovpn

# shaojiemike @ node5 in ~ [0:09:20]
$ ls tsj-node5-client.ovpn
tsj-node5-client.ovpn

还是不行,奇怪

解决办法

ping不通的原因是,脚本默认是8号端口,改成0号教育网端口就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
D:\PowerShell> ping -r 9 -w 10000 222.195.72.114

Pinging 222.195.72.114 with 32 bytes of data:
Reply from 222.195.72.114: bytes=32 time=60ms TTL=60
Route: 172.17.0.3 -> (局域网)
202.38.73.217 -> (node5)
202.38.96.189 -> (北京教育网)
210.45.112.254 -> (合肥教育网)
222.195.72.114 -> (snode2)
222.195.72.114 ->
202.38.96.188 ->(北京教育网)
202.38.73.254 ->(合肥教育网)
172.17.0.1

OpenVPN 3 linux client

apt install

First ensure that your apt supports the https transport:

1
# apt install apt-transport-https

Install the OpenVPN repository key used by the OpenVPN 3 Linux packages

1
# curl -x http://$proxy_addr:$proxy_http_port -fsSL https://swupdate.openvpn.net/repos/openvpn-repo-pkg-key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/openvpn-repo-pkg-keyring.gpg

Then you need to install the proper repository. Replace $DISTRO with the release name depending on your Debian/Ubuntu distribution.

1
2
# curl -x http://$proxy_addr:$proxy_http_port -fsSL https://swupdate.openvpn.net/community/openvpn3/repos/openvpn3-$DISTRO.list >/etc/apt/sources.list.d/openvpn3.list
# apt update

Supported distributions:

Distribution Release Release name ($DISTRO) Architecture DCO support
Ubuntu 20.04 focal amd64, arm64* yes*
Ubuntu 21.10 impish amd64, arm64* yes*
Ubuntu 22.04 jammy amd64, arm64* yes*

And finally the openvpn3 package can be installed

1
# apt install openvpn3

apt需要代理看 apt-get install proxy

openvpn3使用

要提前保留ipv6, 没有设置“流量走当前机器”ssh会断联

Once you’ve moved the file to your Linux system, you can import it.

1
2
openvpn3 config-import --config ${client.ovpn}
Configuration imported. Configuration path: /net/openvpn/v3/configuration/1f475d5cx8d2fx4ef5x8feex25f2871f2642

You can start a new VPN session:

1
2
openvpn3 session-start --config ${client.ovpn}
Configuration imported. Configuration path: /net/openvpn/v3/configuration/1f475d5cx8d2fx4ef5x8feex25f2871f2642

You can manage a running VPN session:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
openvpn3 sessions-list
-----------------------------------------------------------------------------
Path: /net/openvpn/v3/sessions/f83c75e4sd56cs4b27s85bcsc5c6e3ce074e
Created: Thu Oct 6 20:37:29 2022 PID: 1034954
Owner: shaojiemike Device: tun1
Config name: node5-client.ovpn
Session name: snode6.swangeese.fun
Status: Connection, Client connected
-----------------------------------------------------------------------------

$ openvpn3 session-manage
session-manage: ** ERROR ** One of --pause, --resume, --restart, --disconnect, --cleanup or --log-level must be present

$ openvpn3 session-manage --pause -c node5-client.ovpn
Initiated session pause: /net/openvpn/v3/sessions/f83c75e4sd56cs4b27s85bcsc5c6e3ce074e

需要进一步的研究学习

netplan 的 rule from to table

ip route

ip rule指令学习

iptables

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

基于kylemanna/docker-openvpn

https://openvpn.net/vpn-server-resources/connecting-to-access-server-with-linux/

OpenVPN

实验室OpenVPN使用场景

  1. 首先有一个常年挂网络通的,可以校外网IP直连的机器A。
  2. 使用OpenVPN,将对内网机器的ssh请求,通过A机器转发。

所以如果没有可以校外网IP直连的机器A,OpenVPN是没有意义的。

配置OpenVPN服务器端

google openvpn查看 ubuntu
https://ywnz.com/linuxyffq/3952.html

  1. 安装OpenVPN服务
  2. 安装easy-rsa,用来制作证书
    1
    wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz
    1. 生成CA证书(crt=cert)
      有ca.crt和ca.key两个文件
    2. 生成server端证书
      1. KEY_NAME = qszyvpn
      2. 应有qszyvpn.crt、qszyvpn.csr、qszyvpn.key三个文件
      3. 为服务器生成加密交换时的秘钥协议,应有dh2018.pem文件
    3. 生成Client端证书
      1. 应有client1.crt、client1.csr、client1.key三个文件
  3. 修改配置文件server.conf
  4. 配置规则
  5. 运行
    1
    /etc/init.d/openvpn start
  6. 查看端口占用
    1
    netstat -tunlp |grep 1194

具体服务器端文件生成命令

test on snode0

1
2
3
4
5
6
7
8
9
# 安装
sudo apt-get install openvpn
sudo apt-get install easy-rsa
# 配置easy-rsa
cd /etc/openvpn/server
cp -r /usr/share/easy-rsa/ .
## 拷贝模板并修改vars的参数
cp vars.example vars
vim vars

1
2
3
4
5
6
7
8
9
10
# 配置Easyrsa及生成公钥
./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/server/easy-rsa/pki
./easyrsa build-ca nopass
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:acsa
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/server/easy-rsa/pki/ca.crt

“nopass”参数是避免每次都要输入密码,可选项
这一步完成后,在pki目录下会生成ca.crt,pki/private目录下生成ca.key

1
2
3
4
5
6
7
8
# 生成服务器私钥和请求
./easyrsa gen-req shaojie nopass
Common Name (eg: your user, host, or server name) [shaojie]:
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/server/easy-rsa/pki/reqs/shaojie.req
key: /etc/openvpn/server/easy-rsa/pki/private/shaojie.key
# 拷贝服务器私钥文件到openvpn配置文件目录下
cp pki/private/shaojie.key /etc/openvpn/server

因为同一台服务器即做CA服务器又做VPN服务器,自己给自己签发的时候会生成同名文件,先把服务器的请求文件改个名,再导入请求

1
2
3
4
5
6
7
# 生成服务器证书
mv pki/reqs/shaojie.req pki/reqs/shaojieServer.req
./easyrsa import-req pki/reqs/shaojieServer.req shaojie
Using SSL: openssl OpenSSL 1.1.1f 31 Mar 2020
The request has been successfully imported with a short name of: shaojie
You may now use this name to perform signing operations on this request.
./easyrsa sign-req server shaojie


将两个shaojie.crt文件和ca.crt文件一起复制到openvpn配置文件目录下

1
2
3
4
5
6
cp pki/ca.crt pki/issued/shaojie.crt /etc/openvpn/server
# 生成加密文件(可选,可以提高VPN安全性),这个比较慢,需要稍等几分钟
./easyrsa gen-dh
DH parameters of size 2048 created at /etc/openvpn/server/easy-rsa/pki/dh.pem
openvpn --genkey --secret ta.key #生成随机密钥(仅适用于非TLS静态密钥加密模式):--genkey : 生成一个随机密钥作为共享密钥
cp ta.key pki/dh.pem /etc/openvpn/server

至此,服务器端文件:ca.crt dh.pem easy-rsa shaojie.crt shaojie.key ta.key准备好了

openvpn配置文件

1
2
3
4
# 拷贝解压
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/server
gzip -d /etc/openvpn/server/server.conf.gz
vim /etc/openvpn/server/server.conf
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
# 监听的端口号,默认1194,如果要改的话防火墙也要相应修改。(可选)
port 1194

#TCP或UDP,如改成tcp的话,通常端口相应修改成443
;proto tcp
proto udp

# 设置SSL/TLS根证书(ca)、证书(cert)和私钥(key),记得我的服务器名是axvpn,这里也要相应修改 (必选)
ca ca.crt
cert shaojie.crt
key shaojie.key

# 指定迪菲·赫尔曼参数。
# 默认是dh2048.pem, 记得我们生成了dh.pem,改下 (必选)
dh dh.pem

# 推送路由信息到客户端,以允许客户端能够连接到服务器背后的其他私有子网。 (可选)
# 就是允许客户端访问VPN服务器自身所在的其他局域网
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
push "route 10.111.0.0 255.255.0.0"

# 如果启用该指令,所有客户端的默认网关都将重定向到VPN,这将导致诸如web浏览器、DNS查询等所有客户端流量都经过VPN。(可选)
;push "redirect-gateway def1 bypass-dhcp"

# 某些具体的Windows网络设置可以被推送到客户端,例如DNS或WINS服务器地址。(可选)
# 下列地址来自opendns.com提供的Public DNS 服务器。
;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
push "dhcp-option DNS 8.8.8.8"

# 如果有注释的话,取消这句的注释,再加一句 (必选)
#防DDOS攻击,openvpn控制通道的tls握手进行保护,服务器端0,客户端1
tls-auth ta.key 0 # 该文件应该保密
key-direction 0

# 选择一个密码加密算法。
# 该配置项也必须复制到每个客户端配置文件中。
# 添加SHA256算法
cipher AES-256-CBC
auth SHA256

# 在完成初始化工作之后,降低OpenVPN守护进程的权限, (最好取消注释)
# 该指令仅限于非Windows系统中使用。
user nobody
group nobody

# Notify the client that when the server restarts so it
# can automatically reconnect.
# 如果协议改成了TCP,这里数值要改成0
explicit-exit-notify 1

#推送一条路由信息给客户端
#推送路由,若是推送失败,需要检查server 是否设置正常,该故障我遇到过,设置ifconfig-pool了,发现推送失效
push "route 192.168.11.0 255.255.255.0" #(即这个网段的IP的信息都经过VPN)

#记录日志,每次重新启动openvpn后追加原有的log信息
log-append /var/log/openvpn.log

配置OpenVPN客户器端


或者设置isc.ovpn(中间两项是client的)

1
2
3
4
ca ca.crt
cert ???.crt
key ???.key
tls-crypt tc.key

OneDrive下有snode6的ovpn文件

具体客户器端文件生成命令

1
2
3
4
5
6
7
8
9
10
11
12
# 生成客户端私钥和请求
./easyrsa gen-req tsjclient nopass
Common Name (eg: your user, host, or server name) [tsjclient]:
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/server/easy-rsa/pki/reqs/tsjclient.req
key: /etc/openvpn/server/easy-rsa/pki/private/tsjclient.key
# 同理生成证书
mv pki/reqs/tsjclient.req pki/reqs/tsjclient2.req
./easyrsa import-req pki/reqs/tsjclient2.req tsjclient
./easyrsa sign-req client tsjclient
# 保存所需密钥、证书和之前的ta.key ca.crt
cp pki/private/tsjclient.key pki/issued/tsjclient.crt ta.key pki/ca.crt ../../client

OpenVPN的查看

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
sudo service openvpn status
● openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
Active: active (exited) since Sat 2021-04-24 20:40:13 UTC; 2 months 22 days ago
Main PID: 1691 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 154190)
Memory: 0B
CGroup: /system.slice/openvpn.service

Warning: journal has been rotated since unit was started, output may be incomplete.
$ cat server.conf
local 202.38.73.26
port 1194
proto udp
dev tun #tun路由模式,tap桥模式,据说tun效率高于tap,但是tun只能转发IP数据,tap是二层可以封装任何协议,window下只有tap模式
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-crypt tc.key # 新加入 ,不使用 tls-auth ta.key 0 改用 tls-crypt tc.key openvpn 2.4 版的新參數
topology subnet # OpenVPN默认的拓扑方式是net30:表示掩码30位,有地址浪费
server 10.8.0.0 255.255.255.0 #定义分配给客户端的IP段,服务端自己默认使用第一个可用地址
ifconfig-pool-persist ipp.txt #在openvpn重启时,再次连接的客户端将依然被分配和以前一样的IP地址
# push表示推送,即将配置推送给客户端,让客户端也使用
push "redirect-gateway def1 bypass-dhcp" #重定向默认网关 此设置将路由/强制所有流量通过VPN。
push "dhcp-option DNS 202.38.64.56" #指定客户端使用的主DNS
push "dhcp-option DNS 202.38.64.17" #指定客户端使用的备DNS
server-ipv6 2001:0db8:ee00:abcd::/64
push "route-ipv6 2001:da8:d800:811:ae1f:6bff:fe8a:e4ba/64"
push "route-ipv6 2000::/3"
keepalive 10 120 #表示每隔10秒ping一下客户端/服务端,若是120秒内无响应,认为down,随即重启openvpn(强烈开启)
auth SHA512 # 加密算法
cipher AES-256-CBC
user nobody # 待openvpn初始化完成后,将其降级为nobody权限运行
group nogroup
persist-key #通过keepalive检测超时后,重新启动VPN,不重新读取keys,保留第一次使用的keys
persist-tun #通过keepalive检测超时后,重新启动VPN,一直保持tun或者tap设备是linkup的,否则网络连接会先linkdown然后linkup
status openvpn-status.log #状态文件:定期(默认60s)把状态信息写到该文件,以便自己写程序计费或者进行其他操作(需要关闭selinux)
verb 3 #日志记录级别,可选0-9,0只记录错误信息,4能记录普通的信息,5和6在连接出现问题时能帮助调试,9显示所有信息,甚至连包头等信息都显示(像tcpdump)
crl-verify crl.pem # crl证书 ./easyrsa gen-crl产生,默认180天过期
explicit-exit-notify # 如果协议改成了TCP,这里数值要改成0

OpenVPN配置文件通常位于/etc/openvpn中,通常命名为*.conf。 server.conf是规范的;客户端配置文件名通常类似于.conf


subnet(子网拓扑)

注意用户ccd文件固定ip时候写法变成了:

1
ifconfig-push 10.8.0.3 255.255.255.0

10.8.0.3是给VPN用户分配的虚拟IP,其服务端是server 10.8.0.0 255.255.255.0,也就是10.8.0.0/24,用户只能获取到10.8.0.X的虚拟IP,去掉10.8.0.1、10.8.0.255就只剩下253个可分配的IP池了。

重定向默认网关

为什么要重定向网关:vpn客户端是经常出差的,网络环境不安全,希望它将所有流量传到公司,经公司出口

其中包含的flags有”local autolocal def1 bypass-dhcp bypass-dns block-local ipv6 !ipv4”(多个标志之间用空格分隔),

推荐使用def1,它使用0.0.0.0/1和128.0.0.0/1而不是0.0.0.0/0来覆盖默认网关,即有新路由也保留原始默认网关,只是优先匹配而已

block-local 是表示当客户端拨入后,阻断其除与本地网关的访问外,本地的其他IP都不允许访问

PKI

Public Key Infrastructure(PKI),中文叫做公开密钥基础设施,也就是利用公开密钥机制建立起来的基础设施。

  1. PKI的核心是身份证明书的发行
  2. PKI的世界里,这个身份证明书,被叫做“证明书”。发行“证明书”的机关叫做“认证机关”。还有一个就是统一管理证明书的证书“档案库/证书库”。这三个东西加起来,就是PKI的主要构成要素。
    1. 证明书是被存放在硬盘或者IC卡里面的。证明书的文件构造是一种叫做 X.509 的协议规定的。另一方面,认证机关也其实就是一个网络应用程序。
  3. PKI提供的证明书可以用来 身份确认 和 通信加密。
    1. 用“证明书中的密钥”加密过的内容,只能用自己才有的另一个“私人的密钥”才能解密。这样的话,如果你发送给自己的内容被他人窃取的话,他人也无法解密。
    2. 在PKI机制中,放在“证明书里面的密钥”可以被任意自由分发,这里的“证明书里的密钥”被叫做“公开密钥(Public Key)”。与此相对,本人保管的那个“私人的密钥”就要做“私有密钥(Private Key)”。
  4. 认证机关的可信度,直接与证书的可信度挂钩,也就是与整个PKI机制的可信度息息相关。
    1. 在技术上,伪造证明书是非常简单的。所谓假的证明书,比如说有一个所谓的“比尔的证明书”,但是里面含有的公开密钥是史提芬的公开密钥。那么,别人发给比尔的信息,史蒂芬可以解密,反而比尔自己不能解密。

如何查看OpenVPN已连接的用户

将标志–management IP port [pw-file]添加或将相同的指令添加到您的中server.conf,例如:

management localhost 7505

这将允许您远程登录到该端口,并为您提供要运行的命令列表:

telnet localhost 7505

help

需要进一步的研究学习

暂无

遇到的问题

暂无

参考文献

5分钟让你知道什么是PKI

https://www.wsfnk.com/archives/698.html