如何使用Python和iptables从NetworkManager配置文件中提取并封禁VPN IP地址
如何使用Python和iptables从NetworkManager配置文件中提取并封禁VPN IP地址
我来帮你一步步搞定这个需求,咱们从筛选VPN配置文件开始,再提取有效IP,最后用iptables完成封禁,完全贴合你要求的Python实现方案。
一、如何过滤VPN配置文件?
NetworkManager的.nmconnection文件里,VPN连接会在[connection]段明确标注type=vpn——这就是咱们区分VPN配置和其他网络配置(比如WiFi、以太网)的核心依据。咱们可以遍历目标目录下的所有.nmconnection文件,逐个检查是否存在这个标记,以此筛选出真正的VPN配置文件。
二、完整实现脚本
下面是一个满足所有需求的Python脚本,每一步都加了详细注释,方便你理解:
import os import re import subprocess from ipaddress import ip_address # 配置参数,可根据实际情况调整 CONFIG_DIR = "/etc/NetworkManager/system-connections/" FILE_EXT = ".nmconnection" def is_vpn_config(file_path): """判断当前文件是否为VPN配置文件""" try: with open(file_path, 'r') as f: for line in f: line = line.strip() # 找到[connection]段后,检查后续的type字段 if line == "[connection]": for next_line in f: next_line = next_line.strip() if next_line.startswith("type="): return next_line.split("=")[1] == "vpn" break except PermissionError: print(f"权限不足,无法读取文件: {file_path}") return False def extract_valid_ips(file_path): """从VPN配置文件中提取所有合法的IPv4地址""" ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b') valid_ips = set() # 用集合自动去重,避免重复添加规则 try: with open(file_path, 'r') as f: for line in f: line = line.strip() # 重点处理[vpn]段下的remote行,这里存放VPN服务器IP if line.startswith("remote="): # 拆分逗号分隔的多个remote条目 remote_entries = line.split("=")[1].split(",") for entry in remote_entries: entry = entry.strip() # 提取IP部分(去掉后面的端口号) ip_str = entry.split(":")[0] if ":" in entry else entry # 验证IP是否合法(排除999.999.999.999这类无效值) try: ip_address(ip_str) valid_ips.add(ip_str) except ValueError: print(f"无效IP地址,跳过: {ip_str}") except Exception as e: print(f"处理文件{file_path}时出错: {str(e)}") return valid_ips def block_ip_with_iptables(ip): """使用iptables封禁单个IP""" # 分别添加INPUT和OUTPUT方向的封禁规则 commands = [ ["iptables", "-A", "INPUT", "-s", ip, "-j", "DROP"], ["iptables", "-A", "OUTPUT", "-d", ip, "-j", "DROP"] ] for cmd in commands: try: subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print(f"已成功封禁IP: {ip}") except subprocess.CalledProcessError as e: print(f"封禁IP{ip}时出错: {e.stderr.decode('utf-8')}") def main(): # 遍历目标目录下的所有.nmconnection文件 for filename in os.listdir(CONFIG_DIR): if filename.endswith(FILE_EXT): file_path = os.path.join(CONFIG_DIR, filename) # 只处理验证通过的VPN配置文件 if is_vpn_config(file_path): print(f"正在处理VPN配置文件: {filename}") ips = extract_valid_ips(file_path) for ip in ips: block_ip_with_iptables(ip) if __name__ == "__main__": # 检查是否以root权限运行(iptables需要管理员权限) if os.geteuid() != 0: print("错误:需要以root权限运行此脚本(使用sudo执行)") exit(1) main()
三、关键功能说明
- 精准筛选VPN文件:
is_vpn_config函数会定位到[connection]段,确认type字段是否为vpn,确保不会误处理其他网络配置。 - 提取有效IP:
- 先用正则匹配IP格式,再通过
ipaddress.ip_address验证IP合法性,避免无效值 - 专门处理
remote=行,拆分多个IP并去除端口号,提取纯IP地址 - 用集合存储IP,自动去重,避免重复添加相同的封禁规则
- 先用正则匹配IP格式,再通过
- 安全应用iptables规则:每个IP单独执行封禁命令,确保规则生效;脚本开头会检查root权限,避免因权限不足导致失败。
四、使用注意事项
- 运行脚本必须加
sudo,否则无法读取NetworkManager配置文件和修改iptables规则 - 如果需要让封禁规则重启后依然生效,可以在脚本末尾添加
subprocess.run(["iptables-save", ">", "/etc/iptables/rules.v4"], shell=True)(不同发行版路径可能不同,按需调整) - 测试阶段可以把
-A(添加规则)换成-L(查看规则),确认IP提取正确后再正式添加封禁规则
备注:内容来源于stack exchange,提问作者user21379959
相关产品推荐
相关产品推荐

