bugfix
This commit is contained in:
parent
515df93cdc
commit
cf1854f718
167
ecs/gateway_config.sh
Executable file
167
ecs/gateway_config.sh
Executable file
@ -0,0 +1,167 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
curuser=ymq
|
||||
sudo systemctl stop systemd-resolved
|
||||
sudo systemctl disable systemd-resolved
|
||||
sudo rm /etc/resolv.conf
|
||||
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
|
||||
# ==============================================================================
|
||||
# 网关主机配置变量 - 请根据你的实际环境修改!
|
||||
# ==============================================================================
|
||||
# 网关主机的主网卡名称 (例如 eth0, ens5 等)
|
||||
GATEWAY_MAIN_INTERFACE="eth0"
|
||||
|
||||
# 网关主机的内网IP (脚本会自动获取,用于监听和DNS)
|
||||
# 我们假设该网卡上有一个内网IP,例如 10.0.0.10
|
||||
GATEWAY_LAN_IP=""
|
||||
GATEWAY_PUBLIC_IP="" # 网关主机的公网IP,脚本会尝试获取
|
||||
GATEWAY_LAN_CIDR="192.168.16.0/24" # 你的云平台内部网络的IP范围,例如 10.0.0.0/16
|
||||
|
||||
# SSH SOCKS5 代理配置
|
||||
REMOTE_SSH_USER="ocaiuser" # 远程服务器的SSH用户名
|
||||
REMOTE_SSH_IP="opencomputing.ai" # 远程服务器的IP地址
|
||||
REMOTE_SSH_PORT="22" # 远程服务器的SSH端口
|
||||
LOCAL_SOCKS5_PORT="127.0.0.1:1086" # SSH SOCKS5 代理在本机监听的端口 (127.0.0.1:1080)
|
||||
|
||||
# 透明代理工具 redsocks2 监听端口
|
||||
REDSOCKS_PORT="12345" # redsocks2 在本机监听的端口
|
||||
|
||||
# DNSMASQ 配置
|
||||
DNSMASQ_LISTEN_IP="" # 脚本会自动获取 GATEWAY_LAN_IP
|
||||
DOMESTIC_DNS="223.5.5.5,114.114.114.114" # 国内DNS服务器
|
||||
FOREIGN_DNS="8.8.8.8,1.1.1.1" # 国外DNS服务器 (通过SSH SOCKS5代理访问)
|
||||
|
||||
# GFWLIST2NEW 工具仓库和安装路径
|
||||
GFWLIST2NEW_REPO="https://github.com/cokebar/gfwlist2dnsmasq_python.git"
|
||||
GFWLIST2NEW_DIR="/opt/gfwlist2new"
|
||||
|
||||
# ==============================================================================
|
||||
# 通用函数
|
||||
# ==============================================================================
|
||||
log_info() {
|
||||
echo -e "\e[32m[INFO] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "\e[33m[WARN] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m" >&2
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "\e[31m[ERROR] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "此脚本必须以 root 用户或使用 sudo 运行。"
|
||||
fi
|
||||
}
|
||||
|
||||
install_package() {
|
||||
PACKAGE="$1"
|
||||
if ! dpkg -s "$PACKAGE" &>/dev/null; then
|
||||
log_info "安装 $PACKAGE..."
|
||||
sudo apt install -y "$PACKAGE" || log_error "安装 $PACKAGE 失败。"
|
||||
else
|
||||
log_info "$PACKAGE 已安装。"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# 0. 前置检查与环境初始化
|
||||
# ==============================================================================
|
||||
# check_root
|
||||
log_info "开始网关主机配置脚本 (云服务器环境)..."
|
||||
|
||||
log_info "更新系统软件包列表..."
|
||||
sudo apt update || log_error "apt update 失败。"
|
||||
|
||||
log_info "禁用 UFW 以避免与 iptables 冲突..."
|
||||
sudo ufw disable || log_warn "UFW 未运行或禁用失败,请手动确认。"
|
||||
|
||||
log_info "SSH SOCKS5 代理已通过 Systemd 启动,并在 127.0.0.1:${LOCAL_SOCKS5_PORT} 监听,支持自动重连。"
|
||||
|
||||
# ==============================================================================
|
||||
# 5. 安装和配置 gfwlist2new (保持不变)
|
||||
# ==============================================================================
|
||||
log_info "安装和配置 gfwlist2new 工具..."
|
||||
if [ ! -d "${GFWLIST2NEW_DIR}" ]; then
|
||||
log_info "克隆 gfwlist2new 仓库..."
|
||||
sudo git clone "https://github.com/cokebar/gfwlist2dnsmasq_python.git" "${GFWLIST2NEW_DIR}" || log_error "克隆 gfwlist2new 仓库失败。"
|
||||
fi
|
||||
cd "${GFWLIST2NEW_DIR}"
|
||||
log_info "安装 gfwlist2new 依赖..."
|
||||
sudo pip3 install -r requirements.txt || log_error "安装 gfwlist2new 依赖失败。"
|
||||
|
||||
log_info "配置 gfwlist2new 的配置文件 config.conf..."
|
||||
sudo cp config.conf config.conf.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份 gfwlist2new config.conf 失败。"
|
||||
cat <<EOF | sudo tee config.conf > /dev/null
|
||||
[DEFAULT]
|
||||
IPSET_NAME = gfwlist
|
||||
IPSET_FILE = /etc/ipset/gfwlist.conf
|
||||
DNSMASQ_CONF_PATH = /etc/dnsmasq.d/gfwlist_router.conf
|
||||
DNSMASQ_LOG_PATH = /var/log/dnsmasq.log
|
||||
DNS_PROXY_SERVER = 127.0.0.1#${REDSOCKS_PORT} # 这里的端口要指向 redsocks2
|
||||
Proxy Config
|
||||
SOCKS5_SERVER = 127.0.0.1:${LOCAL_SOCKS5_PORT} # 这里的端口是SSH SOCKS5代理
|
||||
GITHUB_RAW_URL = raw.githubusercontent.com
|
||||
EOF
|
||||
|
||||
log_info "执行 gfwlist2new 生成 ipset 和 dnsmasq 规则..."
|
||||
sudo python3 gfwlist2new.py -s "${SOCKS5_SERVER}" -f "8.8.8.8,1.1.1.1" -d "223.5.5.5,114.114.114.114" || log_error "gfwlist2new 运行失败。"
|
||||
sudo systemctl restart dnsmasq || log_error "重启 dnsmasq (gfwlist) 失败。"
|
||||
|
||||
log_info "设置 gfwlist2new 定时更新任务 (每天凌晨 3:00)..."
|
||||
(sudo crontab -l 2>/dev/null; echo "0 3 * * * cd ${GFWLIST2NEW_DIR} && sudo python3 gfwlist2new.py -s ${SOCKS5_SERVER} -f 8.8.8.8,1.1.1.1 -d 223.5.5.5,114.114.114.114 && sudo systemctl restart dnsmasq") | sudo crontab -
|
||||
log_info "gfwlist2new 配置完成并设置定时更新。"
|
||||
cd - > /dev/null
|
||||
|
||||
# ==============================================================================
|
||||
# 6. 配置 IPTABLES 规则实现透明代理和 NAT (针对单网卡环境)
|
||||
# ==============================================================================
|
||||
log_info "配置 IPTABLES 规则 (NAT 和透明代理,针对云服务器单网卡环境)..."
|
||||
|
||||
sudo iptables -F
|
||||
sudo iptables -X
|
||||
sudo iptables -t nat -F
|
||||
sudo iptables -t nat -X
|
||||
sudo iptables -t mangle -F
|
||||
sudo iptables -t mangle -X
|
||||
|
||||
# 1. 开启 NAT (使内网访问外网)
|
||||
# MASQUERADE 应该基于出口接口,这里就是 GATEWAY_MAIN_INTERFACE
|
||||
# --to-source 可以明确指定公网IP,如果GATEWAY_PUBLIC_IP能获取到
|
||||
if [ -n "${GATEWAY_PUBLIC_IP}" ]; then
|
||||
sudo iptables -t nat -A POSTROUTING -o ${GATEWAY_MAIN_INTERFACE} -s ${GATEWAY_LAN_CIDR} -j SNAT --to-source ${GATEWAY_PUBLIC_IP}
|
||||
log_info "已配置 NAT 规则,出口IP为 ${GATEWAY_PUBLIC_IP}。"
|
||||
else
|
||||
sudo iptables -t nat -A POSTROUTING -o ${GATEWAY_MAIN_INTERFACE} -s ${GATEWAY_LAN_CIDR} -j MASQUERADE
|
||||
log_info "已配置 NAT 规则,使用 ${GATEWAY_MAIN_INTERFACE} 主IP作为出口。"
|
||||
fi
|
||||
|
||||
# 2. IP 转发规则 (允许所有来自内网段的流量通过 GATEWAY_MAIN_INTERFACE 转发)
|
||||
# 这里更简化,所有来自内网段的流量都接受转发
|
||||
sudo iptables -A FORWARD -s ${GATEWAY_LAN_CIDR} -o ${GATEWAY_MAIN_INTERFACE} -j ACCEPT
|
||||
sudo iptables -A FORWARD -i ${GATEWAY_MAIN_INTERFACE} -d ${GATEWAY_LAN_CIDR} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
log_info "已配置 IP 转发规则。"
|
||||
|
||||
# 3. 透明代理规则 (使用 redsocks2 和 ipset)
|
||||
# 重定向所有来自内网段的 TCP 流量,如果目标IP在 gfwlist 中,则到 redsocks2
|
||||
sudo iptables -t nat -A PREROUTING -i ${GATEWAY_MAIN_INTERFACE} -p tcp -s ${GATEWAY_LAN_CIDR} -m set --match-set gfwlist dst -j REDIRECT --to-ports ${REDSOCKS_PORT}
|
||||
log_info "已配置透明代理重定向规则 (所有端口,目标IP在 gfwlist 中的内网TCP流量到 redsocks2)。"
|
||||
|
||||
# 4. 排除 redsocks2 自身流量循环 (保持不变)
|
||||
sudo iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport ${REDSOCKS_PORT} -j RETURN
|
||||
sudo iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport ${LOCAL_SOCKS5_PORT} -j RETURN
|
||||
log_info "已配置排除 redsocks2 自身流量循环的规则。"
|
||||
|
||||
# 保存 iptables 规则
|
||||
sudo netfilter-persistent save || log_error "保存 iptables 规则失败。"
|
||||
sudo systemctl enable netfilter-persistent || log_error "启用 netfilter-persistent 服务失败。"
|
||||
log_info "IPTABLES 规则已配置并保存。"
|
||||
|
||||
log_info "----------------------------------------------------------------------------------"
|
||||
log_info "网关云主机配置完成!"
|
||||
log_info "请检查 redsocks2 和 ssh -D 进程是否正常运行。"
|
||||
log_info "请注意:SSH SOCKS5 代理可能需要手动输入密码或配置免密登录才能持久运行。"
|
||||
log_info "----------------------------------------------------------------------------------"
|
||||
311
ecs/gateway_config.sh.j2
Normal file
311
ecs/gateway_config.sh.j2
Normal file
@ -0,0 +1,311 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
curuser=ymq
|
||||
sudo systemctl stop systemd-resolved
|
||||
sudo systemctl disable systemd-resolved
|
||||
sudo rm /etc/resolv.conf
|
||||
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
|
||||
# ==============================================================================
|
||||
# 网关主机配置变量 - 请根据你的实际环境修改!
|
||||
# ==============================================================================
|
||||
# 网关主机的主网卡名称 (例如 eth0, ens5 等)
|
||||
GATEWAY_MAIN_INTERFACE="{{ gateway_main_interface }}"
|
||||
|
||||
# 网关主机的内网IP (脚本会自动获取,用于监听和DNS)
|
||||
# 我们假设该网卡上有一个内网IP,例如 10.0.0.10
|
||||
GATEWAY_LAN_IP=""
|
||||
GATEWAY_PUBLIC_IP="" # 网关主机的公网IP,脚本会尝试获取
|
||||
GATEWAY_LAN_CIDR="{{ internal_network_range }}" # 你的云平台内部网络的IP范围,例如 10.0.0.0/16
|
||||
|
||||
# SSH SOCKS5 代理配置
|
||||
REMOTE_SSH_USER="{{ remote_ssh_user }}" # 远程服务器的SSH用户名
|
||||
REMOTE_SSH_IP="{{ remote_ssh_ip }}" # 远程服务器的IP地址
|
||||
REMOTE_SSH_PORT="{{ remote_ssh_port }}" # 远程服务器的SSH端口
|
||||
LOCAL_SOCKS5_PORT="{{ local_socks5_port }}" # SSH SOCKS5 代理在本机监听的端口 (127.0.0.1:1080)
|
||||
|
||||
# 透明代理工具 redsocks2 监听端口
|
||||
REDSOCKS_PORT="{{ redsocks_port }}" # redsocks2 在本机监听的端口
|
||||
|
||||
# DNSMASQ 配置
|
||||
DNSMASQ_LISTEN_IP="" # 脚本会自动获取 GATEWAY_LAN_IP
|
||||
DOMESTIC_DNS="{{ domestic_dns }}" # 国内DNS服务器
|
||||
FOREIGN_DNS="{{ foreign_dns }}" # 国外DNS服务器 (通过SSH SOCKS5代理访问)
|
||||
|
||||
# GFWLIST2NEW 工具仓库和安装路径
|
||||
GFWLIST2NEW_REPO="{{ gfwlist2new_repo }}"
|
||||
GFWLIST2NEW_DIR="{{ gfwlist2new_dir }}"
|
||||
|
||||
# ==============================================================================
|
||||
# 通用函数
|
||||
# ==============================================================================
|
||||
log_info() {
|
||||
echo -e "\e[32m[INFO] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "\e[33m[WARN] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m" >&2
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "\e[31m[ERROR] $(date +'%Y-%m-%d %H:%M:%S') $1\e[0m" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "此脚本必须以 root 用户或使用 sudo 运行。"
|
||||
fi
|
||||
}
|
||||
|
||||
install_package() {
|
||||
PACKAGE="$1"
|
||||
if ! dpkg -s "$PACKAGE" &>/dev/null; then
|
||||
log_info "安装 $PACKAGE..."
|
||||
sudo apt install -y "$PACKAGE" || log_error "安装 $PACKAGE 失败。"
|
||||
else
|
||||
log_info "$PACKAGE 已安装。"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# 0. 前置检查与环境初始化
|
||||
# ==============================================================================
|
||||
# check_root
|
||||
log_info "开始网关主机配置脚本 (云服务器环境)..."
|
||||
|
||||
log_info "更新系统软件包列表..."
|
||||
sudo apt update || log_error "apt update 失败。"
|
||||
|
||||
log_info "禁用 UFW 以避免与 iptables 冲突..."
|
||||
sudo ufw disable || log_warn "UFW 未运行或禁用失败,请手动确认。"
|
||||
|
||||
log_info "安装必要工具:net-tools, iptables-persistent, ipset, dnsmasq, redsocks2, git, python3-pip..."
|
||||
install_package net-tools
|
||||
install_package iptables-persistent
|
||||
install_package ipset
|
||||
install_package dnsmasq
|
||||
install_package redsocks
|
||||
install_package git
|
||||
install_package python3-pip
|
||||
# install_package isc-dhcp-server # 云服务器环境不需要运行 DHCP 服务器
|
||||
|
||||
# 动态获取网关主机的内网IP和公网IP
|
||||
log_info "获取网关主机的 IP 地址..."
|
||||
GATEWAY_LAN_IP=$(ip -4 addr show dev ${GATEWAY_MAIN_INTERFACE} | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
|
||||
if [ -z "${GATEWAY_LAN_IP}" ]; then
|
||||
log_error "无法获取网卡 ${GATEWAY_MAIN_INTERFACE} 的内网 IP 地址。请检查网卡名称或网络配置。"
|
||||
fi
|
||||
log_info "网关主机的内网 IP: ${GATEWAY_LAN_IP}"
|
||||
|
||||
# 尝试获取公网IP (可能需要专门的服务或配置,这里假设通常第一个IP是公网或路由器的出口IP)
|
||||
# 更准确的获取公网IP方式是 curl ifconfig.me 但这取决于网络能否访问外网
|
||||
# 这里我们直接使用网卡IP进行MASQUERADE,或如果云平台有专门的公网IP,需要替换
|
||||
GATEWAY_PUBLIC_IP=$(curl -s ifconfig.me) # 尝试通过外部服务获取公网IP,如果无法访问,则MASQUERADE会使用网卡主IP
|
||||
if [ -z "${GATEWAY_PUBLIC_IP}" ]; then
|
||||
log_warn "无法通过外部服务获取公网 IP。MASQUERADE 将使用网卡主 IP。"
|
||||
# 另一种方式是获取该网卡上的任何一个非10. 172.16-31. 192.168. 的IP
|
||||
# GATEWAY_PUBLIC_IP=$(ip -4 addr show dev ${GATEWAY_MAIN_INTERFACE} | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -vE '^(10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)' | head -1)
|
||||
fi
|
||||
log_info "网关主机的公网 IP (或出口 IP): ${GATEWAY_PUBLIC_IP:-Using main interface IP}"
|
||||
DNSMASQ_LISTEN_IP="${GATEWAY_LAN_IP}"
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# 1. 配置网卡和 IP 转发
|
||||
# ==============================================================================
|
||||
log_info "确保网关主机主网卡 (${GATEWAY_MAIN_INTERFACE}) 为 DHCP 模式..."
|
||||
# Netplan 配置 (通常云服务器默认就是 DHCP)
|
||||
NETPLAN_FILE="/etc/netplan/01-netcfg.yaml"
|
||||
# 备份现有配置
|
||||
sudo cp ${NETPLAN_FILE} ${NETPLAN_FILE}.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份Netplan文件失败。"
|
||||
|
||||
cat <<EOF | sudo tee ${NETPLAN_FILE} > /dev/null
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
{{ gateway_main_interface }}:
|
||||
dhcp4: true # 云服务器通常使用DHCP获取IP
|
||||
optional: true
|
||||
EOF
|
||||
|
||||
sudo chmod 600 ${NETPLAN_FILE}
|
||||
sudo netplan try --yes
|
||||
sudo netplan apply || log_error "应用 Netplan 配置失败,请检查网卡名称。"
|
||||
log_info "网卡 ${GATEWAY_MAIN_INTERFACE} 已配置为 DHCP 模式。"
|
||||
|
||||
|
||||
log_info "开启 IP 转发功能..."
|
||||
sudo sed -i '/^#net.ipv4.ip_forward=1/s/^#//' /etc/sysctl.conf || true # 取消注释
|
||||
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf > /dev/null # 确保添加
|
||||
sudo sysctl -p > /dev/null || log_error "应用 sysctl 配置失败。"
|
||||
log_info "IP 转发已开启。"
|
||||
# ==============================================================================
|
||||
# 2. SSH SOCKS5 代理 (使用 Systemd 持久化)
|
||||
# ==============================================================================
|
||||
log_info "${curuser}:配置 SSH SOCKS5 代理 Systemd 服务..."
|
||||
SSH_SOCKS5_SERVICE_FILE="/etc/systemd/system/ssh-socks5.service"
|
||||
|
||||
# 动态创建 Service 文件
|
||||
cat <<EOF | sudo tee ${SSH_SOCKS5_SERVICE_FILE} > /dev/null
|
||||
[Unit]
|
||||
Description=SSH SOCKS5 Proxy Service
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=${curuser}
|
||||
Type=simple
|
||||
# 注意:这里需要确保用户 {{ remote_ssh_user }} 是一个实际存在的用户,并且可以访问其 $HOME/.ssh
|
||||
# 为了简化,我们暂时用root运行,但更推荐使用非root用户
|
||||
ExecStart=/usr/bin/ssh -D ${LOCAL_SOCKS5_PORT} -N -p ${REMOTE_SSH_PORT} ${REMOTE_SSH_USER}@${REMOTE_SSH_IP} -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=3
|
||||
# 使用 Restart 策略确保连接断开时自动重连
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
log_info "启动并启用 SSH SOCKS5 代理服务..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ssh-socks5.service || log_error "启用 ssh-socks5 服务失败。"
|
||||
sudo systemctl restart ssh-socks5.service || log_error "启动 ssh-socks5 服务失败。请检查连接和免密登录配置。"
|
||||
sleep 5 # 留出时间让服务启动和重试
|
||||
|
||||
if ! ss -tnlp | grep ":${LOCAL_SOCKS5_PORT}" &>/dev/null; then
|
||||
log_error "SSH SOCKS5 代理端口 ${LOCAL_SOCKS5_PORT} 未在监听。请手动检查 SSH 进程。"
|
||||
fi
|
||||
log_info "SSH SOCKS5 代理已通过 Systemd 启动,并在 127.0.0.1:${LOCAL_SOCKS5_PORT} 监听,支持自动重连。"
|
||||
|
||||
# ==============================================================================
|
||||
# 3. Redsocks2 透明代理 (保持不变)
|
||||
# ==============================================================================
|
||||
log_info "配置 redsocks2 透明代理..."
|
||||
sudo cp /etc/redsocks.conf /etc/redsocks.conf.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份 redsocks.conf 失败。"
|
||||
cat <<EOF | sudo tee /etc/redsocks.conf > /dev/null
|
||||
base {
|
||||
log_debug = off;
|
||||
log_info = on;
|
||||
log = "syslog:daemon";
|
||||
daemon = on;
|
||||
redirector = iptables;
|
||||
}
|
||||
redsocks {
|
||||
local_ip = 127.0.0.1;
|
||||
local_port = ${REDSOCKS_PORT};
|
||||
ip = 127.0.0.1;
|
||||
port = ${LOCAL_SOCKS5_PORT};
|
||||
type = socks5;
|
||||
}
|
||||
EOF
|
||||
sudo systemctl restart redsocks2 || log_error "重启 redsocks2 服务失败。"
|
||||
sudo systemctl enable redsocks2 || log_error "启用 redsocks2 服务失败。"
|
||||
log_info "redsocks2 透明代理已配置并启动,监听 127.0.0.1:${REDSOCKS_PORT}。"
|
||||
|
||||
# ==============================================================================
|
||||
# 4. Dnsmasq 智能 DNS 转发 (保持不变,监听内网IP)
|
||||
# ==============================================================================
|
||||
log_info "配置 dnsmasq 智能 DNS 转发..."
|
||||
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份 dnsmasq.conf 失败。"
|
||||
sudo rm -f /etc/dnsmasq.d/* # 清理旧的额外配置
|
||||
cat <<EOF | sudo tee /etc/dnsmasq.conf > /dev/null
|
||||
listen-address=${DNSMASQ_LISTEN_IP},127.0.0.1
|
||||
no-resolv
|
||||
no-poll
|
||||
server={{ domestic_dns }}
|
||||
conf-dir=/etc/dnsmasq.d
|
||||
EOF
|
||||
|
||||
# 确保 dnsmasq 不会干扰云平台的DHCP (不再是 isc-dhcp-server)
|
||||
# 这些选项只是建议,如果云平台DHCP工作良好,可能不需要
|
||||
# echo "dhcp-option=option:router,${GATEWAY_LAN_IP}" | sudo tee -a /etc/dnsmasq.conf > /dev/null
|
||||
# echo "dhcp-option=option:dns-server,${GATEWAY_LAN_IP}" | sudo tee -a /etc/dnsmasq.conf > /dev/null
|
||||
|
||||
sudo systemctl restart dnsmasq || log_error "重启 dnsmasq 服务失败。"
|
||||
sudo systemctl enable dnsmasq || log_error "启用 dnsmasq 服务失败。"
|
||||
log_info "dnsmasq 智能 DNS 转发已初步配置,监听 ${DNSMASQ_LISTEN_IP}。"
|
||||
|
||||
# ==============================================================================
|
||||
# 5. 安装和配置 gfwlist2new (保持不变)
|
||||
# ==============================================================================
|
||||
log_info "安装和配置 gfwlist2new 工具..."
|
||||
if [ ! -d "${GFWLIST2NEW_DIR}" ]; then
|
||||
log_info "克隆 gfwlist2new 仓库..."
|
||||
sudo git clone "{{ gfwlist2new_repo }}" "${GFWLIST2NEW_DIR}" || log_error "克隆 gfwlist2new 仓库失败。"
|
||||
fi
|
||||
cd "${GFWLIST2NEW_DIR}"
|
||||
log_info "安装 gfwlist2new 依赖..."
|
||||
sudo pip3 install -r requirements.txt || log_error "安装 gfwlist2new 依赖失败。"
|
||||
|
||||
log_info "配置 gfwlist2new 的配置文件 config.conf..."
|
||||
sudo cp config.conf config.conf.bak_$(date +%Y%m%d%H%M%S) || log_warn "备份 gfwlist2new config.conf 失败。"
|
||||
cat <<EOF | sudo tee config.conf > /dev/null
|
||||
[DEFAULT]
|
||||
IPSET_NAME = gfwlist
|
||||
IPSET_FILE = /etc/ipset/gfwlist.conf
|
||||
DNSMASQ_CONF_PATH = /etc/dnsmasq.d/gfwlist_router.conf
|
||||
DNSMASQ_LOG_PATH = /var/log/dnsmasq.log
|
||||
DNS_PROXY_SERVER = 127.0.0.1#${REDSOCKS_PORT} # 这里的端口要指向 redsocks2
|
||||
Proxy Config
|
||||
SOCKS5_SERVER = 127.0.0.1:${LOCAL_SOCKS5_PORT} # 这里的端口是SSH SOCKS5代理
|
||||
GITHUB_RAW_URL = raw.githubusercontent.com
|
||||
EOF
|
||||
|
||||
log_info "执行 gfwlist2new 生成 ipset 和 dnsmasq 规则..."
|
||||
sudo python3 gfwlist2new.py -s "${SOCKS5_SERVER}" -f "{{ foreign_dns }}" -d "{{ domestic_dns }}" || log_error "gfwlist2new 运行失败。"
|
||||
sudo systemctl restart dnsmasq || log_error "重启 dnsmasq (gfwlist) 失败。"
|
||||
|
||||
log_info "设置 gfwlist2new 定时更新任务 (每天凌晨 3:00)..."
|
||||
(sudo crontab -l 2>/dev/null; echo "0 3 * * * cd ${GFWLIST2NEW_DIR} && sudo python3 gfwlist2new.py -s ${SOCKS5_SERVER} -f {{ foreign_dns }} -d {{ domestic_dns }} && sudo systemctl restart dnsmasq") | sudo crontab -
|
||||
log_info "gfwlist2new 配置完成并设置定时更新。"
|
||||
cd - > /dev/null
|
||||
|
||||
# ==============================================================================
|
||||
# 6. 配置 IPTABLES 规则实现透明代理和 NAT (针对单网卡环境)
|
||||
# ==============================================================================
|
||||
log_info "配置 IPTABLES 规则 (NAT 和透明代理,针对云服务器单网卡环境)..."
|
||||
|
||||
sudo iptables -F
|
||||
sudo iptables -X
|
||||
sudo iptables -t nat -F
|
||||
sudo iptables -t nat -X
|
||||
sudo iptables -t mangle -F
|
||||
sudo iptables -t mangle -X
|
||||
|
||||
# 1. 开启 NAT (使内网访问外网)
|
||||
# MASQUERADE 应该基于出口接口,这里就是 GATEWAY_MAIN_INTERFACE
|
||||
# --to-source 可以明确指定公网IP,如果GATEWAY_PUBLIC_IP能获取到
|
||||
if [ -n "${GATEWAY_PUBLIC_IP}" ]; then
|
||||
sudo iptables -t nat -A POSTROUTING -o ${GATEWAY_MAIN_INTERFACE} -s ${GATEWAY_LAN_CIDR} -j SNAT --to-source ${GATEWAY_PUBLIC_IP}
|
||||
log_info "已配置 NAT 规则,出口IP为 ${GATEWAY_PUBLIC_IP}。"
|
||||
else
|
||||
sudo iptables -t nat -A POSTROUTING -o ${GATEWAY_MAIN_INTERFACE} -s ${GATEWAY_LAN_CIDR} -j MASQUERADE
|
||||
log_info "已配置 NAT 规则,使用 ${GATEWAY_MAIN_INTERFACE} 主IP作为出口。"
|
||||
fi
|
||||
|
||||
# 2. IP 转发规则 (允许所有来自内网段的流量通过 GATEWAY_MAIN_INTERFACE 转发)
|
||||
# 这里更简化,所有来自内网段的流量都接受转发
|
||||
sudo iptables -A FORWARD -s ${GATEWAY_LAN_CIDR} -o ${GATEWAY_MAIN_INTERFACE} -j ACCEPT
|
||||
sudo iptables -A FORWARD -i ${GATEWAY_MAIN_INTERFACE} -d ${GATEWAY_LAN_CIDR} -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
log_info "已配置 IP 转发规则。"
|
||||
|
||||
# 3. 透明代理规则 (使用 redsocks2 和 ipset)
|
||||
# 重定向所有来自内网段的 TCP 流量,如果目标IP在 gfwlist 中,则到 redsocks2
|
||||
sudo iptables -t nat -A PREROUTING -i ${GATEWAY_MAIN_INTERFACE} -p tcp -s ${GATEWAY_LAN_CIDR} -m set --match-set gfwlist dst -j REDIRECT --to-ports ${REDSOCKS_PORT}
|
||||
log_info "已配置透明代理重定向规则 (所有端口,目标IP在 gfwlist 中的内网TCP流量到 redsocks2)。"
|
||||
|
||||
# 4. 排除 redsocks2 自身流量循环 (保持不变)
|
||||
sudo iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport ${REDSOCKS_PORT} -j RETURN
|
||||
sudo iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport ${LOCAL_SOCKS5_PORT} -j RETURN
|
||||
log_info "已配置排除 redsocks2 自身流量循环的规则。"
|
||||
|
||||
# 保存 iptables 规则
|
||||
sudo netfilter-persistent save || log_error "保存 iptables 规则失败。"
|
||||
sudo systemctl enable netfilter-persistent || log_error "启用 netfilter-persistent 服务失败。"
|
||||
log_info "IPTABLES 规则已配置并保存。"
|
||||
|
||||
log_info "----------------------------------------------------------------------------------"
|
||||
log_info "网关云主机配置完成!"
|
||||
log_info "请检查 redsocks2 和 ssh -D 进程是否正常运行。"
|
||||
log_info "请注意:SSH SOCKS5 代理可能需要手动输入密码或配置免密登录才能持久运行。"
|
||||
log_info "----------------------------------------------------------------------------------"
|
||||
57
ecs/render.py
Normal file
57
ecs/render.py
Normal file
@ -0,0 +1,57 @@
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
# 1. 定义你的客制化参数字典
|
||||
config_vars = {
|
||||
# 全局/网关主机变量
|
||||
"gateway_main_interface": "eth0", # !!! 网关云主机的主网卡名称,请根据实际情况修改!
|
||||
"internal_network_range": "192.168.16.0/24", # !!! 你的云平台私有网络IP范围,例如 10.0.0.0/16, 172.16.0.0/12, 192.168.0.0/16
|
||||
|
||||
# SSH SOCKS5 代理配置
|
||||
"remote_ssh_user": "ocaiuser", # !!! 替换为你的远程SSH服务器用户名
|
||||
"remote_ssh_ip": "opencomputing.ai", # !!! 替换为你的远程SSH服务器IP
|
||||
"remote_ssh_port": "22",
|
||||
|
||||
# 其他默认值,通常无需修改
|
||||
"local_socks5_port": "1086",
|
||||
"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/cokebar/gfwlist2dnsmasq_python.git",
|
||||
"gfwlist2new_dir": "/opt/gfwlist2new",
|
||||
}
|
||||
|
||||
# 2. 设置 Jinja2 环境
|
||||
env = Environment(loader=FileSystemLoader('.'))
|
||||
|
||||
# 3. 渲染 gateway_config.sh
|
||||
gateway_template = env.get_template('gateway_config.sh.j2')
|
||||
rendered_gateway_script = gateway_template.render(config_vars)
|
||||
|
||||
with open('gateway_config.sh', 'w') as f:
|
||||
f.write(rendered_gateway_script)
|
||||
print("Generated gateway_config.sh for Cloud Server Environment.")
|
||||
|
||||
# 4. 提供内网主机配置说明
|
||||
print("\n--- 内网云主机配置说明 ---")
|
||||
print("内网云主机无需运行任何脚本!它们会从云平台 DHCP 获取 IP 和默认网关。")
|
||||
print("\n您唯一需要做的是:")
|
||||
print("1. 确保内网云主机的网卡 (例如 {{ config_vars['client_main_interface'] | default('ens5') }}) 是 DHCP 客户端模式 (云平台默认)。")
|
||||
print("2. **最关键的步骤:将内网云主机的 DNS 服务器设置为网关云主机的内网 IP。**")
|
||||
print(" - 这通常通过云平台的管理控制台进行配置,或者在内网云主机上手动修改 Netplan。")
|
||||
print(" - 例如,如果网关云主机的内网 IP 是 10.0.0.10,则内网云主机的 DNS 应该设置为 10.0.0.10。")
|
||||
print("\n 示例 Netplan 配置 (内网云主机,如果需要手动修改):")
|
||||
print(f" network:")
|
||||
print(f" version: 2")
|
||||
print(f" renderer: networkd")
|
||||
print(f" ethernets:")
|
||||
print(f" {{ config_vars['client_main_interface'] | default('ens5') }}: # 替换为内网主机的实际网卡名称")
|
||||
print(f" dhcp4: true")
|
||||
print(f" nameservers:")
|
||||
print(f" addresses: [{{ config_vars['gateway_lan_ip'] }}] # DNS 指向网关云主机的内网 IP")
|
||||
print(f" optional: true")
|
||||
print("\n 修改后,应用 Netplan 配置:sudo netplan try && sudo netplan apply")
|
||||
print(" 或者重启内网云主机。")
|
||||
print("--------------------------")
|
||||
|
||||
print("\n!!! 请务必检查生成的 gateway_config.sh 文件,特别是 SSH 代理、网卡名称和云平台私有网络范围等配置。")
|
||||
print("在执行前,给它添加可执行权限:chmod +x gateway_config.sh")
|
||||
Loading…
x
Reference in New Issue
Block a user