我有一台具有多个 IP 地址的服务器。此服务器上正在运行 sshd,我可以连接到它。我还可以将其用作 socks 代理,使用 ssh 的 danymic 转发,这很棒。当我将服务器用作 socks 代理时,其默认出站 IP 地址将用作 IP 连接的源。有没有办法配置哪个 IP 地址将用作 socks 代理的源?
举个例子:我有一个客户端,其 IP 地址为 1.1.1.1,还有一个服务器,其 IP 地址为 2.2.2.2 和 3.3.3.3。默认情况下,服务器的所有出站 IP 连接都使用 2.2.2.2。我想使用 ssh 的动态转发从 1.1.1.1 连接到 4.4.4.4,连接似乎来自 3.3.3.3,使用服务器和 ssh 作为 socks 代理。
当我使用 ssh 动态转发进行连接时,是否有任何方法可以配置 ssh 以使用 3.3.3.3 作为源 ip?最好避免更改该服务器上的常规路由,例如使用 netcat 并避免使用 iptables 的方法。
答案1
看来openssh守护进程目前不包含此功能:功能connect_next()
打开连接不使用任何bind()
系统调用,而只使用socket()
和connect()
:没有为改变默认源地址做出任何规定。
这是一个基于路由的方法,使用了 Linux 4.10 中出现的功能(因此内核 >= 4.10 是先决条件):
添加了 Linux 4.10支持按 UID 路由,从而避免了不得不采取笨拙的iptables規則。
考虑到sshd一旦通过身份验证,就会切换到目标 ssh 用户,转发的连接将代表服务器上经过身份验证的 ssh 用户发起,而不是根。
可以创建与特定用户绑定的特定路由规则:此用户(且只有此用户)将触发使用备用路由设置,这些路由设置与正常路由相同,除了为默认源 IP 地址。这需要将主路由表的大部分内容复制到备用路由表中,以涵盖所有情况。
因此,如果 Linux 系统有一个专用用户来自3333使用 uid 3333 和以下路线将显示ip route
(从此推断评论,请将 2.2.2.1 替换为实际网关并使用正确的接口名称),同时设置辅助地址 3.3.3.3eth0但没有出现在主要的路由表:
default via 2.2.2.1 dev eth0
2.2.2.0/24 dev eth0 proto kernel scope link src 2.2.2.2
这将需要覆盖默认路由,并且出于依赖性原因(2.2.2.1 在查找下表 3333 时必须有一条路由,这将发生在主要的表将被查找以提供它)以及 LAN 路由。最后给出:
# ip route add table 3333 2.2.2.0/24 dev eth0 src 3.3.3.3
# ip route add table 3333 default via 2.2.2.1 dev eth0 src 3.3.3.3
# ip rule add uidrange 3333-3333 lookup 3333
现在,任何由 uid 3333(又名用户来自3333)将选择路由表 3333,它将选择默认源地址 3.3.3.3,而不是 2.2.2.2(除非被应用程序覆盖,但对于sshd),但除此之外将使用相同的路由。例如回复数据包,它们没有来自3333作为所有者,仍将选择主要的路由表,并且它仍将按预期工作。
这将影响用户创建的任何连接来自3333在服务器上,包括通过DynamicForward
/-D
或LocalForward
/发起的-L
代表从运行的 ssh启动的客户系统。
如果服务器具有(按复杂程度排序)附加路由、路由规则或路由表,则必须根据具体情况调整此答案,可能需要进行更多的路由复制工作。