将 SSH 预路由到不同的内部端口

将 SSH 预路由到不同的内部端口

我正在开发本地 git 项目,并且使用非 root 用户在端口 2222 上运行单独的 SSH 服务。除此之外,我使用 ufw 防火墙并打开端口 2222 - 我打开它只是为了测试与其的连接是否按预期工作并且没问题。

因为 SSH 的默认端口是 22,并且我不希望用户在地址中写入其他端口来访问存储库,所以我想将其从 22 预路由到 2222。另外,我希望在预路由时无法从外部访问端口 2222是有效的。

基本上我已经完成了第一部分 - 我将流量从 22 预先路由到 2222,如果端口 2222 也打开,它可以正常工作,但是当尝试关闭端口 2222 时,到 22 的连接也会停止工作(打开端口的规则是还在那儿)。这在某种程度上是合乎逻辑的,因为 iptables 似乎只是将端口 22 转换为 2222 并将其转发到 ufw,然后 ufw 会识别这一点并拒绝连接,因为端口 2222 未打开。

目前,这是我在 ufw 的 before.rules 中的内容,如果端口 2222 也打开,它就可以工作:

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222

有没有办法在不需要打开端口 2222 的情况下执行此预路由?

答案1

原则上不会。在这里使用ufw并不重要,因为它仅充当前端,创建 iptables 规则。正如您所注意到的,NAT 规则是在任何过滤之前处理的,因此过滤器会在任何 NAT 规则之后看到生成的数据包。 (维基百科有一个看起来相当可怕的图表netfilter 内的数据包流,这表示它们是独立的。)

我不确定在其他端口上也可以访问服务器是否是一个大问题。

但是,如果您确实想丢弃直接发送到端口 2222 的数据包,您可以使用一些技巧来实现,即使用连接标记,即目标CONNMARKconnmark模块:

nat表中,在连接上设置标记,并将其重定向到目标端口。

iptables -t nat -A PREROUTING -p tcp --dport 22 -j CONNMARK --set-mark 1234
iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222

filter(默认)表中,如果没有标记,则拒绝连接。

iptables -A INPUT -p tcp --dport 2222 -m connmark ! --mark 1234 -j REJECT

标记编号是多少并不重要,只要它不与您的其他规则冲突即可。

(我不确定是否也可以DROP在 NAT 表中创建规则。iptables v1.4.21 似乎不允许这样做,但抱怨来自 iptables 本身,而不是来自内核,就像它那样REJECT.)

答案2

我宁愿使用配置而不是批处理或以任何方式直接运行 iptables。我总是将 DROP 设置为过滤器表中 INPUT 和 OUTPUT 的默认操作。因此我的解决方案如下。

纳特

...

-A 输入 -p tcp --dport 2222 -m connmark ! --标记1234

-A 预路由 -p tcp --dport 22 -j 重定向 --to-端口 2222

筛选

...

-p tcp --dport 2222 -m connmark --mark 1234 -j 接受

相关内容