在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 表与链之间的包含关系

filterINPUT、FORWARD、OUTPUT
natPREROUTING(DNAT)、OUTPUT、POSTROUTING(SNAT)
manglePREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
rawPREROUTING、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

6. 参考文档

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐