#!/bin/bash # ========================================================================= # WireGuard 统一部署脚本 v3 # 修复:ip_forward 持久化改用 /etc/sysctl.d/99-wg-forward.conf # 避免被其他 sysctl.d 文件覆盖导致重启后转发失效 # 新增:关闭 rp_filter,避免策略路由/多出口场景丢包 # 新增:PostUp/PostDown 动态获取出口网卡名,不再写死 ens2 # ========================================================================= # --- 基础网络配置 --- WG_IFACE="wg0" WG_PORT="1447" WG_SUBNET="10.100.0" WG_CONFIG="/etc/wireguard/${WG_IFACE}.conf" # ========================================================================= # !!! 核心密钥配置区 !!! # ========================================================================= SERVER_PRI_KEY="MM5+YFr9qH/+1FQaGnmGnZw2i1cQCz2oB2Ab8epclnw=" ROS_CLIENT_PRI_KEY="EPt5s0HSvgeZk48zxPuE4Qf9wj5KZLQNgqUmzFKYGGQ=" PRE_SHARED_KEY="sKXGh2P2JeC5PB0FCofclvk1l76XLdHf7HGrb0VizNo=" TEST_CLIENT_PUB_KEY="MKAmcEQCSuUdw1UY11AjTTnAwM9asAjflm33RB/6Wxs=" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' CYAN='\033[0;36m' PLAIN='\033[0m' # ========================================================================= # 工具函数 # ========================================================================= check_root() { if [ "$(id -u)" -ne 0 ]; then echo -e "${RED}错误:必须以 root 权限运行此脚本。${PLAIN}" exit 1 fi } # ========================================================================= # 功能 1:安装 WireGuard # ========================================================================= install_wg() { echo -e "${GREEN}=============================================${PLAIN}" echo -e "${GREEN} 开始安装 统一化 WireGuard 服务端... ${PLAIN}" echo -e "${GREEN}=============================================${PLAIN}" if [ -z "$SERVER_PRI_KEY" ]; then echo -e "${RED}错误:SERVER_PRI_KEY 未填写!${PLAIN}" exit 1 fi # ----------------------------------------------------------------- # [1/7] 安装依赖 # ----------------------------------------------------------------- echo -e "${YELLOW}[1/7] 更新系统并安装依赖...${PLAIN}" apt-get update -qq apt-get install -y wireguard qrencode iptables curl iproute2 openresolv # ----------------------------------------------------------------- # [2/7] 检测网络配置 # ----------------------------------------------------------------- echo -e "${YELLOW}[2/7] 检测网络配置...${PLAIN}" PUBLIC_IP=$(curl -s --max-time 5 ifconfig.me) if [ -z "$PUBLIC_IP" ]; then PUBLIC_IP=$(curl -s --max-time 5 4.ipw.cn); fi if [ -z "$PUBLIC_IP" ]; then echo -e "${RED}错误:无法获取公网 IP,请检查网络连接。${PLAIN}" exit 1 fi PUB_NIC=$(ip -4 route show default | grep -oP '(?<=dev )(\S+)' | head -1) if [ -z "$PUB_NIC" ]; then echo -e "${RED}错误:无法检测到默认网卡。${PLAIN}" exit 1 fi echo -e "公网 IP : ${GREEN}${PUBLIC_IP}${PLAIN}" echo -e "主网卡 : ${GREEN}${PUB_NIC}${PLAIN}" # ----------------------------------------------------------------- # [3/7] 生成配置文件 # ----------------------------------------------------------------- echo -e "${YELLOW}[3/7] 生成服务器配置 (${WG_CONFIG})...${PLAIN}" mkdir -p /etc/wireguard chmod 700 /etc/wireguard ROS_CLIENT_PUB_KEY=$(echo "${ROS_CLIENT_PRI_KEY}" | wg pubkey) SERVER_PUB_KEY=$(echo "${SERVER_PRI_KEY}" | wg pubkey) cat > "${WG_CONFIG}" </dev/null || true; \ iptables -D FORWARD -o ${WG_IFACE} -j ACCEPT 2>/dev/null || true; \ iptables -t nat -D POSTROUTING -o \$NIC -j MASQUERADE 2>/dev/null || true; \ iptables -I FORWARD -i ${WG_IFACE} -j ACCEPT; \ iptables -I FORWARD -o ${WG_IFACE} -j ACCEPT; \ iptables -t nat -A POSTROUTING -o \$NIC -j MASQUERADE PostDown = NIC=\$(ip -4 route show default | grep -oP '(?<=dev )(\S+)' | head -1); \ iptables -D FORWARD -i ${WG_IFACE} -j ACCEPT 2>/dev/null || true; \ iptables -D FORWARD -o ${WG_IFACE} -j ACCEPT 2>/dev/null || true; \ iptables -t nat -D POSTROUTING -o \$NIC -j MASQUERADE 2>/dev/null || true # ------------------------------------------ # Peer 1: ROS 路由器 (固定 IP: .2) # ------------------------------------------ [Peer] PublicKey = ${ROS_CLIENT_PUB_KEY} PresharedKey = ${PRE_SHARED_KEY} AllowedIPs = ${WG_SUBNET}.2/32 # ------------------------------------------ # Peer 2: 测速/连通性节点 test (固定 IP: .3) # ------------------------------------------ [Peer] PublicKey = ${TEST_CLIENT_PUB_KEY} PresharedKey = ${PRE_SHARED_KEY} AllowedIPs = ${WG_SUBNET}.3/32 EOF chmod 600 "${WG_CONFIG}" # ----------------------------------------------------------------- # [4/7] 持久化内核参数 —— 关键修复 # ① ip_forward:写到 99-wg-forward.conf,99- 前缀保证加载最靠后, # 不被其他 sysctl.d 文件覆盖 # ② rp_filter:关闭反向路径过滤,避免策略路由/多出口场景下 # 内核因回包路径不一致而静默丢包 # ----------------------------------------------------------------- echo -e "${YELLOW}[4/7] 持久化内核参数 (ip_forward + rp_filter)...${PLAIN}" cat > /etc/sysctl.d/99-wg-forward.conf < /dev/null # 立即验证 ip_forward CURRENT_FWD=$(cat /proc/sys/net/ipv4/ip_forward) if [ "$CURRENT_FWD" != "1" ]; then echo -e "${RED}错误:ip_forward 设置失败,当前值=${CURRENT_FWD},请手动排查!${PLAIN}" exit 1 fi echo -e "ip_forward 当前值 : ${GREEN}${CURRENT_FWD}${PLAIN} ✓" echo -e "rp_filter 当前值 : ${GREEN}$(cat /proc/sys/net/ipv4/conf/all/rp_filter)${PLAIN} (0=已关闭) ✓" # ----------------------------------------------------------------- # [5/7] 配置 systemd 服务依赖网络就绪后再启动 # 防止 VPS 重启时 wg-quick 早于网卡就绪导致 PostUp iptables 失败 # ----------------------------------------------------------------- echo -e "${YELLOW}[5/7] 配置 wg-quick 服务启动顺序...${PLAIN}" mkdir -p /etc/systemd/system/wg-quick@${WG_IFACE}.service.d/ cat > /etc/systemd/system/wg-quick@${WG_IFACE}.service.d/override.conf <> "${WG_CONFIG}" < "${CLIENT_CONFIG_FILE}" </dev/null | grep -c MASQUERADE) if [ "$NAT_COUNT" -gt 0 ]; then echo -e "NAT MASQUERADE : ${GREEN}存在 (${NAT_COUNT} 条) ✓${PLAIN}" else echo -e "NAT MASQUERADE : ${RED}不存在 ✗${PLAIN}" echo -e " 修复命令: systemctl restart wg-quick@${WG_IFACE}" fi # Peers 握手状态 echo -e "${CYAN}---------------------------------------------${PLAIN}" echo -e "Peer 握手状态:" wg show ${WG_IFACE} 2>/dev/null || echo -e "${RED}wg0 接口不存在${PLAIN}" } # ========================================================================= # 交互菜单 # ========================================================================= check_root echo -e "${CYAN}=============================================${PLAIN}" echo -e "${CYAN} WireGuard 管理脚本 v2 (统一密钥版) ${PLAIN}" echo -e "${CYAN}=============================================${PLAIN}" echo -e " ${GREEN}1.${PLAIN} 安装 WireGuard(全新部署)" echo -e " ${GREEN}2.${PLAIN} 添加客户端(手机/PC,IP 自动顺延)" echo -e " ${GREEN}3.${PLAIN} 状态自检(验证 ip_forward / NAT / Peer)" echo -e " ${GREEN}4.${PLAIN} 退出" echo -e "${CYAN}=============================================${PLAIN}" read -p "请输入数字 [1-4]: " MENU_CHOICE case $MENU_CHOICE in 1) install_wg ;; 2) add_client ;; 3) check_status ;; 4) exit 0 ;; *) echo -e "${RED}输入错误。${PLAIN}"; exit 1 ;; esac