解放双手!本地一键封禁阿里云攻击IP,攻防演练不再手忙脚乱
还在为云攻防演练中手动封IP熬到秃头?🤯 登录阿里云控制台点来点去,一天封几十上百个攻击IP,人都麻了... 🤦♂️刚搞定一个本地脚本,告别繁琐登录!一键自动封禁攻击IP,省时省力,安全部的小伙伴直呼真香!🔥
·
还在为云攻防演练中手动封IP熬到秃头?🤯 登录阿里云控制台点来点去,一天封几十上百个攻击IP,人都麻了… 🤦♂️
刚搞定一个本地脚本,告别繁琐登录!一键自动封禁攻击IP,省时省力,安全部的小伙伴直呼真香!🔥
(脚本已适配阿里云,开源分享,解放双手时刻到了!)
文章目录
博主个人知识库,欢迎订阅:https://literator_ray.flowus.cn
一、先上代码
#!/usr/bin/env python3
"""
阿里云防火墙IP封禁工具 - 北京地域专版
主要功能:
1. 添加IP到防火墙地址簿进行封禁
2. 从地址簿中移除已封禁的IP
3. 列出地址簿中的IP列表
4. 查看所有地址簿信息
5. 创建新的地址簿
使用说明:
- 必须提供阿里云AccessKey ID和Secret
- 需要指定要操作的地址簿名称
- 32为掩码的单个IP地址可以不带掩码,脚本会自动补全(如192.168.1.1、192.168.1.1/32)
"""
import argparse # 用于解析命令行参数
import sys # 系统功能,如退出程序
import re # 正则表达式,用于验证IP格式
import json # 处理JSON数据格式
import os # 操作系统功能,如读取环境变量
import logging # 日志记录功能
import uuid # 生成唯一ID
# 导入阿里云SDK相关模块
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcloudfw.request.v20171207 import (
DescribeAddressBookRequest, # 查询地址簿信息
ModifyAddressBookRequest # 修改地址簿内容
)
# 配置日志系统 - 记录程序运行信息
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("CloudFWBlockTool")
class CloudFWBlockTool:
def __init__(self, access_key, access_secret, region='cn-beijing'):
"""初始化工具类 - 创建阿里云客户端连接"""
logger.info(f"正在连接到阿里云北京({region})区域...")
# 创建阿里云客户端实例
self.client = AcsClient(access_key, access_secret, region)
self.region = region
def validate_ip_or_cidr(self, ip_input):
"""验证输入的IP格式是否正确 - 必须包含CIDR掩码"""
# 去除首尾空白
ip_input = ip_input.strip()
# 允许不带CIDR的IP地址(自动补全/32)
if '/' not in ip_input:
ip_input += '/32'
logger.info(f"自动补全CIDR后缀: {ip_input}")
# 正则表达式验证IP格式(必须包含/和掩码数字)
ip_pattern = re.compile(r'^(\d{1,3}\.){3}\d{1,3}(/\d{1,2})?$')
if not ip_pattern.match(ip_input):
raise ValueError(f"无效的IP格式: {ip_input} - 必须包含CIDR掩码(如192.168.1.1/32)")
# 分离IP和掩码部分
if '/' in ip_input:
ip_part, cidr = ip_input.split('/')
else:
ip_part, cidr = ip_input, "32"
# 分离IP和掩码部分
if '/' in ip_input:
ip_part, cidr = ip_input.split('/')
else:
ip_part, cidr = ip_input, "32"
# 验证掩码是否在0-32范围内
try:
cidr_int = int(cidr)
if not (0 <= cidr_int <= 32):
raise ValueError(f"无效的CIDR后缀: /{cidr} (必须是0-32)")
except ValueError:
raise ValueError(f"无效的CIDR后缀: /{cidr}")
# 验证IP各部分是否在0-255范围内
ip_parts = ip_part.split('.')
for part in ip_parts:
if not part.isdigit() or not 0 <= int(part) <= 255:
raise ValueError(f"IP地址部分超出范围: {ip_input}")
logger.debug(f"验证通过: {ip_input}")
return ip_input
def get_address_book_info(self, address_book_name):
"""获取指定地址簿的详细信息"""
if not address_book_name:
logger.error("地址簿名称不能为空")
return None
# 创建查询地址簿的请求对象
req = DescribeAddressBookRequest.DescribeAddressBookRequest()
req.add_query_param('PageSize', 100) # 设置每页返回结果数量
try:
logger.info(f"查询所有地址簿,查找: '{address_book_name}'")
# 发送请求并获取响应
response = self.client.do_action_with_exception(req)
response_data = json.loads(response.decode('utf-8'))
logger.debug(f"API返回数据: {json.dumps(response_data, indent=2)}")
# 检查响应是否包含地址簿信息
if 'Acls' not in response_data:
logger.error(f"API响应缺少地址簿信息: {response_data}")
return None
address_books = response_data.get('Acls', [])
matched_book = None
# 在返回的地址簿列表中查找匹配项
for book in address_books:
# 检查多种可能的名称字段(不同API版本可能使用不同字段名)
name_fields = ['Name', 'name', 'groupName', 'GroupName', 'addressBookName']
for field in name_fields:
if field in book and book[field] == address_book_name:
matched_book = book
# 确保有标准化的字段名称
matched_book['Name'] = address_book_name
matched_book['GroupUuid'] = book.get('GroupUuid', book.get('GroupId', ''))
logger.info(f"精确匹配到地址簿: '{address_book_name}'")
return matched_book
# 如果没有精确匹配,尝试大小写不敏感的模糊匹配
for book in address_books:
for field in name_fields:
if field in book and book[field].lower() == address_book_name.lower():
logger.warning(f"通过大小写不敏感匹配到地址簿: '{book[field]}' (请求: '{address_book_name}')")
matched_book = book
matched_book['Name'] = address_book_name
matched_book['GroupUuid'] = book.get('GroupUuid', book.get('GroupId', ''))
return matched_book
# 如果仍然没有找到匹配的地址簿,则创建新地址簿
logger.warning(f"地址簿 '{address_book_name}' 不存在")
return self.create_address_book(address_book_name)
except ClientException as e:
logger.error(f"获取地址簿失败: {e.get_error_msg()}")
return None
def create_address_book(self, address_book_name):
"""创建新的地址簿"""
logger.info(f"创建地址簿: {address_book_name}")
# 创建修改地址簿的请求对象(也用于创建新地址簿)
req = ModifyAddressBookRequest.ModifyAddressBookRequest()
# 设置地址簿参数
req.add_query_param('Name', address_book_name) # 地址簿名称
req.add_query_param('GroupType', 'ip') # 地址簿类型(IP类型)
req.add_query_param('AutoAddTag', 0) # 不自动添加标签
req.add_query_param('Description', "由脚本创建的封禁IP地址簿") # 描述信息
try:
# 发送创建地址簿请求
response = self.client.do_action_with_exception(req)
response_data = json.loads(response.decode('utf-8'))
# 构造返回的地址簿信息
book_info = {
'GroupUuid': response_data.get('GroupUuid', ''), # 地址簿唯一ID
'Name': address_book_name, # 地址簿名称
'AddressList': [] # 初始为空列表
}
logger.info(f"地址簿创建成功, UUID: {book_info['GroupUuid']}")
return book_info
except ClientException as e:
logger.error(f"创建地址簿失败: {e.get_error_msg()}")
return None
def get_all_address_books(self):
"""获取所有地址簿的名称和类型信息"""
req = DescribeAddressBookRequest.DescribeAddressBookRequest()
req.add_query_param('PageSize', 100) # 设置每页返回100条记录
try:
logger.info("获取所有地址簿列表...")
response = self.client.do_action_with_exception(req)
response_data = json.loads(response.decode('utf-8'))
logger.debug(f"API返回数据: {json.dumps(response_data, indent=2)}")
# 检查响应是否包含地址簿信息
if 'Acls' not in response_data:
logger.error(f"API响应缺少地址簿信息: {response_data}")
return []
address_books = response_data.get('Acls', [])
logger.info(f"找到 {len(address_books)} 个地址簿")
books_info = []
# 提取每个地址簿的关键信息
for book in address_books:
# 尝试多种可能的名称字段
name_fields = ['Name', 'name', 'groupName', 'GroupName', 'addressBookName']
book_name = "未知名称"
# 查找地址簿名称
for field in name_fields:
if field in book:
book_name = book[field]
break
# 计算IP数量(处理不同格式的响应)
address_list = book.get('AddressList', [])
if isinstance(address_list, str):
# 如果是字符串,按逗号分隔并统计非空IP数量
ip_count = len([ip for ip in address_list.split(',') if ip]) if address_list else 0
elif isinstance(address_list, list):
# 如果是列表,直接统计长度
ip_count = len(address_list)
else:
ip_count = 0
# 收集地址簿信息
books_info.append({
'Name': book_name, # 地址簿名称
'Type': book.get('GroupType', '未知类型'), # 地址簿类型
'Description': book.get('Description', '无描述'), # 描述信息
'IPCount': ip_count # IP数量
})
return books_info
except ClientException as e:
logger.error(f"获取地址簿列表失败: {e.get_error_msg()}")
return []
def get_address_list(self, book_info):
"""统一处理获取地址列表的逻辑 - 处理不同格式的响应"""
if book_info is None:
return []
address_list = book_info.get('AddressList', [])
# 处理字符串格式的地址列表(逗号分隔)
if isinstance(address_list, str):
return [ip for ip in address_list.split(',') if ip]
# 处理列表格式的地址列表
if isinstance(address_list, list):
return address_list
# 处理未知格式
logger.warning(f"无法识别的地址列表格式: {type(address_list)}")
return []
def add_ips_to_book(self, ips, address_book_name):
"""添加IP到地址簿 - 核心功能"""
if not address_book_name:
logger.error("地址簿名称不能为空")
return False
if not ips:
logger.warning("没有有效的IP需要添加")
return False
logger.info(f"准备添加 {len(ips)} 个IP到地址簿 '{address_book_name}'")
# 获取地址簿信息
book_info = self.get_address_book_info(address_book_name)
if book_info is None:
logger.error("无法获取地址簿信息,添加操作终止")
return False
# 获取地址簿唯一ID
book_uuid = book_info.get('GroupUuid', '')
if not book_uuid:
logger.error("地址簿缺少UUID,无法添加IP")
return False
# 获取当前地址簿中的IP列表
current_ips = self.get_address_list(book_info)
# 过滤掉已存在的IP(避免重复添加)
new_ips = [ip for ip in ips if ip not in current_ips]
if not new_ips:
logger.info("所有IP已存在于地址簿中")
return True
# 合并新旧IP列表
combined_ips = current_ips + new_ips
combined_count = len(combined_ips)
# 检查地址簿2000个IP的限制
if combined_count > 2000:
logger.warning(f"地址簿将超过限制 ({combined_count}/2000), 无法添加 {len(new_ips)} 个新IP")
# 询问用户是否继续
if input("是否继续? (y/n): ").lower() != 'y':
logger.info("操作已取消")
return False
book_name = book_info.get('Name', address_book_name)
logger.info(f"开始添加 {len(new_ips)} 个IP到地址簿 '{book_name}'...")
try:
# 创建修改地址簿的请求
req = ModifyAddressBookRequest.ModifyAddressBookRequest()
# 设置必要参数
req.set_GroupUuid(book_uuid) # 地址簿唯一ID
req.set_GroupName(book_name) # 地址簿名称(必需)
req.set_AddressList(','.join(combined_ips)) # 合并后的IP列表(逗号分隔)
req.add_query_param('ModifyMode', 'Cover') # 使用覆盖模式更新
# 设置其他可选参数(根据API要求)
req.add_query_param('SourceIp', '') # 访问者源IP(留空)
req.add_query_param('Lang', '') # 语言(留空)
req.add_query_param('Description', book_info.get('Description', '')) # 保留原有描述
req.add_query_param('AutoAddTagEcs', '0') # 不自动添加标签
# 设置请求ID用于跟踪
req.set_accept_format('json') # 设置响应格式为JSON
request_id = str(uuid.uuid4()) # 生成唯一请求ID
req.add_query_param('RequestId', request_id) # 添加请求ID参数
logger.debug(f"添加IP请求参数: GroupUuid={book_uuid}, GroupName={book_name}, AddressList={len(combined_ips)}个IP, ModifyMode=Cover, RequestId={request_id}")
# 发送请求
response = self.client.do_action_with_exception(req)
response_data = json.loads(response.decode('utf-8'))
# 检查操作是否成功(根据返回的RequestId判断)
if 'RequestId' in response_data:
logger.info(f"成功添加 {len(new_ips)} 个IP到地址簿")
return True
else:
logger.error(f"添加操作失败: {response_data.get('Message', '未知错误')}")
return False
except ClientException as e:
error_code = e.get_error_code()
error_msg = e.get_error_msg()
logger.error(f"添加失败: {error_msg} (错误码: {error_code})")
return False
except Exception as e:
logger.error(f"添加过程中发生意外错误: {str(e)}")
return False
def remove_ips_from_book(self, ips_to_remove, address_book_name):
"""从地址簿中移除IP"""
if not address_book_name:
logger.error("地址簿名称不能为空")
return False
if not ips_to_remove:
logger.warning("没有有效的IP需要移除")
return False
logger.info(f"准备移除 {len(ips_to_remove)} 个IP")
# 获取地址簿信息
book_info = self.get_address_book_info(address_book_name)
if book_info is None:
logger.error("无法获取地址簿信息,移除操作终止")
return False
# 获取地址簿唯一ID
book_uuid = book_info.get('GroupUuid', '')
if not book_uuid:
logger.error("地址簿缺少UUID,无法移除IP")
return False
# 获取当前地址簿中的IP列表
current_ips = self.get_address_list(book_info)
# 创建新的IP列表(排除要移除的IP)
new_ips = [ip for ip in current_ips if ip not in ips_to_remove]
# 计算实际移除的IP数量
removed_count = len(current_ips) - len(new_ips)
# 如果没有匹配的IP
if removed_count == 0:
logger.warning("未找到指定的IP地址")
return False
book_name = book_info.get('Name', address_book_name)
logger.info(f"开始从地址簿 '{book_name}' 中移除 {removed_count} 个IP...")
try:
# 创建修改地址簿的请求
req = ModifyAddressBookRequest.ModifyAddressBookRequest()
# 设置必要参数
req.set_GroupUuid(book_uuid) # 地址簿唯一ID
req.set_GroupName(book_name) # 地址簿名称(必需)
req.set_AddressList(','.join(new_ips)) # 移除后的IP列表
req.add_query_param('ModifyMode', 'Cover') # 使用覆盖模式更新
# 设置其他可选参数
req.add_query_param('SourceIp', '') # 访问者源IP(留空)
req.add_query_param('Lang', '') # 语言(留空)
req.add_query_param('Description', book_info.get('Description', '')) # 保留原有描述
req.add_query_param('AutoAddTagEcs', '0') # 不自动添加标签
# 设置请求ID用于跟踪
req.set_accept_format('json') # 设置响应格式为JSON
request_id = str(uuid.uuid4()) # 生成唯一请求ID
req.add_query_param('RequestId', request_id) # 添加请求ID参数
logger.debug(f"移除IP请求参数: GroupUuid={book_uuid}, GroupName={book_name}, AddressList={len(new_ips)}个IP, ModifyMode=Cover, RequestId={request_id}")
# 发送请求
response = self.client.do_action_with_exception(req)
response_data = json.loads(response.decode('utf-8'))
# 检查操作是否成功
if 'RequestId' in response_data:
logger.info(f"成功移除 {removed_count} 个IP")
return True
else:
logger.error(f"移除操作失败: {response_data.get('Message', '未知错误')}")
return False
except ClientException as e:
logger.error(f"移除失败: {e.get_error_msg()}")
return False
def list_ips_in_book(self, address_book_name):
"""列出地址簿中的所有IP"""
if not address_book_name:
logger.error("地址簿名称不能为空")
return [], None, 0
# 获取地址簿信息
book_info = self.get_address_book_info(address_book_name)
if book_info is None:
logger.error("无法获取地址簿信息")
return [], None, 0
# 获取IP列表
ips = self.get_address_list(book_info)
book_name = book_info.get('Name', address_book_name)
ip_count = len(ips)
return ips, book_name, ip_count
def main():
"""主函数:处理命令行参数和执行对应操作"""
# 设置日志级别
logging.getLogger().setLevel(logging.INFO)
# 创建命令行参数解析器
parser = argparse.ArgumentParser(
description='阿里云防火墙IP封禁工具 - 北京地域专用\n支持列出所有地址簿名称',
formatter_class=argparse.RawTextHelpFormatter
)
# 尝试从环境变量获取AccessKey和Secret
ak_from_env = os.environ.get('ALIYUN_AK')
sk_from_env = os.environ.get('ALIYUN_SK')
# 认证参数组(必须)
auth_group = parser.add_argument_group('认证参数 (必须)')
auth_group.add_argument('--ak', help='阿里云AccessKey ID', default=ak_from_env)
auth_group.add_argument('--sk', help='阿里云AccessKey Secret', default=sk_from_env)
auth_group.add_argument('--region', default='cn-beijing', help='地域ID (默认: cn-beijing)')
# 操作模式组(互斥,只能选择一个)
operation_group = parser.add_argument_group('操作模式 (选择一项)').add_mutually_exclusive_group()
operation_group.add_argument('-a', '--add', nargs='+', metavar='IP',
help='添加要封禁的IP/CIDR 或 IP,掩码会会自动补全,仅针对32掩码的IP')
operation_group.add_argument('-f', '--file', metavar='FILE',
help='从文件读取IP列表')
operation_group.add_argument('-r', '--remove', nargs='+', metavar='IP',
help='移除已封禁的IP')
operation_group.add_argument('-l', '--list', action='store_true',
help='列出指定地址簿中的IP')
operation_group.add_argument('--list-books', action='store_true',
help='列出所有地址簿的名称和类型')
# 其他参数
parser.add_argument('--book', required=False,
help='必须指定地址簿名称(除--list-books操作外)')
parser.add_argument('--debug', action='store_true',
help='启用调试模式(显示详细日志)')
# 解析命令行参数
args = parser.parse_args()
# 检查是否有任何操作被指定
operations = [args.add, args.file, args.remove, args.list, args.list_books]
no_operation = not any(operations)
# 如果没有指定任何操作,显示帮助信息并退出
if no_operation:
parser.print_help()
sys.exit(0)
# 如果启用了调试模式,设置更详细的日志级别
if args.debug:
logging.getLogger().setLevel(logging.DEBUG)
logger.info("启用调试模式")
# 检查AccessKey和Secret是否提供
if not args.ak or not args.sk:
parser.error("必须提供AccessKey (使用--ak/--sk或设置ALIYUN_AK/ALIYUN_SK环境变量)")
# 检查除 --list-books 外的操作是否需要 --book 参数
if not args.list_books and not args.book:
parser.error("对于此操作必须指定地址簿 (使用 --book)")
try:
# 创建工具实例
tool = CloudFWBlockTool(args.ak, args.sk, args.region)
# 如果指定了列出所有地址簿,优先处理
if args.list_books:
books_info = tool.get_all_address_books()
if not books_info:
print("没有找到任何地址簿")
sys.exit(0)
# 格式化输出所有地址簿信息
print("\n阿里云防火墙地址簿列表:")
print("=" * 100)
print(f"{'序号':<5} | {'地址簿名称':<30} | {'类型':<10} | {'IP数量':<8} | {'描述'}")
print("-" * 100)
for idx, book in enumerate(books_info, 1):
description = book['Description']
# 如果描述太长则截断
if len(description) > 50:
description = description[:47] + "..."
# 输出每行信息
print(f"{idx:<5} | {book['Name'][:30]:<30} | {book['Type']:<10} | {book['IPCount']:<8} | {description}")
print("=" * 100)
print(f"总计: {len(books_info)} 个地址簿")
sys.exit(0)
# 处理添加IP操作(从命令行参数)
if args.add:
ip_list = []
for ip in args.add:
try:
# 验证并格式化IP
validated_ip = tool.validate_ip_or_cidr(ip)
ip_list.append(validated_ip)
except ValueError as e:
logger.error(e)
if ip_list:
# 调用添加IP方法
if not tool.add_ips_to_book(ip_list, args.book):
sys.exit(1)
else:
logger.error("未提供有效的IP地址")
sys.exit(1)
# 处理从文件添加IP操作
elif args.file:
try:
ip_list = []
# 打开文件并读取每一行
with open(args.file, 'r') as f:
for line in f:
line = line.strip() # 移除首尾空白
# 忽略空行和注释行
if line and not line.startswith('#'):
try:
# 验证并格式化IP
validated_ip = tool.validate_ip_or_cidr(line)
ip_list.append(validated_ip)
except ValueError as e:
logger.warning(f"跳过无效IP: {line} ({e})")
if ip_list:
logger.info(f"从文件 {args.file} 读取到 {len(ip_list)} 个有效IP")
# 调用添加IP方法
if not tool.add_ips_to_book(ip_list, args.book):
sys.exit(1)
else:
logger.error("文件中未找到有效IP")
sys.exit(1)
except FileNotFoundError:
logger.error(f"文件不存在: {args.file}")
sys.exit(1)
# 处理移除IP操作
elif args.remove:
ip_list = []
for ip in args.remove:
try:
# 验证并格式化IP
validated_ip = tool.validate_ip_or_cidr(ip)
ip_list.append(validated_ip)
except ValueError as e:
logger.error(e)
if ip_list:
# 调用移除IP方法
if not tool.remove_ips_from_book(ip_list, args.book):
sys.exit(1)
else:
logger.error("未提供有效的IP地址")
sys.exit(1)
# 处理列出地址簿中IP的操作
elif args.list:
# 获取IP列表
ips, book_name, ip_count = tool.list_ips_in_book(args.book)
if ips is None or book_name is None:
sys.exit(1)
# 输出IP列表
if ips:
print(f"\n地址簿 '{book_name}' 中的IP列表 ({ip_count}个):")
print("=" * 60)
for i, ip in enumerate(ips, 1):
print(f"{i:4d}. {ip}")
print("=" * 60)
else:
print("地址簿为空")
# 捕获所有异常并记录
except Exception as e:
logger.exception("程序发生严重错误:")
sys.exit(1)
# 程序入口
if __name__ == "__main__":
main()
二、帮助文档
PS D:\auto_scripts> python auto_stop7.py --ak 你自己的access_key --sk 你自己的access_secret --help
usage: auto_stop7.py [-h] [--ak AK] [--sk SK] [--region REGION] [-a IP [IP ...] | -f FILE | -r IP [IP ...] | -l | --list-books] [--book BOOK] [--debug]
阿里云防火墙IP封禁工具 - 北京地域专用
支持列出所有地址簿名称
options:
-h, --help show this help message and exit
--book BOOK 必须指定地址簿名称(除--list-books操作外)
--debug 启用调试模式(显示详细日志)
认证参数 (必须):
--ak AK 阿里云AccessKey ID
--sk SK 阿里云AccessKey Secret
--region REGION 地域ID (默认: cn-beijing)
操作模式 (选择一项):
-a, --add IP [IP ...]
添加要封禁的IP/CIDR (必须包含掩码,如192.168.1.1/32)
-f, --file FILE 从文件读取IP列表 (每行一个IP,必须包含掩码)
-r, --remove IP [IP ...]
移除已封禁的IP
-l, --list 列出指定地址簿中的IP
--list-books 列出所有地址簿的名称和类型
三、指令解释
默认地域是北京,如果是其他地域,需要添加地域参数,如 --region cn-hangzhou
3.1 查看地址簿列表
python auto_stop6.py --ak 你自己的access_key --sk 你自己的access_secret --list-books
会显示全部地址簿名称,类型、ip数量、描述
3.2 查看指定地址簿详细列表
python auto_stop6.py --ak 你自己的access_key --sk 你自己的access_secret --book "脚本自动封禁ip地址簿" --list
3.3 添加需要封禁的IP
3.3.1 示例
地址簿名称:脚本自动封禁ip地址簿
当前地址簿里只有1个IP
1、现在需要把测试IP添加到地址簿里:192.168.99.3/24 2.2.2.3/32 2.2.2.4/32
python auto_stop6.py --ak 你自己的access_key --sk 你自己的access_secret--book "脚本自动封禁ip地址簿" --add 192.168.99.3/24 2.2.2.3/32 2.2.2.4/32
要在废话几句:单个IP也需要加32为子网掩码,以确保地址地址簿添加无误,因为阿里云是如此规定的,但是脚本自带32为掩码补全功能,所以也可以不写【仅针对32为掩码的IP!!!】
2、指定要添加的地址簿,执行新增指令
python auto_stop6.py --ak 你自己的access_key --sk 你自己的access_secret --book "脚本自动封禁ip地址簿" --add 192.168.99.0/24 2.2.2.3/32 2.2.2.4/32
3、添加成功,查看云防火墙地址簿,新增无误
最后要提醒大家,也是最重要的,如果要行地址簿生效,一定要在互联网边界创建策略,这里就过多赘述了
欢迎所有人提出你的问题,并指正代码中的不足
最后我想说:请不要以此视为定论,这只是我的个人经验
更多推荐
所有评论(0)