【iptables】k8s节点上设置iptables策略

k8s节点上设置iptables策略

# cat set-k8s-iptales.sh

#!/bin/bash

ips="
172.17.0.0/16
172.18.0.0/16
10.86.0.0/16
10.96.0.0/16

127.0.0.1

192.168.1.52
192.168.1.53
192.168.1.54
192.168.1.55
192.168.1.39
192.168.1.40
"

# 在服务器上执行 iptables -F 命令时,默认会清理当前默认表(filter表)中所有链(如INPUT、FORWARD、OUTPUT等)的规则,但不会删除链本身,也不会影响其他表(如nat、mangle等)的规则
# k8s集群不在默认的filter表、链上做策略,iptables -F 不会清理k8s集群创建的表、链(因为它们通常在 nat 表)
iptables -F


# 如果filter表中不存在ipWhiteList链,创建
ipWhiteList=`iptables-save | grep ipWhiteList`
if [ "novalue$ipWhiteList" = 'novalue' ];then
        echo "no ipWhiteList"
        iptables -t filter -N ipWhiteList
fi

# 如果filter表中不存在portWhiteList链,创建
portWhiteList=`iptables-save | grep portWhiteList`
if [ "novalue$portWhiteList" = 'novalue' ];then
        echo "no portWhiteList"
        iptables -t filter -N portWhiteList
fi


# 如要对访问目标port的源ip访问做限制示例
# iptables -t filter -A portWhiteList -s 10.29.88.193/24 -p tcp -m multiport --dport 22 -j ACCEPT

# 不对访问目标端口的源ip做限制
iptables -t filter -A portWhiteList -p tcp -m multiport --dport 22  -j  ACCEPT


# 将 portWhiteList 链附加到 INPUT 链,使规则生效
iptables -t filter -A INPUT -j portWhiteList

# 设置 ipWhiteList 规则(允许白名单 IP)
# 遍历 ips 列表,为每个 IP/CIDR 添加规则:-s ${ip}:匹配源 IP  -j ACCEPT:允许匹配的流量
for ip in ${ips};
  do iptables -t filter -A ipWhiteList  -s ${ip}  -j  ACCEPT
done

# 将 ipWhiteList 插入到 INPUT 链的最前面(优先级高于后续规则)
iptables -t filter -I INPUT -j ipWhiteList

# 拒绝所有未匹配前面规则的流量(默认拒绝)
# 注意:REJECT 会返回拒绝响应(ICMP port unreachable),而 DROP 会静默丢弃
iptables -t filter -A INPUT -j REJECT

# 允许已经建立的连接(如 SSH 会话、HTTP 响应)
# -I INPUT:插入到 INPUT 链的最前面(优先级最高)
iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# iptables  -nvL   --line

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1       44  4672 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
2        1    64 ipWhiteList  all  --  *      *       0.0.0.0/0            0.0.0.0/0
3        1    64 portWhiteList  all  --  *      *       0.0.0.0/0            0.0.0.0/0
4        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 30 packets, 4452 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain ipWhiteList (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  *      *       172.17.0.0/16        0.0.0.0/0
2        0     0 ACCEPT     all  --  *      *       172.18.0.0/16        0.0.0.0/0
3        0     0 ACCEPT     all  --  *      *       10.86.0.0/16         0.0.0.0/0
4        0     0 ACCEPT     all  --  *      *       10.96.0.0/16         0.0.0.0/0
5        0     0 ACCEPT     all  --  *      *       127.0.0.1            0.0.0.0/0
6        0     0 ACCEPT     all  --  *      *       192.168.1.52         0.0.0.0/0
7        0     0 ACCEPT     all  --  *      *       192.168.1.53         0.0.0.0/0
8        0     0 ACCEPT     all  --  *      *       192.168.1.54         0.0.0.0/0
9        0     0 ACCEPT     all  --  *      *       192.168.1.55         0.0.0.0/0
10       0     0 ACCEPT     all  --  *      *       192.168.1.39         0.0.0.0/0
11       0     0 ACCEPT     all  --  *      *       192.168.1.40         0.0.0.0/0

Chain portWhiteList (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        1    64 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 22

image.png

iptables 防火墙脚本详细解读

这个 bash 脚本用于配置 Linux 系统的 iptables 防火墙规则,主要实现 IP 白名单和端口访问控制功能。

下面我将详细解析每一部分:

1. IP 白名单定义

ips="
172.17.0.0/16
172.18.0.0/16
10.86.0.0/16
10.96.0.0/16
127.0.0.1
192.168.1.52
192.168.1.53
192.168.1.54
192.168.1.55
192.168.1.39
192.168.1.40
"

这部分定义了一个 IP 地址/CIDR 块的白名单列表,包括:

  • Docker 默认网段 (172.17.0.0/16, 172.18.0.0/16)
  • 两个 10.0.0.0/16 的私有网络
  • 本地回环地址 (127.0.0.1)
  • 多个 192.168.1.0/24 的特定主机

2. 初始化防火墙

iptables -F

清空 filter 表中所有链的规则(但不删除链本身,不影响其他表如 nat、mangle)

3. 创建自定义链

IP 白名单链

ipWhiteList=`iptables-save | grep ipWhiteList`
if [ "novalue$ipWhiteList" = 'novalue' ];then
        echo "no ipWhiteList"
        iptables -t filter -N ipWhiteList
fi

检查是否已存在名为 ipWhiteList 的自定义链,不存在则创建

端口白名单链

portWhiteList=`iptables-save | grep portWhiteList`
if [ "novalue$portWhiteList" = 'novalue' ];then
        echo "no portWhiteList"
        iptables -t filter -N portWhiteList
fi

同样方式检查并创建 portWhiteList

4. 配置端口访问规则

iptables -t filter -A portWhiteList -p tcp -m multiport --dport 22 -j ACCEPT

portWhiteList 链中添加规则:

  • 允许所有 TCP 流量访问 22 端口(SSH)
  • -m multiport 支持多端口(虽然这里只指定了 22)
iptables -t filter -A INPUT -j portWhiteList

portWhiteList 链附加到 INPUT 链,使规则生效

5. 配置 IP 白名单规则

for ip in ${ips};
  do iptables -t filter -A ipWhiteList  -s ${ip}  -j  ACCEPT
done

遍历 IP 白名单列表,为每个 IP/CIDR 添加规则:

  • -s ${ip} 匹配源 IP
  • -j ACCEPT 允许匹配的流量
iptables -t filter -I INPUT -j ipWhiteList

ipWhiteList 链插入到 INPUT 链的最前面(优先级高于后续规则)

6. 设置默认策略

iptables -t filter -A INPUT -j REJECT

拒绝所有未匹配前面规则的入站流量(返回拒绝响应)

iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

INPUT 链最前面插入规则:

  • 允许已建立的连接和相关的流量(确保现有连接不受影响)

规则执行顺序总结

  1. 允许已建立的连接(最高优先级)
  2. IP 白名单检查(允许白名单 IP)
  3. 端口访问控制(允许 SSH 访问)
  4. 拒绝所有其他流量(默认策略)

安全注意事项

  1. SSH 访问:脚本允许所有 IP 访问 22 端口,这可能不安全,建议限制源 IP
  2. REJECT vs DROP:使用 REJECT 会返回拒绝响应,DROP 则静默丢弃,后者更安全但可能影响用户体验
  3. Kubernetes 兼容性:注释提到 k8s 使用 nat 表,所以清空 filter 表不会影响 k8s
  4. 规则持久化:脚本未包含保存规则的命令(如 iptables-save),重启后规则会丢失

这个脚本实现了基本的白名单防火墙功能,适合需要严格限制访问来源的环境使用。

如何清理自定义链 ipWhiteList portWhiteList ?

要清理自定义链 ipWhiteListportWhiteList,你需要先确保这些链没有被任何其他链引用,然后才能删除它们。以下是清理这些自定义链的步骤:

#!/bin/bash

# 清理 ipWhiteList 链
# 1. 从所有引用它的规则中删除引用
iptables-save | grep -E "ipWhiteList" | while read -r line; do
    # 提取链名和规则号
    chain=$(echo "$line" | awk '{print $2}')
    rule_num=$(echo "$line" | awk '{print $1}' | cut -d'[' -f2 | cut -d']' -f1)
    # 删除引用规则
    iptables -t filter -D "$chain" "$rule_num"
done

# 2. 清空链本身的所有规则
iptables -t filter -F ipWhiteList

# 3. 删除链
iptables -t filter -X ipWhiteList

# 清理 portWhiteList 链
# 1. 从所有引用它的规则中删除引用
iptables-save | grep -E "portWhiteList" | while read -r line; do
    # 提取链名和规则号
    chain=$(echo "$line" | awk '{print $2}')
    rule_num=$(echo "$line" | awk '{print $1}' | cut -d'[' -f2 | cut -d']' -f1)
    # 删除引用规则
    iptables -t filter -D "$chain" "$rule_num"
done

# 2. 清空链本身的所有规则
iptables -t filter -F portWhiteList

# 3. 删除链
iptables -t filter -X portWhiteList

echo "已清理 ipWhiteList 和 portWhiteList 自定义链"

说明:

  1. 首先查找所有引用这些自定义链的规则并删除它们
  2. 使用 -F 选项清空链中的所有规则
  3. 最后使用 -X 选项删除空链

注意事项:

  • 执行此脚本需要 root 权限
  • 如果链已经被其他规则引用但没有被正确删除,-X 命令会失败并显示错误信息
  • 建议在执行前先备份当前 iptables 规则:iptables-save > iptables.backup
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容