linux 防火墙初始化

2018-08-14 18:06:39

常量定义

这些常量在后面将会用到

INTERNET="ens33"           #根据自己的接口名定义
LOOPBACK_INTERFACE="lo"
IPADDR="my.ip.address"
MY_ISP="my.isp.address.range"       #外网地址范围
SUBNET_BASE="my.subnet.network"     #子网网络地址
SUBNET_BROADCAST="my.subnet.bcast"  #子网广播地址
LOOPBACK="127.0.0.0/8"   #保留回环地址范围
CLASS_A="10.0.0.0/8"     #A私有网络
CLASS_B="172.16.0.0/12"  #B私有网络
CLASS_C="192.168.0.0/16" #C私有网络
CLASS_D_MULTICAST="224.0.0.0/4"  #D类多播地址
CLASS_E_RESERVED_NET="240.0.0.0/5"  #E类保留地址
BROADCAST_SRC="0.0.0.0"
BROADCAST_DEST="255.255.255.255"
PRIVPORTS="0:1023"
UNPRIVPORTS="1024:65535"

对于 nftables 端口的 : 要被替换成 -。

PRIVPORTS="0-1023"
UNPRIVPORTS="1024-65535"

内核相关配置

通知内核丢弃发往广播地址或组播地址的 icmp echo 请求消息。

echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

丢弃所有传入的 echo 请求消息,注意,isp 通常使用 ping 来诊断网络,dhcp 有时依赖于 echo 请求以避免地址冲突。

echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_all

源路由现如今很少被合法使用,下面是禁用源路由数据包来避免源路由欺骗

echo '1' > /proc/sys/net/ipv4/conf/all/accept_source_route

假设有客户端A、B,服务器C,服务器C的防火墙只允许客户端B来访问。此时,客户端A把数据包的源地址改成合法的B地址,并在ip包上标记 "源站选路",C以为它是合法的B就没有阻止,然后响应包通过源路由返回到A。

开启 syn flood 防御

echo '1' > /proc/sys/net/ipv4/tcp_syncookies

源地址确认也叫反向过滤技术,一个传入的数据包中带有一个源地址,然后用该源地址作为目的地址从传入接口发出,如果不能发出,那么该数据包会被丢弃。一般路由器不会开启这一确认功能,下面的命令可以禁用它:

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
    echo "0" > $f
done

记录来自不太可能的地址的数据包。

不太可能的数据包源地址包括组播或广播地址,0和127网络中的地址,以及E类保留地址空间。

不太可能的数据包目的地址包括 0.0.0.0,任何网络中的0号主机,任何127网络中的主机,以及E类地址。

echo '1' > /proc/sys/net/ipv4/conf/all/log_martians


移除所有预先存在的规则

iptables

#清空 filter 表所有规则链上的规则
iptables -F

iptables -t nat -F
iptables -t mangle -F

#删除表所有自定义链
iptables -X

iptables -t nat -X
iptables -t mangle -X

nftables

需要指定表,如果你是按照社区标准的命名约定,那么一般会有 filter 表和 nat 表。

nft flush table filter

nft flush table nat

刷新所有的规则链

for i in `nft list tables | awk '{print $3}'`
do
    echo "flushing $i"
    #nft flush table $i
done

既删除规则链,而且删除规则链和表本身。

for i in `nft list tables | awk '{print $3}'`
do
    echo "flushing $i"
    nft flush table $i  #删除表里的所有规则

    for j in `nft list table $i | grep chain | awk '{print $2}'`
    do
        echo "...deleting chain $j from table $i"
        nft delete chain $i $j  #删除链
    done

    echo "deleting $i"
    nft delete table $i   #删除表
done

注意:刷新规则链不会影响当前起作用的默认策略状态。

重置默认策略

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT

对于 nftables 来说,没有相当于 iptables 的默认策略,规则链和表都已经被删除。其实相当于 iptables 的默认 ACCEPT。

我们新建一个 setup-tables 规则文件,优先级从低到高

table ip filter {
        chain input             { type filter hook input priority 0; }
        chain forward           { type filter hook forward priority 0; }
        chain output            { type filter hook output priority 0; }
}

table ip nat {
        chain prerouting        { type nat hook prerouting priority -100; }
        chain postrouting       { type nat hook postrouting priority 100; }
        chain output            { type nat hook output priority -100; }
}

table ip mangle {
        chain output            { type route hook output priority -150; }
}

可以使用如下命令加载

nft -f setup-tables

启用回环接口

当默认策略为禁止时,回环接口就不能被访问了。

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

nftables 有2中方式

新建 localhost-policy 文件

table filter {
    chain input{
        iifname lo accept
    }

    chain output{
        oifname lo accept
    }
}
nft -f localhost-policy

下面的命令也可以做同样的事

nft add rule filter input iifname lo accept
nft add rule filter output oifname lo accept

利用连接状态绕过规则检测

在伸缩性和状态表超时方面的资源限制要求同时使用静态规则和动态规则。这种限制成了大型商业防火墙的一个卖点。 可扩展性主要是因为,大型的防火墙往往需要同时处理50000-100000个连接,有大量的状态要处理。系统资源有时会被用尽,这样就无法完成连接的追踪了。要么必须丢弃新的连接,要么必须将软件回退到无状态模式。 还有一个问题就是超时。连接状态并不能永远保持。一些慢速或静止态的连接会轻易地被清理掉,从而为更加活跃的连接留出空间。当一个数据包又传来时,状态信息必须被 重建。与此同时,当传输堆栈查找连接信息并且通知状态模块该数据包确实是已建立交换的一部分时,数据包流必须回退到无状态模式。

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -m state --state INVALID -j LOG --log-prefix "invalid input: "
iptables -A INPUT -m state --state INVALID -j DROP

iptables -A OUTPUT -m state --state INVALID -j LOG --log-prefix "invalid output: "
iptables -A OUTPUT -m state --state INVALID -j DROP

对于 nftables

nft add rule filter input ct state established,related accept
nft add rule filter input ct state invalid log prefix \"invalid input: \" limit rate 3/second drop

nft add rule filter output ct state established,related accept
nft add rule filter output ct state invalid log prefix \"invalid output: \" limit rate 3/second drop

源地址欺骗及其他不合法地址

丢弃声称来自您计算机的数据包

iptables -A INPUT -i $INTERNET -s $IPADDR -j DROP
nft add rule filter input iif $INTERNET ip saddr $IPADDR drop

阻塞发往自己的传出数据包是没有意义的,因为发送数据到外部接口,这些数据会到达回环接口的输入队列,而不是外部接口的输入队列。所以使用本机地址作为源地址的数据直接在回环返回,永远不会到达外部接口,即使你发送数据到外部接口。

下面3个规则不允许以任何A、B、C类私有网络地址为源地址的数据包传入。在一个公共网络中,这样的数据包不允许出现。

iptables -A INPUT -i $INTERNET -s $CLASS_A -j DROP
iptables -A INPUT -i $INTERNET -s $CLASS_B -j DROP
iptables -A INPUT -i $INTERNET -s $CLASS_C -j DROP

不允许声称来自回环地址,因为回环地址是为内部本地软件接口所分配的,任何这样的声称都是刻意伪造的。

iptables -A INPUT -i $INTERNET -s $LOOPBACK -j DROP

nftables

nft add rule filter input iif $INTERNET ip saddr $CLASS_A drop
nft add rule filter input iif $INTERNET ip saddr $CLASS_B drop
nft add rule filter input iif $INTERNET ip saddr $CLASS_C drop
nft add rule filter input iif $INTERNET ip saddr $LOOPBACK drop

广播

拒绝声称来自于 255.255.255.255 的数据包,这个地址为保留广播地址,0.0.0.0 作为保留的广播源地址。

netfilter 约定中指定,对任意地址(any/0,0.0.0.0/0)的匹配不会匹配到广播地址。原因是广播数据包第二层帧报头中有特定的标识符。

iptables -A INPUT -i $INTERNET -s 255.255.255.255 -j LOG
iptables -A INPUT -i $INTERNET -s 255.255.255.255 -j DROP

#拒绝目的地址为0.0.0.0
iptables -A INPUT -i $INTERNET -d 0.0.0.0 -j LOG
iptables -A INPUT -i $INTERNET -d 0.0.0.0 -j DROP

把目的地址设为 0.0.0.0 一般是用来嗅探是否为 unix 计算机。

nftables

nft add rule filter input iif $INTERNET ip saddr 255.255.255.255 log limit rate 3/second drop

nft add rule filter input iif $INTERNET ip daddr 0.0.0.0 log limit rate 3/second drop

假设我们的ip地址为 192.168.1.10/24。

拒绝两种形式的直接广播  

iptables -A INPUT -i $INTERNET -d 192.168.1.0 -j DROP
iptables -A INPUT -i $INTERNET -d 192.168.1.255 -j DROP
nft add rule filter input iif $INTERNET ip daddr 192.168.1.0 drop
nft add rule filter input iif $INTERNET ip daddr 192.168.1.255 drop

拒绝本局域网的受限广播

iptables -A INPUT -i $INTERNET -d 255.255.255.255 -j DROP
nft add rule filter input iif $INTERNET ip daddr 255.255.255.255 drop

组播地址只能为合法的目的地址,丢弃源地址为组播地址的包

iptables -A INPUT -i $INTERNET -s 224.0.0.0/4 -j DROP
nft add rule filter input iif $INTERNET ip saddr 224.0.0.0/4 drop

合法的组播包总是 udp 数据包,下面拒绝非 udp 的组播包。

iptables -A INPUT -i $INTERNET ! -p udp -d 224.0.0.0/4 -j DROP
nft add rule filter input iif $INTERNET ip daddr 224.0.0.0/4 ip protocol !=udp drop

D类组播 IP 地址范围 224.0.0.0 - 239.255.255.255。匹配地址的前4个比特 224.0.0.0/4。

下面的规则丢弃声称来自E类保留地址的网络包

iptables -A INPUT -i $INTERNET -s 240.0.0.0/5 -j DROP
nft add rule filter input iif $INTERNET ip saddr 240.0.0.0/5 drop

E 类地址范围 240.0.0.0 - 247.255.255.255。匹配地址的前5个比特 240.0.0.0/5。

禁止对常用的 tcp 非特权端口的链接

确保到远程 x window 管理器的链接不是自己传出的

iptables -A OUTPUT  -o $INTERNET -p tcp --syn --destination-port 6000:6063 -j REJECT
nft add rule filter output oif $INTERNET ct state new tcp dport 6000-6063 reject

下一条规则阻止尝试到本机的 x window 连接。

iptables -A INPUT -i $INTERNET -p tcp --syn --destination-port 6000:6063 -j DROP
nft add rule filter input iif $INTERNET ct state new tcp dport 6000-6063 drop


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。