首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iptables:将入站UDP重定向到不同的端口,并响应输出“公共”端口

iptables:将入站UDP重定向到不同的端口,并响应输出“公共”端口
EN

Server Fault用户
提问于 2020-06-25 20:13:16
回答 1查看 1.9K关注 0票数 2

我有一个SNMP代理监听一个高级端口(16161),我希望从标准SNMP代理端口161重定向流量。简易页表规则:

代码语言:javascript
复制
iptables -t nat -A PREROUTING -p udp --dport 161 -j REDIRECT --to-ports 16161

但是,响应似乎来自端口16161,并由linux客户端删除。

我希望将响应的源端口更改为161 (根据SNMP规范,这也是正确的)。我补充说:

代码语言:javascript
复制
-t nat -A POSTROUTING -p udp --sport 16161 -j SNAT --to-source :161

这似乎会导致人们的反应永远不会离开特工。如果我将to-source更改为任何其他端口,即162个端口,它就能工作。或者,如果我使用--dport 162并让客户端将请求发送到端口162,则响应可以使用端口161。只有当PREROUTING dport与POSTROUTING to-source匹配时,响应才会从代理发送失败。

例如,使用PREROUTING --dport 161和POSTROUTING --to-source 162

代码语言:javascript
复制
snmpget -v2c -c public $DEVICE_IP iso.3.6.1.2.1.1.5.0

来自代理的tcpdump,在响应包上将源端口更改为162 (预期:)

代码语言:javascript
复制
$ tcpdump -n udp and port 161 or port 162 or port 16161
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:47:30.755126 IP 192.168.66.3.55843 > 192.168.9.87.161:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:47:30.787415 IP 192.168.9.87.162 > 192.168.66.3.55843:  GetResponse(41)  .1.3.6.1.2.1.1.5.0="foo"

我甚至可以为同一个端口设置一个PREROUTING和POSTROUTING规则,但是请求不能通过响应将使用的相同端口:

代码语言:javascript
复制
$ iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 3 packets, 313 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   142 REDIRECT   udp  --  any    any     anywhere             anywhere             udp dpt:snmp redir ports 16161
    0     0 REDIRECT   udp  --  any    any     anywhere             anywhere             udp dpt:snmp-trap redir ports 16161

Chain INPUT (policy ACCEPT 3 packets, 313 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   168 SNAT       udp  --  any    any     anywhere             anywhere             udp spt:16161 to::162

单一tcpdump会话:

代码语言:javascript
复制
tcpdump -n udp and port 161 or port 162 or port 16161
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

>>>>>>> made request to port 161, response over 162, OK <<<<<<<<<

19:55:10.709670 IP 192.168.66.3.51621 > 192.168.9.87.161:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:10.751607 IP 192.168.9.87.162 > 192.168.66.3.51621:  GetResponse(41)  .1.3.6.1.2.1.1.5.0="foo"

>>>>>>> made request to port 162, response not sent <<<<<<<<<

19:55:20.372213 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:21.378445 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:22.380925 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:23.390915 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:24.393482 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0
19:55:25.397306 IP 192.168.66.3.55108 > 192.168.9.87.162:  GetRequest(28)  .1.3.6.1.2.1.1.5.0

如何让我的代理接受UDP数据包,并使用iptable在同一个端口上发送回复?

EN

回答 1

Server Fault用户

发布于 2020-06-26 16:17:18

感谢Tero对我的问题的评论,使用-j DNAT而不是REDIRECT是缺少的酱汁。最后解决办法:

在nat规则中:

代码语言:javascript
复制
-A PREROUTING -p udp --dport 161 -j DNAT --to-destination :16161
-A POSTROUTING -p udp --sport 16161 -j SNAT --to-source :161

过滤规则:

代码语言:javascript
复制
-A INPUT -p udp --dport 16161 -m conntrack --ctstate DNAT -j ACCEPT

--ctstate DNAT技巧来自于这个答案,因此只有端口161接受连接,而不是16161。

票数 1
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/1022957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档