![多个 IP 地址的 SSH 配置(循环或随机)](https://linux22.com/image/213827/%E5%A4%9A%E4%B8%AA%20IP%20%E5%9C%B0%E5%9D%80%E7%9A%84%20SSH%20%E9%85%8D%E7%BD%AE%EF%BC%88%E5%BE%AA%E7%8E%AF%E6%88%96%E9%9A%8F%E6%9C%BA%EF%BC%89.png)
我有一台机器用作 SSH 跳转主机,它有多个以太网端口,每个端口都有自己的 IP 地址(192.168.1.22 和 192.168.1.178,以防万一)。我使用 SSH 来做很多事情,特别是大文件传输。我想在这两个以太网端口之间均匀分配 SSH 流量。我并不关心它是否是循环配置,或者每次连接时它是否随机选择两个 IP 地址之一,只要流量或多或少均匀分布即可。
除此之外,可以通过 SSH 从外部世界访问跳转主机,具有两个端口转发配置,一个端口(假设为 22)指向第一个 IP 地址,另一个端口(假设为 2222)指向另一个 IP 地址。可以说,我弄清楚如何在两个端口之间“循环”而不是两个 IP 地址之间更重要,因为当我在网络之外时,跳转主机最重要。
有没有一个 SSH 配置示例可以用于类似的事情?我一直找不到一个。可能使用 Match 关键字?我尝试在“主机”字段中添加多个 IP 地址,但它只使用第一个,而忽略其余的。
答案1
好吧,经过一番研究后,我找到了解决方案。
我写了两个脚本,一个名为on_lan
,另一个名为seconds_are_even
.然后,我执行这些脚本来确定应使用哪些连接参数。
这些脚本是用 python 编写的,非常简单:
局域网上
#!/usr/bin/env python3
from ipaddress import ip_address, ip_network
from itertools import chain
from sys import exit
from psutil import net_if_addrs
def ip_addr(candidate: str):
try:
return ip_address(candidate)
except Exception:
return None
def on_lan() -> bool:
IPS = {ip_addr(a.address) for a in chain.from_iterable(addrs for addrs in net_if_addrs().values()) if ip_addr(a.address)}
return any(ip in ip_network('192.168.XXX.0/24') for ip in IPS) # note that for this to work well, you don't wanna use a common LAN IP address range like 192.168.1.0/24
exit(0 if on_lan() else 1)
秒数偶数
#!/usr/bin/env python3
from time import time
from sys import exit
T = int(time())
exit(0 if T % 2 else 1)
这两个脚本可以通过 4 种不同的方式组合。我们要么在局域网上,要么不在局域网上,要么相等,要么不相等。所以我的 SSH 配置如下所示:
Host myserver.b
...
Match host *.b !exec ~/.ssh/scripts/on_lan !exec ~/.ssh/scripts/seconds_are_even
Hostname <DOMAIN NAME>
Port 2222
Match host *.b !exec ~/.ssh/scripts/on_lan exec ~/.ssh/scripts/seconds_are_even
Hostname <DOMAIN NAME>
Port 2222
Match host *.b exec ~/.ssh/scripts/on_lan !exec ~/.ssh/scripts/seconds_are_even
Hostname 192.168.1.22
Port 22
Match host *.b exec ~/.ssh/scripts/on_lan exec ~/.ssh/scripts/seconds_are_even
Hostname 192.168.1.178
Port 22
Host *.b
ServerAliveInterval 30
ServerAliveCountMax 2
IdentityFile ~/.ssh/keys.d/id_ed2551
这样,当我执行时ssh server.b
,我们首先判断我们是否在局域网上,然后判断当前秒数是否为偶数。如果我们在 LAN 上,我们使用本地 IP,否则我们使用公共域名。然后我们使用当前秒数作为随机发生器在我的 SSH 堡垒具有的两个可能的接口之间进行切换。