文章目录

  • 注意事项
  • 1. 地址列表填写规范
  • 2. 代码块
  • 2.1. Shell
  • 2.2. Python
  • 3. 执行结果
  • 4. 地址与端口获取方法
  • 4.1 tcpdump抓包分析(推荐使用)
  • 4.2 TCP连接分析(仅能识别TCP连接)



注意事项

  • 请务必按照格式填写具体参数,否则会影响到匹配规则的创建,严重时会影响到业务流量!!!
  • 请务必按照格式填写具体参数,否则会影响到匹配规则的创建,严重时会影响到业务流量!!!
  • 请务必按照格式填写具体参数,否则会影响到匹配规则的创建,严重时会影响到业务流量!!!

1. 地址列表填写规范

ip.txt文件内容填写案例:

ip port 						# 单个地址和单个端口格式
ip port1,port2...				# 单个地址和多个端口格式
ip/net port						# 网段地址和单个端口格式
ip/net port1,port2...			# 网段地址和多个端口格式
  • 地址文件名称为ip.txt,若需替换则修改代码块第9if test -s ./ip.txt;ip.txt即可;
  • 多个IP地址请务必隔行输出,请使用英文半字符格式输入配置;
  • 添加IP地址不可重复,但支持包含关系;
  • 支持CIDR格式添加IP地址;
  • 多个端口使用 [逗号] 间隔;
  • IP地址与端口之间使用 [空格] 字符进行间隔。
  • 若不了解该服务,可先查阅iptables服务详解

2. 代码块

2.1. Shell

#!/bin/bash

file_path=$(dirname "$0")
cd $file_path

chain="IP_WHITELIST"											# 创建链名称为:IP_WHITELIST
ip_list=""

if test -s ./ip.txt; then
	cat ip.txt | awk '{print$1}' > ./ip_temp.txt				# IP地址去重
	ip_list=($(sort -u ./ip_temp.txt))
	rm -f ./ip_temp.txt
fi

function create_rule(){
	# 注意iptables插入顺序
	iptables -w -t filter -N $chain								# 创建新链
	iptables -w -t filter -I $chain -j DROP						# 匹配所有流量,执行动作拒绝
	for ip in ${ip_list[@]}; do
		dports=`cat ip.txt | grep "$ip" | awk '{print$2}'`
		if [ -z "$dports" ]; then								# 判断端口列表是否为空
			iptables -w -t filter -I $chain -s $ip -j ACCEPT
		else
			iptables -w -t filter -I $chain -s $ip -p tcp -m multiport --dports $dports -j ACCEPT
		fi
	done
	echo -e "\033[32miptables service rule crete complete!\033[0m" 
}

function delete_rule(){
	# 清理iptables创建的匹配规则
	while iptables -w -t filter -D INPUT -p tcp -j $chain 2>/dev/null; do 		# 忽略删除匹配规则错误信息
		sleep 0.1s	
	done
	# 
	iptables -w -t filter -F $chain 2>/dev/null
    iptables -w -t filter -X $chain 2>/dev/null
    echo -e "\033[32miptables service rule cleanup complete!\033[0m" 
}

function backup_rule(){
	# 备份当前环境下iptables规则到指定目录下临时文件
	iptables-save > ./iptables_bk_$(date +"%Y-%m-%d %H:%M:%S")	# 以时间指定文件名称
	echo -e "\033[32miptables service rule backup complete,path is "$file_path"/iptables_bk_<local_time>\033[0m"
}

case ${1:-help} in 
	"create" )
		# 先备份规则,再清理规则,后创建新规则
		backup_rule && delete_rule && create_rule
		;;
	"delete" )
		# 先备份规则,再清理规则
		backup_rule && delete_rule
		;;
	"backup" )
		# 直接备份规则
		backup_rule
		;;
	* )
		# 可用参数说明
		echo -e "\033[31m  Usage: \n\t$0 options is [create/delete/backup/help]\033[0m"
		;;
esac

2.2. Python

import os
import subprocess
import sys
from datetime import datetime

CHAIN_NAME = "IP_WHITELIST"

def help():
    print("\033[32m  Usage: \n\t{}脚本参数说明:[ create 创建 / delete 删除 / backup 备份 / help 帮助 ]"
          "\n\t脚本所用地址/网段+端口配置案例,文件指定名称ip.txt:"
          "\n\t\t1.1.1.1 80\t\t\t地址+端口"
          "\n\t\t2.2.2.2 80,81,82\t\t地址+多端口"
          "\n\t\t3.3.3.3\t\t\t\t单个地址"
          "\n\t\t4.4.4.4/32\t\t\t单个网段"
          "\n\t\t5.5.5.5/32 80,81,82\t\t网段+多端口"
          "\033[0m".format(sys.argv[0]))

def create_rule():
    # 注意iptables插入顺序
    subprocess.run(["iptables", "-w", "-t", "filter", "-N", CHAIN_NAME])
    # 优先配置拒绝any规则
    subprocess.run(["iptables", "-w", "-t", "filter", "-I", CHAIN_NAME, "-j", "DROP"])
    with open("ip.txt") as f:
        ip_list = sorted(list(set([line.split()[0] for line in f])))
    for ip in ip_list:
        with open("ip.txt") as f:
            # dports 若没有填写,列表取值会报索引异常,需消除异常
            try:
                dports = ",".join([line.split()[1] for line in f if line.split()[0] == ip])
            except IndexError as _:
                # 变量滞空
                dports = None
        if not dports:
            subprocess.run(["iptables", "-w", "-t", "filter", "-I", CHAIN_NAME, "-s", ip, "-j", "ACCEPT"])
        else:
            subprocess.run(["iptables", "-w", "-t", "filter", "-I", CHAIN_NAME, "-s", ip, "-p", "tcp", "-m", "multiport", "--dports", dports, "-j", "ACCEPT"])
    print("\033[32miptables service rule crete complete!\033[0m")

def delete_rule():
    # 清理iptables创建的匹配规则,-F 清空,-X 删除
    while subprocess.run(["iptables", "-w", "-t", "filter", "-D", "INPUT", "-p", "tcp", "-j", CHAIN_NAME], stderr=subprocess.DEVNULL).returncode == 0:  # 忽略删除匹配规则错误信息
        pass
    subprocess.run(["iptables", "-w", "-t", "filter", "-F", CHAIN_NAME], stderr=subprocess.DEVNULL)
    subprocess.run(["iptables", "-w", "-t", "filter", "-X", CHAIN_NAME], stderr=subprocess.DEVNULL)
    print("\033[32miptables service rule cleanup complete!\033[0m")

def backup_rule():
    # 备份当前环境下iptables规则到指定目录下临时文件,以当前时钟命名,保存路径为当前路径下
    with open(f"{os.path.dirname(os.path.abspath(__file__))}/iptables_bk_{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", "w") as f:  # 以时间指定文件名称
        subprocess.run(["iptables-save"], stdout=f)
    print(f"\033[32miptables service rule backup complete,path is {os.path.dirname(os.path.abspath(__file__))}/iptables_bk_<local_time>\033[0m")

if __name__ == "__main__":
    if len(sys.argv) == 1 or sys.argv[1] == "help":
        # 可用参数说明
        help()
    elif sys.argv[1] == "create":
        # 先备份规则,再清理规则,后创建新规则
        backup_rule()
        delete_rule()
        create_rule()
    elif sys.argv[1] == "delete":
        # 先备份规则,再清理规则
        backup_rule()
        delete_rule()
    elif sys.argv[1] == "backup":
        # 直接备份规则
        backup_rule()
    else:
        # 帮助文档
        help()

3. 执行结果

ip.txt配置参考

Shell ❀ 一键配置Iptables规则脚本 (HW推荐)_网络


以Python代码块为案例展示其执行结果:

Shell ❀ 一键配置Iptables规则脚本 (HW推荐)_IP_02

4. 地址与端口获取方法

4.1 tcpdump抓包分析(推荐使用)

tcpdump -i any -s56 -lnnqt 'inbound and (dst port 2181 or dst port 2888 or dst port 3888)' | cut -d'.' -f1-4 | awk '!a[$NF]++ {print $NF; fflush();}' | tee <file_path>/ip.txt

命令解析

  • tcpdump:-i any 抓取所有接口数据包,-s56 截取报文前56字节内容,-lnnqt 使用数字格式显示IP地址和端口号,inbound 只抓取入站数据包,dst port 目标端口列表
  • cut:切割出IP地址
  • awk:对每个IP地址进行去重操作

4.2 TCP连接分析(仅能识别TCP连接)

ss -nat | grep -E ":2181|2888|3888" | awk '{print $NF}' | grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | awk '!a[$0]++' | tee <file_path>/ip.txt

命令解析

  • ss:查找当前系统中所有TCP连接的状态信息,并同时过滤端口
  • awk:第一个为输出最后一行信息并过滤出IP地址,第二个为对每个IP地址进行去重操作