bugfix
This commit is contained in:
parent
9c99d67db3
commit
f2456fe033
@ -74,6 +74,14 @@ install_package() {
|
||||
# 0. 前置检查与环境初始化
|
||||
# ==============================================================================
|
||||
# check_root
|
||||
# 释放53端口
|
||||
|
||||
sudo systemctl stop systemd-resolved
|
||||
sudo systemctl disable systemd-resolved
|
||||
sudo rm /etc/resolv.conf
|
||||
# 创建新的 resolv.conf 文件,将本机地址作为唯一的 DNS 服务器
|
||||
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf > /dev/null
|
||||
|
||||
log_info "开始网关主机配置脚本..."
|
||||
|
||||
log_info "更新系统软件包列表..."
|
||||
@ -151,7 +159,6 @@ max-lease-time ${DHCP_LEASE_TIME};
|
||||
authoritative;
|
||||
|
||||
# A slightly different configuration for an internal subnet.
|
||||
{% set net_base = gateway_lan_ip.split('.') | slice(3) | join('.') %}
|
||||
subnet {{ net_base }}.0 netmask 255.255.255.0 {
|
||||
range ${DHCP_START_IP} ${DHCP_END_IP};
|
||||
option routers ${GATEWAY_LAN_IP};
|
||||
@ -211,18 +218,20 @@ fi
|
||||
log_info "SSH SOCKS5 代理已通过 Systemd 启动,并在 127.0.0.1:${LOCAL_SOCKS5_PORT} 监听,支持自动重连。"
|
||||
|
||||
# ==============================================================================
|
||||
# 4. 配置 redsocks (透明 SOCKS5 代理) (保持不变)
|
||||
# 4. 配置 redsocks (透明 SOCKS5 代理) (请替换为以下修正代码!)
|
||||
# ==============================================================================
|
||||
log_info "配置 redsocks 透明代理..."
|
||||
# 备份现有配置
|
||||
sudo cp /etc/redsocks.conf /etc/redsocks.conf.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份 redsocks.conf 失败。"
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# ❗❗ 关键修正:移除所有注释和分号,以避免 redsocks 配置文件解析错误 ❗❗
|
||||
cat <<EOF | sudo tee /etc/redsocks.conf > /dev/null
|
||||
base {
|
||||
log_debug = off;
|
||||
log_info = on;
|
||||
log = "syslog:daemon";
|
||||
daemon = on; # 后台运行
|
||||
daemon = on;
|
||||
redirector = iptables;
|
||||
}
|
||||
|
||||
@ -230,11 +239,12 @@ redsocks {
|
||||
local_ip = 127.0.0.1;
|
||||
local_port = ${REDSOCKS_PORT};
|
||||
|
||||
ip = 127.0.0.1; # SSH SOCKS5 代理的地址
|
||||
port = ${LOCAL_SOCKS5_PORT}; # SSH SOCKS5 代理的端口
|
||||
type = socks5; # SOCKS5 代理
|
||||
ip = 127.0.0.1;
|
||||
port = ${LOCAL_SOCKS5_PORT};
|
||||
type = socks5;
|
||||
}
|
||||
EOF
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
sudo systemctl restart redsocks || log_error "重启 redsocks 服务失败。"
|
||||
sudo systemctl enable redsocks || log_error "启用 redsocks 服务失败。"
|
||||
@ -263,6 +273,7 @@ server={{ domestic_dns2 }}
|
||||
# 国外域名通过 gfwlist2new 生成的配置文件转发到代理
|
||||
# dnsmasq will read additional configuration files from /etc/dnsmasq.d
|
||||
conf-dir=/etc/dnsmasq.d
|
||||
user=root
|
||||
EOF
|
||||
|
||||
# 注意:DHCP 服务器功能由 isc-dhcp-server 提供,dnsmasq 不再提供 DHCP。
|
||||
@ -275,7 +286,7 @@ sudo systemctl enable dnsmasq || log_error "启用 dnsmasq 服务失败。"
|
||||
log_info "dnsmasq 智能 DNS 转发已初步配置。"
|
||||
|
||||
# ==============================================================================
|
||||
# 6. 安装和配置 gfwlist2new (保持不变)
|
||||
# 6. 安装和配置 gfwlist2new (已修正 crontab 参数和 PySocks 依赖)
|
||||
# ==============================================================================
|
||||
log_info "集成和配置 GFW 规则生成器 (gfw_rules_generator.py)..."
|
||||
LOCAL_SCRIPT_NAME="gfw_rules_generator.py"
|
||||
@ -284,15 +295,12 @@ if [ ! -d "${GFWLIST2NEW_DIR}" ]; then
|
||||
log_info "创建脚本目录..."
|
||||
sudo mkdir -p "${GFWLIST2NEW_DIR}" || log_error "创建目录 ${GFWLIST2NEW_DIR} 失败。"
|
||||
fi
|
||||
cp $LOCAL_SCRIPT_NAME ${GFWLIST2NEW_DIR}
|
||||
sudo cp $LOCAL_SCRIPT_NAME ${GFWLIST2NEW_DIR}
|
||||
|
||||
# 确保安装 requests 依赖
|
||||
log_info "安装 Python 依赖:requests..."
|
||||
sudo pip3 install requests || log_error "安装 requests 依赖失败。"
|
||||
# 确保安装 requests 和 PySocks 依赖
|
||||
log_info "安装 Python 依赖:requests 和 PySocks..."
|
||||
sudo pip3 install requests PySocks || log_error "安装 requests/PySocks 依赖失败。"
|
||||
|
||||
# 写入新的 Python 脚本(假设您已将上面的内容保存到临时文件并复制到这里)
|
||||
# 推荐您手动将上面的 Python 代码保存到 ${GFWLIST2NEW_DIR}/${LOCAL_SCRIPT_NAME}
|
||||
# 如果要用脚本自动写入,代码会非常长,这里跳过写入步骤,假设文件已存在。
|
||||
log_info "请确保 gfw_rules_generator.py 文件已存在于 ${GFWLIST2NEW_DIR}/"
|
||||
|
||||
cd "${GFWLIST2NEW_DIR}"
|
||||
@ -301,14 +309,18 @@ cd "${GFWLIST2NEW_DIR}"
|
||||
SOCKS5_SERVER_ADDR="127.0.0.1:${LOCAL_SOCKS5_PORT}"
|
||||
|
||||
log_info "执行 GFW 规则生成脚本..."
|
||||
# 使用 -p, -f, -d 参数执行新脚本
|
||||
sudo python3 "${LOCAL_SCRIPT_NAME}" -p "${SOCKS5_SERVER_ADDR}" -f "{{ foreign_dns1 }} {{foreign_dns2 }}" -d "{{ domestic_dns1 }} {{ domestic_dns2 }}" || log_error "规则生成脚本运行失败。"
|
||||
# 修正后的参数传递方式 (注意双引号和变量组)
|
||||
sudo python3 "${LOCAL_SCRIPT_NAME}" \
|
||||
-p "${SOCKS5_SERVER_ADDR}" \
|
||||
-f {{ foreign_dns1 }} {{ foreign_dns2 }} \
|
||||
-d {{ domestic_dns1 }} {{ domestic_dns2 }} \
|
||||
|| log_error "规则生成脚本运行失败。"
|
||||
|
||||
sudo systemctl restart dnsmasq || log_error "重启 dnsmasq (gfwlist) 失败。"
|
||||
|
||||
log_info "设置 GFW 规则定时更新任务 (每天凌晨 3:00)..."
|
||||
# 设置定时任务
|
||||
(sudo crontab -l 2>/dev/null; echo "0 3 * * * cd ${GFWLIST2NEW_DIR} && sudo python3 ${LOCAL_SCRIPT_NAME} -p ${SOCKS5_SERVER_ADDR} -f "{{ foreign_dns1 }} {{ foreign_dns2 }}" -d "{{ domestic_dns1 }} {{domestic_dns1}}" && sudo systemctl restart dnsmasq") | sudo crontab -
|
||||
# 设置定时任务(已修正国内 DNS 变量)
|
||||
(sudo crontab -l 2>/dev/null; echo "0 3 * * * cd ${GFWLIST2NEW_DIR} && sudo python3 ${LOCAL_SCRIPT_NAME} -p ${SOCKS5_SERVER_ADDR} -f {{ foreign_dns1 }} {{ foreign_dns2 }} -d {{ domestic_dns1 }} {{ domestic_dns2 }} && sudo systemctl restart dnsmasq") | sudo crontab -
|
||||
log_info "规则生成器配置完成并设置定时更新。"
|
||||
cd - > /dev/null
|
||||
|
||||
@ -351,35 +363,32 @@ sudo iptables -t nat -A PREROUTING -d 127.0.0.0/8 -j RETURN || log_error "排除
|
||||
# 3.2 排除局域网内流量 (不代理内网互访)
|
||||
sudo iptables -t nat -A PREROUTING -i {{ lan_interface }} -d {{ gateway_lan_cidr }} -j RETURN || log_error "排除内网流量失败。"
|
||||
|
||||
# 3.3 【❗ 补充:排除远程 SSH 服务器 IP ❗】
|
||||
# 避免 SSH 连接本身被重定向,防止无限循环。
|
||||
# 假设变量 REMOTE_SSH_IP 已经正确替换。
|
||||
# 3.3 排除远程 SSH 服务器 IP (防止 SSH 连接本身被重定向)
|
||||
sudo iptables -t nat -A PREROUTING -d {{ remote_ssh_ip }} -j RETURN || log_error "排除远程 SSH IP 失败。"
|
||||
log_info "已添加规则:排除远程 SSH 服务器 {{ remote_ssh_ip }}。"
|
||||
|
||||
|
||||
# 3.4 【❗ 补充:排除国内 IP ❗】
|
||||
# 排除目标 IP 在 china_ip 集合中的流量(国内流量直连)
|
||||
# 假设 china_ip 集合通过其他脚本/步骤创建
|
||||
# 注意:您的 gfwlist2new/gfw_rules_generator 脚本只处理 gfwlist,这里不需要 china_ip 的 ipset 排除
|
||||
# 而是依赖 gfwlist ipset 的精准捕获。我们移除这个容易出错的步骤,只依赖 gfwlist。
|
||||
# 如果需要排除国内 IP 段,需要有外部脚本维护 china_ip 集合。
|
||||
|
||||
# --- 重定向规则 ---
|
||||
|
||||
# 3.5 核心重定向规则:
|
||||
# 3.4 核心重定向规则:
|
||||
# 只有流量目标 IP 在 gfwlist ipset 集合中,才重定向到 redsocks。
|
||||
# 注意:该规则必须在排除规则之后。
|
||||
sudo iptables -t nat -A PREROUTING -i {{ lan_interface }} -p tcp -s {{ gateway_lan_cidr }} -m set --match-set gfwlist dst -j REDIRECT --to-ports ${REDSOCKS_PORT}
|
||||
log_info "已配置透明代理重定向规则 (目标IP在 gfwlist 中的内网TCP流量到 redsocks)。"
|
||||
|
||||
# ❗❗ 关键修正:必须排除远程 SSH 服务器的 IP ❗❗
|
||||
# 确保 SSH 隧道本身可以直连建立,不被代理。
|
||||
sudo iptables -t nat -A OUTPUT -d {{ remote_ssh_ip }} -p tcp -j RETURN
|
||||
log_info "已配置排除远程 SSH 服务器 {{ remote_ssh_ip }} 的规则。"
|
||||
|
||||
|
||||
# 4. 排除 redsocks 自身流量循环 (OUTPUT 链)
|
||||
# 这一步非常重要,避免 redsocks/ssh 客户端自己产生流量又被 iptables 捕获
|
||||
# 排除目标地址是 127.0.0.1 的流量,它们是 SSH 和 Redsocks 的内部通信。
|
||||
sudo iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp -j RETURN
|
||||
log_info "已配置排除 redsocks 自身流量循环的规则。"
|
||||
|
||||
# 核心 OUTPUT 重定向规则:捕获所有目标IP在 gfwlist ipset 集合中的网关主机自身TCP流量,重定向到 redsocks。
|
||||
sudo iptables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports ${REDSOCKS_PORT}
|
||||
|
||||
# 保存 iptables 规则
|
||||
sudo netfilter-persistent save || log_error "保存 iptables 规则失败。"
|
||||
sudo systemctl enable netfilter-persistent || log_error "启用 netfilter-persistent 服务失败。"
|
||||
|
||||
@ -50,18 +50,26 @@ def generate_rules(proxy_server, foreign_dns_list, domestic_dns_list, ipset_name
|
||||
if not line or line.startswith(('#', '!')):
|
||||
continue
|
||||
|
||||
# 简单提取域名
|
||||
# 1. 清理前缀
|
||||
if line.startswith('||'):
|
||||
domain = line[2:]
|
||||
elif line.startswith('.'):
|
||||
domain = line[1:]
|
||||
elif '/' in line:
|
||||
continue
|
||||
else:
|
||||
domain = line
|
||||
|
||||
# 过滤掉 IP 地址,只保留域名
|
||||
# 2. 移除 URL 路径和查询参数
|
||||
if '/' in domain:
|
||||
domain = domain.split('/')[0]
|
||||
|
||||
# 3. 过滤掉 IP 地址和通配符,只保留域名
|
||||
if domain and '.' in domain and not domain.startswith('*.'):
|
||||
# dnsmasq只接受不带前导点的域名,例如: example.com
|
||||
if domain.startswith('.'):
|
||||
domain = domain[1:]
|
||||
|
||||
# 确保域名不包含非法字符
|
||||
if not any(c in domain for c in ('&', '?', '=', ':', '@', '%')):
|
||||
domains.add(domain)
|
||||
|
||||
# 2. 生成 DNSMasq 配置文件
|
||||
@ -70,7 +78,7 @@ def generate_rules(proxy_server, foreign_dns_list, domestic_dns_list, ipset_name
|
||||
# 代理的上游 DNS (只使用提供的第一个国外 DNS)
|
||||
primary_foreign_dns = foreign_dns_list[0]
|
||||
proxy_port = proxy_server.split(':')[1]
|
||||
proxy_dns_server = f"{primary_foreign_dns}#{proxy_port}"
|
||||
proxy_dns_server = f"{primary_foreign_dns}#53"
|
||||
|
||||
try:
|
||||
with open(dnsmasq_conf_path, 'w') as f:
|
||||
|
||||
@ -12,6 +12,7 @@ config_vars = {
|
||||
# 网关主机独有变量
|
||||
"dhcp_start_ip": "192.168.2.100",
|
||||
"dhcp_end_ip": "192.168.2.200",
|
||||
"net_base": "192.168.2",
|
||||
"dhcp_lease_time": "7200",
|
||||
"remote_ssh_user": "kww",
|
||||
"remote_ssh_ip": "8.222.165.87", # !!! 替换为你的远程SSH服务器IP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user