抱歉,这篇文章太长了,我有一台运行 ubuntu 22.04 服务器的远程电脑,上面有两个服务,ssh 和 xrdp,我使用它通过 checkpoint VPN 连接到远程办公室,无论如何,一切运行良好,但要保持与本地网络 (192.168.50.0/24) 的连接,需要在 VPN 连接开始之前必须输入一些命令。
sudo ip rule add table 128 from 192.168.50.215
sudo ip route add table 128 to 192.168.50.0/24 dev ens33
sudo ip route add table 128 default via 192.168.50.1
需要考虑的一些信息是,这台远程 PC 通过 dhcp4 获取其 IP,但其分配的 IP 为 192.168.50.215,网关为 192.168.50.1。
这里的问题是,有时当 VPN 连接时出现某种网络故障(例如由于服务提供商导致链接断开和接通),规则和路由就会消失,然后无法通过 ssh 或 RDP 访问,而修复该问题的唯一方法是在控制台(TTY)中再次输入这些命令。
所以我一直在寻找解决方案,我在 Google 上搜索了很多次,找到了一些应该可以配置 netplan 的东西,这样它就可以在接口启动和关闭时(包括在启动时)安装这些线路。
我一直关注这个问题:[在 netplan 中重现一组 ip 命令][1],但是它有点旧了。
我编写了一个 00-network-config.yaml 并添加了以下内容:
> # This is the network config written by 'subiquity'
network:
renderer: networkd
ethernets:
enp2s1:
dhcp4: true
routing-policy:
- from: 192.168.50.215
table: 128
routes:
- to: default
via: 192.168.50.1
- to: 192.168.50.0/24
via: 192.168.50.1
table: 128
on-link: True
- to: 0.0.0.0/0
via: 192.168.50.1
table: 128
on-link: True
version: 2
我尝试过没有第一条路线(通往主路线表的默认路线)的其他变体。
但是当我获得这个实时功能(使用 netplan apply 等)时,我遇到了以下问题:
从 192.168.50.0/24 中的任何 PC ping 192.168.50.215(远程 PC)都可以
从 192.168.50.215 ping 192.168.50.0/24 中的任何位置也可以
从 192.168.50.215 进行 SSH 连接,一切正常。
从 192.168.50.0/24(例如 192.168.50.214)到 192.168.50.215 的 SSH 不起作用,我得到这个:
kex_exchange_identification:读取:对端重置连接,192.168.50.215 端口 22 重置连接
任何 RDP 连接都无法工作。
此时,我认为可能存在某种防火墙阻止内容,但 UFW 处于非活动状态,并且 iptables -L 将所有内容打开,因此似乎没有被阻止,我读到一些文章说这可能是路由问题,但我不知道。
为了收集更多有关此信息,我收集了一些有关路由的信息,如下所示:
在 DHCP 没有路由并手动写入 IP 规则/路由的情况下,我得到以下信息:
rule show
ip rule show
0: from all lookup local
32765: from 192.168.50.215 lookup routing
32766: from all lookup main
32767: from all lookup default
route table routing - 128
ip route show table 128
default via 192.168.50.1 dev ens33
192.168.50.0/24 dev ens33 scope link
route table local
ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.168.50.215 dev ens33 proto kernel scope host src 192.168.50.215
broadcast 192.168.50.255 dev ens33 proto kernel scope link src 192.168.50.215
route table main
ip route show table main
default via 192.168.50.1 dev ens33 proto dhcp src 192.168.50.215 metric 100
192.168.50.0/24 dev ens33 proto kernel scope link src 192.168.50.215 metric 100
192.168.50.1 dev ens33 proto dhcp scope link src 192.168.50.215 metric 100
ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:45:3b:9f brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.50.215/24 metric 100 brd 192.168.50.255 scope global dynamic ens33
valid_lft 47843sec preferred_lft 47843sec
inet6 fe80::20c:29ff:fe45:3b9f/64 scope link
valid_lft forever preferred_lft forever
通过之前显示的 netplan 文件我得到:
rule show
ip rule show
0: from all lookup local
32765: from 192.168.50.215 lookup routing proto static
32766: from all lookup main
32767: from all lookup default
route table routing - 128
ip route show table 128
default via 192.168.50.1 dev ens33 proto static onlink
192.168.50.0/24 via 192.168.50.1 dev ens33 proto static onlink
route table local
ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.168.50.215 dev ens33 proto kernel scope host src 192.168.50.215
broadcast 192.168.50.255 dev ens33 proto kernel scope link src 192.168.50.215
route table main
ip route show table main
default via 192.168.50.1 dev ens33 proto static onlink
default via 192.168.50.1 dev ens33 proto dhcp src 192.168.50.215 metric 100
192.168.50.0/24 dev ens33 proto kernel scope link src 192.168.50.215 metric 100
192.168.50.1 dev ens33 proto dhcp scope link src 192.168.50.215 metric 100
ip a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:45:3b:9f brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.50.215/24 metric 100 brd 192.168.50.255 scope global dynamic ens33
valid_lft 86109sec preferred_lft 86109sec
inet6 fe80::20c:29ff:fe45:3b9f/64 scope link
valid_lft forever preferred_lft forever
所以大部分都是一样的,我对此束手无策,所以如果有人可以帮助我,我觉得我的 netplan yaml 应该可以工作,但遗憾的是它不行。
我在 dmesg 和 journalctl 中没有看到任何有趣的东西,但如果有人知道该怎么做,请告诉我,因为我即将放弃 ubuntu 服务器。PD:如果有人提到 yaml 上的 on-link,你可以阅读我在这里发布的链接,因为没有它,路由根本就不会注册。[1]:在 netplan 中重现一组 ip 命令
答案1
我不确定您的 Netplan 配置是否损坏。您描述的行为是可以预料到的,因为 SSH 在 TCP 上运行,因此会对丢失的数据包进行错误检查。您可以考虑从另一个角度解决这个问题 — 让您的远程 shell 连接更能抵御中断。
首先,SSH 有一些技巧。添加以下内容可能有助于延长 ssh 连接套接字的打开时间。
# </home/User/.ssh/config>
Host *
ControlMaster auto
ControlPath /tmp/%r@%h:%p
ControlPersist 4h
#-- If the network disappears your connection will hang,
#-- but if it then re-appears with 10 minutes it will resume working.
TCPKeepAlive no
ServerAliveInterval 60
ServerAliveCountMax 10
您还可以考虑使用除 ssh 之外的其他远程终端。例如,Mosh 就是专门为此目的而设计的。
... 描述: 支持漫游和智能本地回显的移动外壳 Mosh 是一个远程终端应用程序,支持:
- 网络连接不稳定,
- 漫游到不同的 IP 地址而不会断开连接,并且
- 智能本地回显和线路编辑,减少“网络延迟”对高延迟连接的影响。主页:https://mosh.org
最后,在服务器端使用 mux 系统将使您的会话即使断开连接也能保持。连接中断时运行的任何任务都将继续在后台运行。这与通过 SSH 运行的正常进程形成对比,后者将在连接断开时被终止。出于这个目的,我是 byobu 的粉丝,但您的情况可能会有所不同。
描述:文本窗口管理器、shell 多路复用器、集成 DevOps 环境 Byobu 是 Ubuntu 强大的基于文本的窗口管理器、shell 多路复用器和集成 DevOps 环境。
使用 Byobu,您可以通过单个 SSH 连接或 TTY 终端快速创建并在不同窗口之间移动,将每个窗口拆分为多个窗格,监视有关系统的数十个重要统计数据,稍后分离并重新连接到会话,同时程序继续在后台运行。主页:http://byobu.org
总结
你的 OP 没有说明你是否使用 SSH 来建立 XRDP 连接。如果是这种情况,你可以考虑类似西庇太而是。这是另一个隧道协议,多年前我曾使用过,类似于隧道 VNC。它比 SSH 的优势在于它不需要持久连接,这对您的情况有帮助。但是,它需要从代码编译,因此不是最简单的解决方案。