主要规则是:
OUTIF=eth0
/sbin/iptables --policy INPUT DROP
/sbin/iptables --policy FORWARD DROP
/sbin/iptables --policy OUTPUT ACCEPT
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A INPUT -i $OUTIF -m state --state RELATED,ESTABLISHED -j ACCEPT
我想让mysql监听lo
3306端口。我还希望它侦听 WAN 接口 ( eth0
) 上的端口 33060,因为我想让它远离机器人。
我尝试了几次重定向但没有成功。例如:
/sbin/iptables -A INPUT -p tcp -i $OUTIF --dport 34306 -j ACCEPT
/sbin/iptables -A PREROUTING -t nat -p tcp -s 0/0 --dport 34306 \
-j DNAT --to 127.0.0.1:3306
我怎样才能做到这一点?
编辑:
我要使用重迪尔但是我仍然想知道如何使用 iptables 来做到这一点。
答案1
这个可以工作,但前提是你允许从外部访问端口 3306:(但这不起作用)
iptables -t nat -A PREROUTING -p tcp --dport 34306 --syn -j DNAT --to :3306
但你最终想要做的是:(但这也行不通)
iptables -t nat -A PREROUTING -p tcp --dport 34306 --syn -j DNAT --to 127.0.0.1:3306
也就是说,您希望将发送到外部接口上端口 34306 的数据包重定向到 127.0.0.1,端口 3306。这可以工作,但一旦目的地被重写为 127.0.0.1,该数据包就会变成火星数据包(从外部进入,目的地为 127.0.0.1)。火星数据包会被正常、安静地过滤掉,而你真的非常想要这样。
有一个涉及防火墙标记的更迂回的解决方案。理论:当数据包调用外部接口上的端口 34306/tcp 时,我们只需将其标记为可接受,然后将其重写为看起来像是来自 3306/tcp。至 3306/tcp 的流量与标记被允许。到 3306/tcp 的所有其他流量都会被拒绝(通过默认策略显式或隐式)。代码:
IFACE=eth0 # or whatever
HIPORT=34306
REALPORT=3306
MARK=42 # not-so-random random number
iptables -t mangle -A PREROUTING -p tcp -i $IFACE --dport $HIPORT -j MARK --set-mark $MARK
iptables -t nat -A PREROUTING -p tcp --dport $HIPORT --syn -j DNAT --to :$REALPORT
iptables -A INPUT -p tcp -m mark --mark $MARK -j ACCEPT
iptables -A INPUT -p tcp --dport $REALPORT -j DROP # explicitly dropping
最后一条规则是您可以对不允许的数据包执行操作的位置。我喜欢记录所有丢弃的数据包,因此我的链落入最后两条规则,即 a-j LOG
和-j DROP
。因此,就我而言,我不需要它,但您自己的里程当然会有所不同。
我刚刚对此进行了测试,它适用于我的设置。这比预期的要迂回一些,但这就是 netfilter 的生活。
如果你使用状态过滤,添加--syn
到规则 3(-m mark
在链中INPUT
)并将其粘贴在您的州检查规则之前。如果您使用规则 4 明确丢弃/拒绝数据包并且执行状态防火墙,--syn
则也应该添加该规则。这有点复杂(八个完整字节),但标记检查规则仅适用于每个 TCP 连接的 SYN(第一个)数据包。一旦做出接受/拒绝决定,状态检查规则就会完成其余的工作,因此防火墙不必为每个数据包保留检查标记。没有理由浪费 CPU 周期,并且可以保持较高的网络性能。
需要注意的一些事项:
- 您的问题提到端口 33060,但您的代码使用端口 34306。我使用了后者。
- 确保 MySQL 实际上正在侦听 127.0.0.1:3306。它可以使用 Unix 域套接字进行本地通信,而不是 Internet 域 (TCP/IP) 套接字,而且它不是联网的。
- 您只需要
DNAT
数据SYN
包。状态 NAT 将自动转换所有其他数据包。这使得事情稍微快一些。 - 您不必显式指定 -s 0/0 ,只需完全忽略源即可。
问题的实质是:默默无闻的安全是一个严厉的情妇。通过更改 MySQL 正在侦听的端口,您并没有真正保护自己。端口扫描器是自动化的东西,它们不介意扫描系统上的所有端口。 :) 我建议ssh
使用-L
安全的方式使用隧道,或者,如果您想要更高级的功能,可以使用 VPN。但有时,生活给了你柠檬,你必须用 netfilter 制作柠檬水(这可能是你为数不多的东西之一)不能用它做)
答案2
只需看一下像 nmap 这样的工具,考虑一下指挥僵尸网络的恶棍拥有无限的时间和手头的机器,并估计“将 MySQL 隐藏在(容易猜测的)端口”将为您赢得多少时间。