解决TopSAP启用VPN期间互联网不可用问题

作者:zhangyunlong 发布时间: 2025-12-09 阅读量:4 评论数:0

使用场景

  1. 笔记本电脑:插网线上网,同时开热点给手机使用

  2. 台式机+USB无线网卡:共享有线网络

  3. 临时网络扩展:在没有路由器的情况下共享网络

核心思路是开启ip转发, 设置双向流量转发, 将热点设备的流量伪装为有线网卡

原理:

互联网
   ↓
有线网卡 (ETH_IF) ←─ 电脑主机 ─→ WiFi热点 (WIFI_IF)
   ↓                                     ↓
ISP网络                               其他设备(手机/平板等)

脚本内容:

#!/bin/bash

export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8

# 检查依赖
missing=""

if ! command -v zenity &> /dev/null; then
    missing="$missing zenity"
fi

if [ -n "$missing" ]; then
    if command -v sudo &> /dev/null; then
        echo "缺少以下依赖:$missing,正在尝试自动安装..."
        sudo apt update
        sudo apt install -y $missing
        if ! command -v zenity &> /dev/null; then
            echo "依赖安装失败或未安装 zenity,请手动安装后重试。"
            exit 1
        fi
        zenity --info --title="依赖安装" --text="依赖已安装:$missing"
    else
        echo "缺少以下依赖:$missing,请手动安装。"
        exit 1
    fi
fi

# 自动检测接口

detect_interfaces() {
    ETH_IF=$(nmcli -t -f DEVICE,TYPE,STATE device status | grep '^.*:ethernet:connected' | cut -d: -f1 | head -n1)
    WIFI_IF=$(nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device status | grep '^.*:wifi:connected:Hotspot' | cut -d: -f1 | head -n1)
}

enable_hotspot() {
    nmcli connection up Hotspot
    sleep 2
}

disable_hotspot() {
    nmcli connection down Hotspot
    sleep 1
}

enable_sharing() {
    detect_interfaces
    if [ -z "$ETH_IF" ]; then
        zenity --error --title="网络共享" --text="未检测到已连接的有线网卡!"
        return
    fi
    if [ -z "$WIFI_IF" ]; then
        zenity --question --title="开启热点" --text="未检测到热点,是否自动开启?"
        if [ $? -eq 0 ]; then
            enable_hotspot
            detect_interfaces
        else
            return
        fi
    fi

    sudo sysctl -w net.ipv4.ip_forward=1
    sudo iptables -t nat -C POSTROUTING -o "$ETH_IF" -j MASQUERADE 2>/dev/null || \
        sudo iptables -t nat -A POSTROUTING -o "$ETH_IF" -j MASQUERADE
    sudo iptables -C FORWARD -i "$ETH_IF" -o "$WIFI_IF" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
        sudo iptables -A FORWARD -i "$ETH_IF" -o "$WIFI_IF" -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo iptables -C FORWARD -i "$WIFI_IF" -o "$ETH_IF" -j ACCEPT 2>/dev/null || \
        sudo iptables -A FORWARD -i "$WIFI_IF" -o "$ETH_IF" -j ACCEPT

    zenity --info --title="共享网络" --text="网络共享已开启\n有线: $ETH_IF\n热点: $WIFI_IF"
}

disable_sharing() {
    detect_interfaces
    sudo sysctl -w net.ipv4.ip_forward=0
    if [ -n "$ETH_IF" ] && [ -n "$WIFI_IF" ]; then
        sudo iptables -t nat -D POSTROUTING -o "$ETH_IF" -j MASQUERADE 2>/dev/null
        sudo iptables -D FORWARD -i "$ETH_IF" -o "$WIFI_IF" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null
        sudo iptables -D FORWARD -i "$WIFI_IF" -o "$ETH_IF" -j ACCEPT 2>/dev/null
    fi
    disable_hotspot
    zenity --info --title="共享网络" --text="网络共享已关闭"
}

show_status() {
    detect_interfaces
    ip_forward=$(sysctl net.ipv4.ip_forward | awk '{print $3}')
    ip_status="未启用"
    [ "$ip_forward" = "1" ] && ip_status="已启用"

    nat_rules=$(sudo iptables -t nat -L POSTROUTING -n --line-numbers | grep MASQUERADE || echo "无 MASQUERADE 规则")
    forward_rules=$(sudo iptables -L FORWARD -n --line-numbers | grep -E "$ETH_IF|$WIFI_IF" || echo "无共享相关的 FORWARD 规则")

    zenity --info \
        --title="网络共享状态" \
        --text="IP 转发: $ip_status\n\nNAT MASQUERADE 规则:\n$nat_rules\n\nFORWARD 规则:\n$forward_rules"
}

MODE=$(zenity --list --radiolist \
    --title "网络共享工具" \
    --text "请选择操作:" \
    --column "" --column "操作" \
    TRUE "开启共享" FALSE "关闭共享" FALSE "查看状态" \
    --height=335 --width=300)

if [ -z "$MODE" ]; then
    exit 0
fi

case "$MODE" in
    "开启共享") enable_sharing ;;
    "关闭共享") disable_sharing ;;
    "查看状态") show_status ;;
esac

评论