bugfix
This commit is contained in:
parent
cf1854f718
commit
c23c5f1979
@ -27,8 +27,10 @@ REDSOCKS_PORT="{{ redsocks_port }}" # redsocks2 在本机监听的端口
|
|||||||
|
|
||||||
# DNSMASQ 配置
|
# DNSMASQ 配置
|
||||||
DNSMASQ_LISTEN_IP="${GATEWAY_LAN_IP}" # dnsmasq 监听的IP
|
DNSMASQ_LISTEN_IP="${GATEWAY_LAN_IP}" # dnsmasq 监听的IP
|
||||||
DOMESTIC_DNS="{{ domestic_dns }}" # 国内DNS服务器
|
DOMESTIC_DNS1="{{ domestic_dns1 }}" # 国内DNS服务器
|
||||||
FOREIGN_DNS="{{ foreign_dns }}" # 国外DNS服务器 (通过SSH SOCKS5代理访问)
|
DOMESTIC_DNS2="{{ domestic_dns2 }}" # 国内DNS服务器
|
||||||
|
FOREIGN_DNS1="{{ foreign_dns1 }}" # 国外DNS服务器 (通过SSH SOCKS5代理访问)
|
||||||
|
FOREIGN_DNS2="{{ foreign_dns2 }}" # 国外DNS服务器 (通过SSH SOCKS5代理访问)
|
||||||
|
|
||||||
# GFWLIST2NEW 工具仓库和安装路径
|
# GFWLIST2NEW 工具仓库和安装路径
|
||||||
GFWLIST2NEW_REPO="{{ gfwlist2new_repo }}"
|
GFWLIST2NEW_REPO="{{ gfwlist2new_repo }}"
|
||||||
@ -240,7 +242,8 @@ no-resolv
|
|||||||
no-poll
|
no-poll
|
||||||
|
|
||||||
# 国内域名直连公共DNS
|
# 国内域名直连公共DNS
|
||||||
server={{ domestic_dns }}
|
server={{ domestic_dns1 }}
|
||||||
|
server={{ domestic_dns2 }}
|
||||||
|
|
||||||
# 国外域名通过 gfwlist2new 生成的配置文件转发到代理
|
# 国外域名通过 gfwlist2new 生成的配置文件转发到代理
|
||||||
# dnsmasq will read additional configuration files from /etc/dnsmasq.d
|
# dnsmasq will read additional configuration files from /etc/dnsmasq.d
|
||||||
102
scripts/gfw_rules_generator.py
Normal file
102
scripts/gfw_rules_generator.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import argparse
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# GFWList 官方(或常见)的地址
|
||||||
|
GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"
|
||||||
|
|
||||||
|
def log_info(message):
|
||||||
|
print(f"[INFO] {message}")
|
||||||
|
|
||||||
|
def generate_rules(proxy_server, foreign_dns, domestic_dns, ipset_name="gfwlist"):
|
||||||
|
"""
|
||||||
|
生成 Dnsmasq 和 IPSet 规则文件。
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
log_info(f"正在从 {GFWLIST_URL} 下载 GFWList...")
|
||||||
|
response = requests.get(GFWLIST_URL, timeout=30)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
# 1. 解码 GFWList
|
||||||
|
try:
|
||||||
|
content = base64.b64decode(response.text).decode('utf-8')
|
||||||
|
except:
|
||||||
|
# 如果内容不是 base64 编码,则直接使用
|
||||||
|
content = response.text
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
log_info(f"下载 GFWList 失败,使用本地缓存:{e}")
|
||||||
|
# 允许继续运行,依赖旧的规则文件
|
||||||
|
content = ""
|
||||||
|
|
||||||
|
domains = set()
|
||||||
|
for line in content.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith(('#', '!')):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 提取域名(忽略 IP、通配符规则和特殊标记)
|
||||||
|
if line.startswith('||'):
|
||||||
|
domain = line[2:]
|
||||||
|
elif line.startswith('.'):
|
||||||
|
domain = line[1:]
|
||||||
|
elif '/' in line:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
domain = line
|
||||||
|
|
||||||
|
# 简单过滤,确保是域名
|
||||||
|
if domain and '.' in domain and not domain.startswith('*.'):
|
||||||
|
domains.add(domain)
|
||||||
|
|
||||||
|
# 2. 生成 DNSMasq 配置文件
|
||||||
|
dnsmasq_conf_path = "/etc/dnsmasq.d/gfwlist_router.conf"
|
||||||
|
|
||||||
|
# 确保 foreign_dns 包含端口 (例如 127.0.0.1#1086)
|
||||||
|
proxy_dns_server = f"{foreign_dns}#{proxy_server.split(':')[1]}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(dnsmasq_conf_path, 'w') as f:
|
||||||
|
f.write(f"# Dnsmasq rules generated by gfw_rules_generator.py\n")
|
||||||
|
|
||||||
|
# 设置国内 DNS
|
||||||
|
f.write(f"server={domestic_dns}\n")
|
||||||
|
|
||||||
|
# GFWList 域名设置
|
||||||
|
for domain in sorted(list(domains)):
|
||||||
|
# 1. 将域名加入 IPSet 集合
|
||||||
|
f.write(f"ipset=/{domain}/{ipset_name}\n")
|
||||||
|
# 2. 通过代理的 DNS 服务器解析
|
||||||
|
f.write(f"server=/{domain}/{proxy_dns_server}\n")
|
||||||
|
|
||||||
|
log_info(f"已生成 Dnsmasq 规则到 {dnsmasq_conf_path},包含 {len(domains)} 个域名。")
|
||||||
|
except IOError as e:
|
||||||
|
log_info(f"写入 Dnsmasq 文件失败: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 3. 确保 IPSet 存在
|
||||||
|
# 脚本不负责添加 IP 地址(由 Dnsmasq 在运行时动态添加)
|
||||||
|
# 但需要确保 IPSet 集合本身存在。
|
||||||
|
try:
|
||||||
|
os.system(f"sudo ipset create {ipset_name} hash:ip family inet hashsize 1024 maxelem 65536 &>/dev/null || sudo ipset flush {ipset_name}")
|
||||||
|
log_info(f"已确保 IPSet 集合 '{ipset_name}' 存在。")
|
||||||
|
except Exception as e:
|
||||||
|
log_info(f"创建 IPSet 失败: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="GFWList Rules Generator for Dnsmasq/IPSet")
|
||||||
|
parser.add_argument("-p", "--proxy", required=True, help="SOCKS5 Proxy server (e.g., 127.0.0.1:1086)")
|
||||||
|
parser.add_argument("-f", "--foreign-dns", required=True, help="Foreign DNS IP (e.g., 8.8.8.8)")
|
||||||
|
parser.add_argument("-d", "--domestic-dns", required=True, help="Domestic DNS IP (e.g., 223.5.5.5)")
|
||||||
|
parser.add_argument("-n", "--name", default="gfwlist", help="IPSet Name")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
log_info("开始生成 GFWList 规则...")
|
||||||
|
generate_rules(args.proxy, args.foreign_dns, args.domestic_dns, args.name)
|
||||||
|
log_info("规则生成完成。")
|
||||||
@ -2,26 +2,29 @@ from jinja2 import Environment, FileSystemLoader
|
|||||||
|
|
||||||
# 1. 定义你的客制化参数字典
|
# 1. 定义你的客制化参数字典
|
||||||
config_vars = {
|
config_vars = {
|
||||||
# 全局变量
|
# 全局变量
|
||||||
"gateway_lan_ip": "192.168.10.1",
|
"gateway_lan_ip": "192.168.2.1",
|
||||||
"gateway_lan_cidr": "192.168.10.0/24",
|
"gateway_lan_cidr": "192.168.2.0/24",
|
||||||
"wan_interface": "eth0", # 网关主机外网网卡
|
"wan_interface": "eno1", # 网关主机外网网卡
|
||||||
"lan_interface": "eth1", # 网关主机内网网卡
|
"lan_interface": "enx00e04c6800ae", # 网关主机内网网卡
|
||||||
"client_lan_interface": "eth0", # 内网主机网卡
|
"client_lan_interface": "eth0", # 内网主机网卡
|
||||||
|
|
||||||
|
# 网关主机独有变量
|
||||||
|
"dhcp_start_ip": "192.168.2.100",
|
||||||
|
"dhcp_end_ip": "192.168.2.200",
|
||||||
|
"dhcp_lease_time": "7200",
|
||||||
|
"remote_ssh_user": "kww",
|
||||||
|
"remote_ssh_ip": "8.222.165.87", # !!! 替换为你的远程SSH服务器IP
|
||||||
|
"remote_ssh_port": "22",
|
||||||
|
"local_socks5_port": "1080",
|
||||||
|
"redsocks_port": "55555",
|
||||||
|
"domestic_dns1": "223.5.5.5"
|
||||||
|
"domestic_dns2": "114.114.114.114",
|
||||||
|
"foreign_dns1": "8.8.8.8",
|
||||||
|
"foreign_dns2": "1.1.1.1",
|
||||||
|
"gfwlist2new_repo": "https://github.com/cokebar/gfwlist2dnsmasq_python.git",
|
||||||
|
"gfwlist2new_dir": "/opt/gfwlist2new",
|
||||||
|
|
||||||
# 网关主机独有变量
|
|
||||||
"dhcp_start_ip": "192.168.10.100",
|
|
||||||
"dhcp_end_ip": "192.168.10.200",
|
|
||||||
"dhcp_lease_time": "7200",
|
|
||||||
"remote_ssh_user": "your_remote_user",
|
|
||||||
"remote_ssh_ip": "your_remote_server_ip", # !!! 替换为你的远程SSH服务器IP
|
|
||||||
"remote_ssh_port": "22",
|
|
||||||
"local_socks5_port": "1080",
|
|
||||||
"redsocks_port": "12345",
|
|
||||||
"domestic_dns": "223.5.5.5,114.114.114.114",
|
|
||||||
"foreign_dns": "8.8.8.8,1.1.1.1",
|
|
||||||
"gfwlist2new_repo": "https://github.com/louisabrahams/gfwlist2new.git",
|
|
||||||
"gfwlist2new_dir": "/opt/gfwlist2new",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 2. 设置 Jinja2 环境
|
# 2. 设置 Jinja2 环境
|
||||||
@ -29,11 +32,11 @@ config_vars = {
|
|||||||
env = Environment(loader=FileSystemLoader('.'))
|
env = Environment(loader=FileSystemLoader('.'))
|
||||||
|
|
||||||
# 3. 渲染 gateway_config.sh
|
# 3. 渲染 gateway_config.sh
|
||||||
gateway_template = env.get_template('gateway_config.sh.j2')
|
gateway_template = env.get_template('gateway.sh.j2')
|
||||||
rendered_gateway_script = gateway_template.render(config_vars)
|
rendered_gateway_script = gateway_template.render(config_vars)
|
||||||
|
|
||||||
with open('gateway_config.sh', 'w') as f:
|
with open('gateway.sh', 'w') as f:
|
||||||
f.write(rendered_gateway_script)
|
f.write(rendered_gateway_script)
|
||||||
print("Generated gateway_config.sh")
|
print("Generated gateway_config.sh")
|
||||||
|
|
||||||
# 4. 渲染 client_config.sh
|
# 4. 渲染 client_config.sh
|
||||||
@ -41,7 +44,7 @@ client_template = env.get_template('client_config.sh.j2')
|
|||||||
rendered_client_script = client_template.render(config_vars) # 客户端脚本也需要一些全局变量
|
rendered_client_script = client_template.render(config_vars) # 客户端脚本也需要一些全局变量
|
||||||
|
|
||||||
with open('client_config.sh', 'w') as f:
|
with open('client_config.sh', 'w') as f:
|
||||||
f.write(rendered_client_script)
|
f.write(rendered_client_script)
|
||||||
print("Generated client_config.sh")
|
print("Generated client_config.sh")
|
||||||
|
|
||||||
print("\n!!! 请务必检查生成的 .sh 文件,特别是 SSH 代理和网卡名称等配置。")
|
print("\n!!! 请务必检查生成的 .sh 文件,特别是 SSH 代理和网卡名称等配置。")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user