iptables 拒绝所有应该接受的内容

iptables 拒绝所有应该接受的内容

大家好!

我正在尝试使用 iptables 设置我的服务器防火墙(我必须承认我上次使用 iptables 是在一年前),但是 iptables 的行为与我的要求相反。

这是我的测试脚本:

#!/bin/sh
IPT="/sbin/iptables"

echo -n "Loading iptables rules..."

# Flush old rules
$IPT --flush
$IPT --delete-chain

# Allow incoming and outgoing for loopback interfaces
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Allow incoming traffic for HTTP(S), SSH and SMTP
$IPT -A INPUT -p tcp --dport 80 -i eth0 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -i eth0 -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp --dport 25 -i eth0 -j ACCEPT
# Allow ICMP requests
$IPT -A INPUT -p icmp -i eth0 -j ACCEPT
$IPT -A OUTPUT -p icmp -o eth0 -j ACCEPT
# Allow outgoing traffic for SMTP, DNS, NTP, PgSQL, SolR, and SSH
$IPT -A OUTPUT -p tcp --dport 25 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 53 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 123 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 5433 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 5433 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 8983 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 8983 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 22 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 22 -o eth0.2654 -j ACCEPT
# Deny web server user outgoing connections
$IPT -A OUTPUT -o eth0 -m owner --uid-owner www-data -j DROP

# Drop everything else
$IPT -A INPUT -j DROP
$IPT -A OUTPUT -j DROP
$IPT -A FORWARD -j DROP

echo "rules loaded."
# Print rules as understood, then flush to avoid lockout
sleep 10
$IPT -L
# Flush old rules
$IPT --flush
$IPT --delete-chain

使用此脚本,服务器不再回答除 ping(ICMP)之外的任何请求,然后,10 秒后,打印以下文本并退出:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  100  5920 ACCEPT     all  --  lo     any     anywhere             anywhere            
    0     0 ACCEPT     tcp  --  eth0   any     anywhere             anywhere            tcp dpt:www 
    0     0 ACCEPT     tcp  --  eth0   any     anywhere             anywhere            tcp dpt:https 
    1    52 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh 
    0     0 ACCEPT     tcp  --  eth0   any     anywhere             anywhere            tcp dpt:smtp 
    0     0 ACCEPT     icmp --  eth0   any     anywhere             anywhere            
    0     0 DROP       all  --  any    any     anywhere             anywhere            

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  any    any     anywhere             anywhere            

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  100  5920 ACCEPT     all  --  any    lo      anywhere             anywhere            
    0     0 ACCEPT     icmp --  any    eth0    anywhere             anywhere            
    0     0 ACCEPT     tcp  --  any    eth0    anywhere             anywhere            tcp dpt:smtp 
    0     0 ACCEPT     tcp  --  any    eth0    anywhere             anywhere            tcp dpt:domain 
    0     0 ACCEPT     udp  --  any    eth0    anywhere             anywhere            udp dpt:domain 
    0     0 ACCEPT     udp  --  any    eth0    anywhere             anywhere            udp dpt:ntp 
    0     0 ACCEPT     tcp  --  any    eth0.2654  anywhere             anywhere            tcp dpt:5433 
    0     0 ACCEPT     udp  --  any    eth0.2654  anywhere             anywhere            udp dpt:5433 
    0     0 ACCEPT     tcp  --  any    eth0.2654  anywhere             anywhere            tcp dpt:8983 
    0     0 ACCEPT     udp  --  any    eth0.2654  anywhere             anywhere            udp dpt:8983 
    0     0 ACCEPT     tcp  --  any    eth0    anywhere             anywhere            tcp dpt:ssh 
    0     0 ACCEPT     tcp  --  any    eth0.2654  anywhere             anywhere            tcp dpt:ssh 
    0     0 DROP       all  --  any    eth0    anywhere             anywhere            owner UID match www-data 
   14  2061 DROP       all  --  any    any     anywhere             anywhere            

第一个令人不安的元素,我注意到 INPUT 和 OUTPUT 的第一条规则是接受所有数据包,而我并没有要求这样做。此外,我尝试将 INPUT 和 OUTPUT 的策略设置为 DROP(使用$IPT -P INPUT DROP$IPT -P OUTPUT DROP),但这样做最终将我锁定,即使在十秒超时之后也是如此,并且服务器只响应 ICMP,这迫使我硬重启服务器。如果我在脚本开头设置策略设置,效果相同。

我怀疑我的错误对于普通 iptables 用户来说很明显,但我已经搜索了几个小时的解决方案,而且,就像在这种情况下一样,只有有人指出来,答案才会对我显而易见。请问有哪位好心人能帮助我吗?

eth0.2654是用于与我们的 PgSQL 服务器通信的 VLAN。关于 HTTP 答案,我的印象是它们使用客户端打开的连接,这是我的规则允许的。我错了吗?

答案1

关于 HTTP 答案,我的印象是它们使用客户端打开的连接,这是我的规则允许的。我错了吗?

是的,你错了。你很可能想要接受已建立的连接或与传入连接相关的连接。因此,输入规则上接受的任何内容都可以得到回答。使用无状态防火墙,必须明确打开源端口。由于 IPtables 是有状态的,因此你不需要这样做。它将跟踪你的连接状态并自动按照你的想法允许出站连接,但前提是你告诉它这样做。此规则是iptables -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT。将其放在输出列表的顶部。如果你想特别积极,你可以将该规则绑定到特定端口。

如果您以无状态的方式看待这个问题,您必须记住数据包来自哪里以及要去哪里。您当前已将服务器设置为允许您通过 SSH 连接到另一台计算机。由于您不允许任何以端口 22 为源的流量,因此您的服务器无法响应传入连接。同样,“ESTABLISHED,RELATED”规则解决了这个问题,允许流量响应入站连接,就像允许来自端口 22 的流量一样,但与在无状态防火墙上打开 22 不同,此设置不允许从那里开始新连接。

答案2

你的方法很糟糕。你允许所有输入连接,然后在输出时停止它们。这不会阻止 DDoS 攻击。正确的方法是停止输入连接并允许输出。

通读你的代码后,我尝试重新制作。我认为它应该是这样的:

#!/bin/sh

IPT=/usr/sbin/iptables

echo "Clear firewall rules..."
$IPT -F
$IPT -Z
$IPT -t nat -F
$IPT -t nat -Z
$IPT -t mangle -F
$IPT -t mangle -Z
$IPT -X

echo "Setting firewall policy..."
$IPT -P INPUT   DROP    # Deny  all incoming connections
$IPT -P OUTPUT  ACCEPT  # Allow all outgoing connections
$IPT -P FORWARD DROP    # Deny  all forwaring

echo "Allow connections from: lo, eth0, eth0.2654"
$IPT -I INPUT -i lo   -j ACCEPT
$IPT -I INPUT -i eth0 -j ACCEPT

echo "Allow icmp requests from eth0"
$IPT -A INPUT -p icmp -i eth0 -j ACCEPT

echo "Allow traffic for HTTP(S), SSH, SMTP, DNS, NTP, PgSQL, SolR"
$IPT -A INPUT -p tcp --dport 22                 -j ACCEPT
$IPT -A INPUT -p tcp --dport 25   -i eth0       -j ACCEPT
$IPT -A INPUT -p tcp --dport 53   -i eth0       -j ACCEPT
$IPT -A INPUT -p udp --dport 53   -i eth0       -j ACCEPT
$IPT -A INPUT -p tcp --dport 80   -i eth0       -j ACCEPT
$IPT -A INPUT -p udp --dport 123  -i eth0       -j ACCEPT
$IPT -A INPUT -p tcp --dport 443  -i eth0       -j ACCEPT
$IPT -A INPUT -p tcp --dport 5433 -i eth0.2654  -j ACCEPT
$IPT -A INPUT -p udp --dport 5433 -i eth0.2654  -j ACCEPT
$IPT -A INPUT -p tcp --dport 8983 -i eth0.2654  -j ACCEPT
$IPT -A INPUT -p udp --dport 8983 -i eth0.2654  -j ACCEPT

echo "Deny web server user outgoing connections; eth0"
$IPT -A INPUT -o eth0 -m owner --uid-owner www-data -j DROP

echo "Drop everything."
$IPT -A INPUT -s 0/0 -j DROP

echo "Firewall loaded."
sleep 20
$IPT -nvL

echo "Clear firewall rules..."
$IPT -F
$IPT -Z
$IPT -t nat -F
$IPT -t nat -Z
$IPT -t mangle -F
$IPT -t mangle -Z
$IPT -X

我还没有测试过,所以请记住这一点。我不确定“-i eth0.2654”是否适用于虚拟接口。

如果您愿意,请尝试一下,然后告诉我是否有效。

相关内容