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