这是我参与更文挑战的第8天,活动详情查看: 更文挑战
iptable是linux上一套防火墙服务,调用的其实是Netfilter内核模块。Netfilter是linux操作系统核心层内部的一个数据包处理模块。
- Netfilter功能
- 网络地址转换
- 数据包内容修改
- 数据包过滤防火墙功能
iptables和firewalld之间的差异
1.iptables默认允许访问服务或者通过数据包进行访问的,例如不允许某些数据包访问就可以设置具体的规则进行阻断。
2.firewalld是默认拒绝所有数据包进行访问,当设置允许一个数据包满足某个规则时才去做对应的设置。
3.firewalld在对数据安全的防护管理上用到了区域的概念,会分成很多个区域来进行安全管理,而iptables则不会分区而是直接去进行规则上的设置。
iptables安全规则
4张表
- Filter表:用于过滤数据包,默认表
- NAT表:用于网络地址转换(IP、端口)
- Mangle表:用于修改数据包的服务类型、TTL,并且可以配置路由实现QOS
- Raw:用于决定数据包是否被状态跟踪机制处理
5条链
- INPUT链:进来的数据包应用此规则链中的规则
- OUTPUT链:外出的数据包应用此规则链中的规则
- FORWARD:转发数据包应用此规则链中的规则
- PREROUTING链:对数据包做路由选择前应用此链中的规则
- POSTROUTING链:对数据包做路由选择后应用此链中的规则
常见参数选项
- -A 指向指定链添加一个或多个新规则
- -D 表示从指定链中删除一个或多个规则
- -N 表示创建一个新的用户定义链
- -F 通常是在表初始化时,指定规则链中或所有规则链中的策略
- -X 则是删除指定的用户定义链(需先清空链路中的策略)
- -p 指定具体一些协议,比如 TCP、UDP、ICMP 等常见的一些协议数据包
- -s 用来指定 IP 地址 [/ mask] 源地址
- -d 用来指定 IP 地址 [/ mask] 目标地址
- -i 指定设备数据包进入的接口,如果是多网卡的话,可能需要指定具体的接口
iptables -F 清空规则
默认设置3条规则链,INPUT、OUTPUT、FORWARD
一些案例
# 结合shell限制访问ip
iptables -A INPUT -i lo -j ACCEPT # 允许本地访问
LOCAL_NET="xxx.xxx.xxx.xxx/xx" # 允许内部指定网段访问
if [ "$LOCAL_NET" ];then
iptables -A INPUT -p tcp -s $LOCAL_NET -j ACCEPT
fi
ALLOW_HOSTS=( # 允许访问主机Ip开白
"x.x.x.x"
"x.x.x.x"
)
if [ "${ALLOW_HOSTS}" ];then
for allow_host in ${ALLOW_HOSTS[@]}
do
iptables -A INPUT -p tcp -s $allow_host -j ACCEPT
done
fi
# 结合shell设置白名单
DENY_HOSTS=( #直接丢弃列表
"xxx.xxx.xxx.xxx"
"xxx.xxx.xxx.xxx"
)
if [ "${DENY_HOSTS}" ]
then
for deny_host in ${DENY_HOSTS[@]}
do
iptables -A INPUT -s $deny_host -m limit --limit 1/s -j LOG --log-prefix "deny_host: "
iptables -A INPUT -s $deny_host -j DROP
done
fi
# 防御SYN攻击
iptables -N SYN_FLOOD
iptables -A SYN_FLOOD -p tcp --syn \
-m hashlimit \
--hashlimit 200/s \ # 每秒最多200个连接
--hashlimit-burst \ #如果连接数连续三次超过上述限制,则将有一个限制。
--hashlimit-htable-expire 300000 \ #管理表中记录的有效期限(单位:毫秒)
--hashlimit-mode srcip \ #通过源地址管理请求数
--hashlimit-name t_SYN_FLOOD \ #哈希表名存储在/proc/net /ipt_hashlimit
-j RETURN
iptables -A SYN_FLOOD -j LOG --log-prefix "syn_flood_attack: "
iptables -A SYN_FLOOD -j DROP
iptables -A INPUT -p tcp --syn -j SYN_FLOOD
# 针对icmp
iptables -N PING_OF_DEATH #丢弃ICMP超出限制
iptables -A PING_OF_DEATH -p icmp --icmp-type echo-request \
-m hashlimit \
--hashlimit 1/s \
--hashlimit-burst 10 \
--hashlimit-htable-expire 300000 \
--hashlimit-mode srcip \
--hashlimit-name t_PING_OF_DEATH \
-j RETURN
iptables -A PING_OF_DEATH -j LOG --log-prefix "ping_of_death_attack: "
iptables -A PING_OF_DEATH -j DROP
iptables -A INPUT -p icmp --icmp-type echo-request -j PING_OF_DEATH
# 针对HTTP协议,http也是基于4层的策略来限制,这里基于tcp;并不是基于7层会话的cookie session设置的。
# 所以这里也是进行的一个TCP连接,只不过是指定了访问具体的某一个服务端口,从而进行频次限制。
iptables -N HTTP_DOS
iptables -A HTTP_DOS -p tcp -m multiport --dports $HTTP \
-m hashlimit \
--hashlimit 1/s \
--hashlimit-burst 100 \
--hashlimit-htable-expire 300000 \
--hashlimit-mode srcip \
--hashlimit-name t_HTTP_DOS \ #哈希表存储在/proc /net /ipt_hashlimit
-j RETURN
iptables -A HTTP_DOS -j LOG --log-prefix "http_dos_attack: "
iptables -A HTTP_DOS -j DROP
iptables -A INPUT -p tcp -m multiport --dports $HTTP -j HTTP_DOS
# 基于SSH等服务
iptables -A INPUT -p tcp -m multiport --dports $HTTP -j ACCEPT
……
LIMITED_LOCAL_NET="xxx.xxx.xxx.xxx/xx"
if [ "$LIMITED_LOCAL_NET" ]
then
# SSH
iptables -A INPUT -p tcp -s $LIMITED_LOCAL_NET -m multiport --dports $SSH -j ACCEPT # LIMITED_LOCAL_NET -> SELF
# FTP
iptables -A INPUT -p tcp -s $LIMITED_LOCAL_NET -m multiport --dports $FTP -j ACCEPT # LIMITED_LOCAL_NET -> SELF
# MySQL
iptables -A INPUT -p tcp -s $LIMITED_LOCAL_NET -m multiport --dports $MYSQL -j ACCEPT # LIMITED_LOCAL_NET -> SELF
fi
ZABBIX_IP="xxx.xxx.xxx.xxx"
if [ "$ZABBIX_IP" ]
then
iptables -A INPUT -p tcp -s $ZABBIX_IP --dport 10050 -j ACCEPT
fi