Linux iptables和五链四表相关规则说明
在k8s环境中经常使用iptables规则进行负载均衡、路由转发和NAT等操作,本文针对iptables的实现原理和相关常用方法进行整理和讨论。
1. iptables的作用
iptables是一种用于配置和管理Linux操作系统上的防火墙的工具。它允许系统管理员定义和维护数据包过滤规则,以控制进入和离开系统的网络流量。通过使用iptables,管理员可以实现以下功能:
- 数据包过滤:iptables可以根据源IP地址、目标IP地址、源端口、目标端口、协议等条件过滤网络数据包,从而允许或拒绝特定的流量。
- NAT(Network Address Translation):iptables可以进行网络地址转换,将内部IP地址和端口映射到外部IP地址和端口,实现内部网络与外部网络之间的通信。
- 防止DDoS攻击:iptables可以根据流量频率和连接数等指标进行限制,从而帮助防止分布式拒绝服务(DDoS)攻击。
- 负载均衡:iptables可以根据负载状况将流量分配到不同的服务器上,从而实现负载均衡。
- 网络地址过滤:iptables可以过滤特定的IP地址或IP地址范围,从而限制对系统的访问。
总而言之,iptables是一个功能强大的工具,可以帮助管理员保护系统免受恶意网络流量的攻击,并提供对网络流量的精细控制。
2. iptables和netfilter的联系和区别
iptables和netfilter是两个密不可分的概念,它们都是Linux操作系统中用于网络数据包过滤和防火墙功能的重要组件。
- Netfilter是一个内核层的框架,用于在Linux内核中进行数据包处理。它提供了一个抽象层,允许用户空间程序(如iptables)通过Netfilter钩子函数来捕获和操作网络数据包。Netfilter框架支持各种功能,包括数据包过滤、NAT(网络地址转换)、连接追踪等。
- iptables则是一个用户空间的命令行工具,它是对Netfilter框架的接口封装,用于配置和管理防火墙规则。iptables允许用户定义不同的规则集,以过滤和修改网络数据包。用户可以使用iptables命令来添加、删除、修改防火墙规则,从而实现对网络流量的控制和管理。
因此,iptables是通过与Netfilter框架进行交互来实现网络数据包过滤和防火墙功能的。iptables提供了更方便和友好的用户接口,使得用户可以轻松地配置和管理防火墙规则,而Netfilter则在内核层实现了具体的数据包处理和转发功能。
3. 四表五链说明
3.1 四表
四表:filter、nat、managle、raw,默认是filter表。表的处理优先级:raw>managle>nat>filter
表 | 作用 | 备注 |
---|---|---|
filter | 过滤数据包 | 主要用于过滤数据包,该表根据系统管理员预定义的一组规则过滤符合条件的数据包。对于防火墙而言,主要利用在filter表中指定的规则来实现对数据包的过滤。Filter表是默认的表,如果没有指定哪个表,iptables 就默认使用filter表来执行所有命令,filter表包含了INPUT链(处理进入的数据包),RORWARD链(处理转发的数据包),OUTPUT链(处理本地生成的数据包)在filter表中只能允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改 |
nat | 网络地址转换(端口映射、地址映射等。) | 主要用于网络地址转换NAT,该表可以实现一对一,一对多,多对多等NAT 工作,iptables就是使用该表实现共享上网的,NAT表包含了PREROUTING链(修改即将到来的数据包),POSTROUTING链(修改即将出去的数据包),OUTPUT链(修改路由之前本地生成的数据包) |
mangle | 用于对特定数据报的修改。 | 主要用于对指定数据包进行更改,在内核版本2.4.18 后的linux版本中该表包含的链为:INPUT链(处理进入的数据包),RORWARD链(处理转发的数据包),OUTPUT链(处理本地生成的数据包)POSTROUTING链(修改即将出去的数据包),PREROUTING链(修改即将到来的数据包) |
raw | 优先级最高,设置raw时一般是为了不再让iptables做数据报的链接跟踪处理,提高性能。 | 只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了RAW表,在 某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了. |
3.2 五链
五链:PREROUTING 、INPUT、FORWARD、OUTPUT、POSTROUTING
链 | 作用 |
---|---|
PREROUTING | 数据包进入路由表之前,对数据包做路由选择前应用此链路中的规则,所有的数据包进来的时候都先由这个链处理 |
INPUT | 通过路由表后目的为本机,进来的数据报应用此规则链上的策略 |
FORWARD | 通过路由表后,目标地址不为本机,做转发数据报时应用此规则链上的策略 |
OUTPUT | 由本机产生的外出的数据包向外转发时,应用此规则链中的策略 |
POSTROUTING | 数据报做路由选择后发送后到网卡接口之前应用此链中的规则,所有的数据包出来的时候都先由这个链处理 |
五链的链路的数据示意走向图
一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转发出去。
- 如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经 过OUTPUT链,然后到达POSTROUTING链输出。
- 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过 FORWARD链,然后到达POSTROUTING链输出。
3.3 表与链之间的包含关系
表 | 链 |
---|---|
filter | INPUT、FORWARD、OUTPUT |
nat | PREROUTING(DNAT)、OUTPUT、POSTROUTING(SNAT) |
mangle | PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING |
raw | PREROUTING、OUTPUT |
4. iptables规则的常用命令和使用方法
4.1 iptables规则组成
- 数据包访问控制:ACCEPT、DROP、REJECT
- 数据包改写:SNAT、DNAT
- 信息记录:LOG
iptables [-t TABLE] COMMAND CHAIN [num] 匹配标准 -j 处理办法
4.2 规则数据管理
管理规则:
-A:附加一条规则,添加在链的尾部
-I CHAIN [num]:插入一条规则,插入为对应CHAIN上的第num条,不指定默认为第一条
-D CHAIN [num]:删除指定链中的第num条规则
-R CHAIN [num]:替换指定的规则
管理链:
-F [CHAIN]:flush,情况指定规则链,如果省略CHAIN,则可以实现删除对应表中的所有链
-P CHAIN:设定指定链的默认策略 iptables -P INPUT DROP
-N:自定义一个新的空链
-X:删除一个自定义的空链
-Z:置零指定链中所有规则的计数器
-E:重命名自定义的链
查看类:
-L:显示指定表中的规则
-n:以数字格式显示主机地址和端口号
-v:显示链及规则的详细信息
-x:显示计数器的精确值
--line-numbers:显示规则号码
保存规则:
# /etc/init.d/iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
清理规则:
iptables -F
5. 常用的iptables场景
5.1 禁止外部主机ping内部主机
# 禁ping
iptables -w -t filter -I INPUT -p icmp -m icmp --icmp-type 8 -j DROP
# 解ping
iptables -w -t filter -D INPUT -p icmp -m icmp --icmp-type 8 -j DROP
5.2 禁止某些端口访问
iptables -A INPUT -p tcp --dport 18:80 -j DROP
iptables -A INPUT -p tcp -m multiport --dport 21,22,23 -j DROP
5.3 只允许某些ip端和端口访问
5.3.1 非k8s机器
# 配置脚本 iptables.sh
#!/bin/bash
echo $- | grep -q i || cd "$(dirname "$0")"
set -u
set -e
set -o pipefail
### 以下内容需要根据环境和服务修改 ###
chain="TEST_WHITELIST"
dports="65535,65534"
### 以上内容需要根据环境和服务修改 ###
iplist=()
if test -s ./ip.txt
then :
iplist=($(sort -u ./ip.txt))
else :
true
fi
func_do() {
iptables -w -t filter -N $chain
test "$iplist" && iptables -w -t filter -I $chain -j REJECT
for ip in ${iplist[@]}
do :
iptables -w -t filter -I $chain -s $ip -j RETURN
done
iptables -w -t filter -I $chain -m addrtype --src-type LOCAL -j RETURN
test "$iplist" && iptables -w -t filter -I INPUT -p tcp -m multiport --dports $dports -j $chain
# test "$iplist" && iptables -w -t filter -I INPUT -p udp -m multiport --dports $dports -j $chain
}
func_undo() {
while iptables -w -t filter -D INPUT -p tcp -m multiport --dports $dports -j $chain 2>/dev/null
do :
sleep 0.1
done
# while iptables -w -t filter -D INPUT -p udp -m multiport --dports $dports -j $chain 2>/dev/null
# do :
# sleep 0.1
# done
iptables -w -t filter -F $chain 2>/dev/null || true
iptables -w -t filter -X $chain 2>/dev/null || true
}
func_bk() {
iptables-save > ./iptables_bk_$(date +%s)
}
func_help() {
echo "$0 do|undo"
}
case "${1:-help}" in
"do" ) func_bk && func_undo && func_do ;;
"undo" ) func_bk && func_undo ;;
"bk" ) func_bk ;;
* ) func_help ;;
esac
5.3.2 k8s机器
#!/bin/bash
echo $- | grep -q i || cd "$(dirname "$0")"
set -u
set -e
set -o pipefail
### 以下内容需要根据环境和服务修改 ###
chain="TEST_WHITELIST"
dports="11180,65528"
### 以上内容需要根据环境和服务修改 ###
iplist=()
if test -s ./ip.txt
then :
iplist=($(sort -u ./ip.txt))
else :
true
fi
func_do() {
iptables -w -t mangle -N $chain
test "$iplist" && iptables -w -t mangle -I $chain -j DROP
for ip in ${iplist[@]}
do :
iptables -w -t mangle -I $chain -s $ip -j RETURN
done
iptables -w -t mangle -I $chain -m addrtype --src-type LOCAL -j RETURN
test "$iplist" && iptables -w -t mangle -I PREROUTING -p tcp -m multiport --dports $dports -j $chain
# test "$iplist" && iptables -w -t mangle -I PREROUTING -p udp -m multiport --dports $dports -j $chain
}
func_undo() {
while iptables -w -t mangle -D PREROUTING -p tcp -m multiport --dports $dports -j $chain 2>/dev/null
do :
sleep 0.1
done
# while iptables -w -t mangle -D PREROUTING -p udp -m multiport --dports $dports -j $chain 2>/dev/null
# do :
# sleep 0.1
# done
iptables -w -t mangle -F $chain 2>/dev/null || true
iptables -w -t mangle -X $chain 2>/dev/null || true
}
func_bk() {
iptables-save > ./iptables_bk_$(date +%s)
}
func_help() {
echo "$0 do|undo"
}
case "${1:-help}" in
"do" ) func_bk && func_undo && func_do ;;
"undo" ) func_bk && func_undo ;;
"bk" ) func_bk ;;
* ) func_help ;;
esac
5.3.3 配置访问来源和执行脚本
ip.txt代表允许访问的来源ip和网段
cat ip.txt
# 配置单个ip
10.10.10.10
# 配置网段
10.10.20.0/24
执行命令
sh iptables.sh do