暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux配置白名单限制访问_ipset+iptables

原创 楚枫默寒 2025-09-22
56

 常规意义上的 MAC 地址白名单依赖于二层环境运作,故基本上仅限于同一个局域网(同网段/VLAN)内有效;若要实现跨网段的安全管控,则应采用更完善的网络准入控制系统或其他更高层级的身份鉴权手段


2025/10/27  添加 IP段 控制 (可使用ipset添加IP段,如 192.168.1.0/24 )


 一、IP清单文件 whitelist.txt

[root@centos610:/opt]# cat whitelist.txt 
00:50:56:ad:72:2e0
00:50:56:b6:c7:07
127.0.0.3
192.168.249.2
127.0.0.300

二、ipset

ipset 是一个在 Linux 系统中用于创建和管理 IP 地址集合的工具,它可以用来快速匹配 IP 地址,并且可以与防火墙规则(如 iptables 或 nftables)结合使用,以实现高效的网络流量过滤。

使用 ipset 创建一个新的集合,可以指定集合的类型。例如,使用 hash:ip或hash:net 类型来存储 IP 地址。

特点 hash:ip hash:ip,port hash:net hash:net,port hash:mac hash:iface
存储内容 单个 IP 地址 IP 网络地址(CIDR)
使用场景 精确匹配单个 IP 匹配整个 IP 网络段
效率 对于单个 IP 匹配效率更高 对于网络段匹配效率更高
灵活度 相对较低 相对较高

创建hash:ip的ip集合

# 创建一个存储单个 IP 地址的集合
ipset create ip_whitelist hash:ip

# 添加一个ip地址到 whitelist ip地址集合 
ipset add ip_whitelist <IP地址>

# 创建hash:ip,port的ip端口集合
ipset create aa hash:ip,port

# 添加一个ip:port到 地址集合
ipset add aa 1.1.1.1,22

# 创建一个存储 IP 网络地址的集合
ipset create ip_whitelist hash:net

# 查看已创建的ipset
ipset list

# 删除ipset集合
ipset destroy blacklist

ip规则管理

# 添加一个 IP 网络地址
ipset add ip_whitelist 192.168.11.2

# 添加一个ip范围
ipset add ip_whitelist 192.168.10.21-192.168.10.31

# 添加一个网段--必须是hash:net
ipset add ip_whitelist 192.168.1.0/24

#从ipset集合中删除ip
ipset del blacklist 10.60.10.xx

#从ipset集合中清空ip
ipset flush blacklist

# 保存ipset规则
ipset save a -f /etc/sysconfig/ipset

二、iptable

查看所有规则使用命令:iptables -L,如下图,重点看chain input

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   

#添加一个IP段
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

#添加一个固定IP
iptables -I INPUT -s 192.168.1.1 -j ACCEPT

#添加一个IP并指定端口
iptables -I INPUT -s 192.168.1.1 -ptcp --dport 9200 -j ACCEPT

#拒绝所有IP的端口
iptables -A INPUT -p tcp -m tcp --dport 9200 -j DROP

#创建防火墙规则,设置状态,只有已连接的才可以通过,如果是NEW状态的,就直接拦截
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#创建防火墙规则,现在规则外的其他都直接Drop
iptables -A INPUT -j DROP

#保存规则
#centos5、6
service iptables save       #默认 /etc/sysconfig/iptables
#centos7,8,9  Anolis  Kylin
iptables-save > /etc/sysconfig/iptables

三、iptable_set.sh

iptable_set.sh 读取 whitelist.txt 文件,并配置白名单。

[root@centos79:/opt]# cat whitelist.txt 
00:50:56:ad:72:2e0
00:50:56:b6:c7:07
127.0.0.3
192.168.249.2
127.0.0.300

[root@centos79:/opt]# ./iptable_set.sh 
IP/MAC: 00:50:56:ad:72:2e0 地址错误! 
IP/MAC: 127.0.0.300 地址错误! 

[root@centos79:/opt]# ipset list
Name: whitelist
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 1000000
Size in memory: 216
References: 2
Number of entries: 2
Members:
192.168.249.2
127.0.0.3

[root@centos79:/opt]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  gateway              anywhere            
ACCEPT     all  --  127.0.0.3            anywhere            
ACCEPT     all  --  anywhere             anywhere             MAC 00:50:56:B6:C7:07
ACCEPT     all  --  anywhere             anywhere             match-set whitelist src
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    
     
[root@centos79:/opt]# 

四、完整脚本

        72~86行代码使用方式

                A:使用ipset 管理IP,iptables管理MAC (Cenos5 没有 ipset )

    for target_ip in ${LINELIST};do
        #IP4合法性检查
        if [[ ${target_ip} =~ ${ip_check} ]];then
            #ipset配置
            if [[ $(which ipset 2>/dev/null) ]];then 
                ipset add whitelist ${target_ip} -exist
            else
                #iptables配置
                iptables -I INPUT -s ${target_ip} -j ACCEPT
            fi
        elif [[ ${target_ip} =~ ${mac_check} ]]; then
            iptables -I INPUT -m mac --mac-source ${target_ip} -j ACCEPT
        else
            echo -e "${AC}IP/MAC:${RC} ${target_ip} 地址错误! ${EC}" >> ${soft_errlog}
        fi 
    done

                B:使用ipset 管理IP,iptables管理 IP+MAC 

    for target_ip in ${LINELIST};do
        #IP4合法性检查
        if [[ ${target_ip} =~ ${ip_check} ]];then
            #ipset配置
            if [[ $(which ipset 2>/dev/null) ]];then 
                ipset add whitelist ${target_ip} -exist
            fi
            #iptables配置
            iptables -I INPUT -s ${target_ip} -j ACCEPT
        elif [[ ${target_ip} =~ ${mac_check} ]]; then
            iptables -I INPUT -m mac --mac-source ${target_ip} -j ACCEPT
        else
            echo -e "${AC}IP/MAC:${RC} ${target_ip} 地址错误! ${EC}" >> ${soft_errlog}
        fi 
    done

完整脚本:

#!/bin/bash
#=====================================================#
# File    :  iptable_set.sh(ipset+iptables)
# Ctime   :  2022/08/04
# Mtime   :  2025/10/29
# Version :  4.0.0
# author  :  楚枫默寒
# Copyright (C) 2022-2099
# explain :  ipset配置IP清单,iptables配置MAC地址
#=====================================================#

# 检查是否以root身份运行
if [[ $EUID -ne 0 ]]; then
    echo "此脚本必须以root权限运行!"
    exit 1
fi

color_setting(){
    RC='\033[31;1m'        #红色 error
    GC='\033[32;1m'        #绿色 success
    YC='\033[33;1m'        #黄色 warning
    BC='\033[34;1m'        #蓝色 output
    DC='\033[35;1m'        #粉色 detail
    AC='\033[36;1m'        #天蓝 info
    EC='\033[0m'           #黑白 end
} 

get_os_info(){
    if [[ -e /etc/os-release ]];then
        Verfile='/etc/os-release'
    elif [[ -e /etc/system-release ]];then
        Verfile='/etc/system-release'
    elif [[ -e /etc/redhat-release ]];then
        Verfile='/etc/redhat-release'
    fi 
    os_version=$(cat ${Verfile}|egrep -o '[0-9]{1,3}'|head -n 1)
}

soft_conf(){
    current=$(date +%Y%m%d%H%M%S)
    soft_path="/opt"
    soft_file="${soft_path}/whitelist.txt"
    soft_errlog="${soft_path}/ipset_err_${current}.log"
    #安装iptables,系统默认已安装
    if [[ ! $(which iptables 2>/dev/null) ]];then
        yum install iptables -y
    fi
    #MAC判断表达式
    mac_check="^([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}$"
}

#IP4判断表达式
is_valid_ip() {
    local ip=$1
    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        IFS='.' read -ra ADDR <<< "$ip"
        for i in "${ADDR[@]}"; do
            if [[ $i -gt 255 ]] || [[ $i -lt 0 ]]; then
                return 1
            fi
        done
        return 0
    else
        return 1
    fi
}

whitelist_set(){
    #清单去空行、注释、重复
    LINELIST=$(sed -e "/#.*.$/d" ${soft_file}|sort -u)
    #设置默认规则
    iptables -P INPUT ACCEPT
    #清空现有所有规则
    iptables -F 
    iptables -t raw -F
    if [[ $(which ipset 2>/dev/null) ]];then 
        #ipset 删除现有白名单
        ipset destroy whitelist
        > /etc/sysconfig/ipset
        #ipset 创建白名单
        ipset create whitelist hash:ip maxelem 1000000
    else 
        echo -e "${RC}未安装 ipset ,将采用 iptables 配置 IP+MAC 方式进行.${EC}" #>> ${soft_errlog}
    fi
    #循环提取IP清单
    for target_ip in ${LINELIST};do
        #IP4合法性检查
        if is_valid_ip "${target_ip}" ; then
            #ipset配置
            if [[ $(which ipset 2>/dev/null) ]];then 
                ipset add whitelist ${target_ip} -exist
            else
                #iptables配置
                iptables -A INPUT -s ${target_ip} -j ACCEPT
            fi
        #IP段检查
        elif [[ ${target_ip} =~ "/" ]]; then
                IP_segment=$(echo ${target_ip} | cut -d'/' -f1)
                IP_segment_gateway=$(echo ${target_ip} | cut -d'/' -f2)
                if is_valid_ip "${IP_segment}" && [[ ${IP_segment_gateway} =~ ^[0-9]+$ ]] && ( (( ${IP_segment_gateway} >= 0 )) || (( ${IP_segment_gateway} <= 32 )) ); then
                #if is_valid_ip "${IP_segment}" && [[ ${IP_segment_gateway} =~ ^[0-9]+$ ]] && [[ ${IP_segment_gateway} -gt 0 || ${IP_segment_gateway} -lt 32 ]]; then
                    if [[ $(which ipset 2>/dev/null) ]];then 
                        ipset add whitelist ${target_ip} -exist
                    fi
                else
                    echo -e "${AC}IP段:${RC} ${target_ip} ${AC}地址错误,已注释处理! ${EC}" >> ${soft_errlog}
                fi
                
        #mac合法性检查
        elif [[ ${target_ip} =~ ${mac_check} ]]; then
            iptables -A INPUT -m mac --mac-source ${target_ip} -j ACCEPT
        else
            echo -e "${AC}IP/MAC:${RC} ${target_ip} 地址错误,已注释处理! ${EC}" >> ${soft_errlog}
            sed -i "s@${target_ip}@#${target_ip}@g" ${soft_file}
        fi 
    done
    if [[ $(which ipset 2>/dev/null) ]];then 
        #创建防火墙白名单规则,01、白名单内的直接通过
        iptables -A INPUT -m set --match-set whitelist src -p all -j ACCEPT
        #配置防火墙白名单规则,02、白名单里面不做状态追踪
        iptables -t raw -A PREROUTING -m set --match-set whitelist src -p all -j NOTRACK
    fi
    #创建防火墙规则,03、设置状态只有已连接的才可以通过,如果是NEW状态的,就直接拦截
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    #创建防火墙规则,04其他的都直接Drop
    iptables -A INPUT -j DROP
    
    #保存配置
    case ${os_version} in
        5|6)
            chkconfig iptables on
            if [[ $(which ipset 2>/dev/null) ]];then 
                chkconfig ipset on
                service ipset save >/dev/null                                           #/etc/sysconfig/ipset
                chkconfig --list|egrep "iptables|ipset"
            else
                chkconfig --list|egrep "iptables"
            fi
            cp /etc/sysconfig/iptables /etc/sysconfig/iptables_${current}
            service iptables save >/dev/null                                            #/etc/sysconfig/iptables
            service iptables restart >/dev/null;;
        7|8|9|10)
            if [[ $(which ipset 2>/dev/null) ]];then 
                ipset save > /etc/sysconfig/ipset                                       #/etc/sysconfig/ipset
            fi
            cp /etc/sysconfig/iptables /etc/sysconfig/iptables_${current}
            iptables-save > /etc/sysconfig/iptables;;                                   #/etc/sysconfig/iptables
    esac
}

auto_start(){
    #添加开机启动
    if [[ ! $(grep -R "iptable_set.sh" /etc/rc.d/rc.local|grep -v "#") ]];then
        echo "sh +x ${soft_path}/iptable_set.sh 2>/dev/null" >>/etc/rc.d/rc.local
    fi 
}

main(){
    color_setting
    get_os_info
    soft_conf
    if [ ! -f ${soft_file} ];then
        echo -e ${RC}"没有检测到白名单文件"${EC}
        exit
    else
        whitelist_set
    fi
    auto_start
    rm -f ${soft_path}/{dba.txt}
    find ${soft_path} -type f -name 'whitelist_20*' -mtime +30 |xargs rm -f;
    if [[ -s ${soft_errlog} ]];then
        cat ${soft_errlog}
    fi
}

main "$@" 



  

最后修改时间:2025-10-29 15:44:59
文章转载自楚枫默寒,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论