使用场景
笔记本电脑:插网线上网,同时开热点给手机使用
台式机+USB无线网卡:共享有线网络
临时网络扩展:在没有路由器的情况下共享网络
核心思路是开启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