Files
cellular-proxy/scripts/lib.sh
T
Hermes 8835646d34 feat: cellular-proxy 一键安装 — 走代理一律数据出口
- sing-box 单进程 bind 数据网卡
- mixed HTTP+SOCKS + 中文静态面板
- install.sh 支持 curl | sudo bash
- 512MB 友好 MemoryMax 默认 96MB
2026-07-21 10:56:27 +00:00

160 lines
4.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 公共库
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_FILE="${CONFIG_FILE:-$ROOT_DIR/config/settings.conf}"
log() { printf '[%s] %s\n' "$(date '+%F %T')" "$*" >&2; }
info() { log "INFO $*"; }
warn() { log "WARN $*"; }
err() { log "ERROR $*"; }
die() { err "$*"; exit 1; }
need_root() {
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
die "请用 root 运行(sudo"
fi
}
load_config() {
if [[ ! -f "$CONFIG_FILE" ]]; then
die "缺少配置: $CONFIG_FILE
请先: cp $ROOT_DIR/config/settings.conf.example $ROOT_DIR/config/settings.conf"
fi
set -a
# shellcheck disable=SC1090
source "$CONFIG_FILE"
set +a
INSTALL_DIR="${INSTALL_DIR:-/opt/cellular-proxy}"
LOG_DIR="${LOG_DIR:-/var/log/cellular-proxy}"
CELLULAR_IFACE="${CELLULAR_IFACE:-}"
CELLULAR_SOURCE_IP="${CELLULAR_SOURCE_IP:-}"
REQUIRE_CELLULAR_IFACE="${REQUIRE_CELLULAR_IFACE:-true}"
CELLULAR_IFACE_PATTERNS="${CELLULAR_IFACE_PATTERNS:-wwan,wwp,usb,enx,ppp,cdc}"
PROXY_LISTEN_HOST="${PROXY_LISTEN_HOST:-0.0.0.0}"
PROXY_MIXED_PORT="${PROXY_MIXED_PORT:-7890}"
PROXY_USER="${PROXY_USER:-}"
PROXY_PASS="${PROXY_PASS:-}"
PANEL_LISTEN_HOST="${PANEL_LISTEN_HOST:-0.0.0.0}"
PANEL_PORT="${PANEL_PORT:-9090}"
PANEL_SECRET="${PANEL_SECRET:-please-change-me}"
ENABLE_DNS="${ENABLE_DNS:-true}"
LOG_LEVEL="${LOG_LEVEL:-warn}"
SING_BOX_SOURCE="${SING_BOX_SOURCE:-release}"
SING_BOX_VERSION="${SING_BOX_VERSION:-1.11.7}"
SING_BOX_BIN="${SING_BOX_BIN:-}"
MEMORY_MAX_MB="${MEMORY_MAX_MB:-96}"
EGRESS_CHECK_URL="${EGRESS_CHECK_URL:-https://ifconfig.me}"
EXPECTED_CELLULAR_PUBLIC_IP="${EXPECTED_CELLULAR_PUBLIC_IP:-}"
for v in REQUIRE_CELLULAR_IFACE ENABLE_DNS; do
val="${!v}"
case "${val,,}" in
1|true|yes|on) printf -v "$v" '%s' true ;;
*) printf -v "$v" '%s' false ;;
esac
done
}
iface_exists() {
local ifc="$1"
[[ -n "$ifc" ]] && [[ -d "/sys/class/net/$ifc" ]]
}
is_virtual_or_skip_iface() {
local name="$1"
case "$name" in
lo|docker*|br-*|veth*|virbr*|cni*|flannel*|tun*|tap*|wg*|zt*|tailscale*|easy*|et*)
return 0
;;
esac
return 1
}
list_ifaces() {
local name state ip
for name in $(ls /sys/class/net 2>/dev/null | sort); do
[[ "$name" == "lo" ]] && continue
state="$(cat "/sys/class/net/$name/operstate" 2>/dev/null || echo unknown)"
ip="$(ip -4 -o addr show dev "$name" 2>/dev/null | awk '{print $4}' | head -1)"
printf '%s|%s|%s\n' "$name" "$state" "${ip:-}"
done
}
detect_default_iface() {
ip route show default 2>/dev/null | awk '/default/ {print $5; exit}'
}
detect_cellular_iface() {
local configured="$1"
if [[ -n "$configured" ]]; then
if [[ "$configured" == "lo" ]]; then
warn "CELLULAR_IFACE=lo 无效,将尝试自动探测"
elif iface_exists "$configured"; then
echo "$configured"
return 0
else
warn "配置的 CELLULAR_IFACE=$configured 不存在"
if [[ "$REQUIRE_CELLULAR_IFACE" == "true" ]]; then
return 1
fi
fi
fi
local patterns name state ip p cand=""
IFS=',' read -r -a patterns <<< "$CELLULAR_IFACE_PATTERNS"
while IFS='|' read -r name state ip; do
[[ -z "$name" ]] && continue
is_virtual_or_skip_iface "$name" && continue
for p in "${patterns[@]}"; do
p="${p// /}"
[[ -z "$p" ]] && continue
if [[ "$name" == *"$p"* ]]; then
if [[ "$state" == "up" || "$state" == "unknown" ]] && [[ -n "$ip" ]]; then
echo "$name"
return 0
fi
cand="${cand:-$name}"
fi
done
done < <(list_ifaces)
if [[ -n "$cand" ]]; then
echo "$cand"
return 0
fi
return 1
}
detect_source_ip() {
local ifc="$1"
ip -4 -o addr show dev "$ifc" 2>/dev/null | awk '{print $4}' | head -1 | cut -d/ -f1
}
arch_go() {
case "$(uname -m)" in
x86_64|amd64) echo amd64 ;;
aarch64|arm64) echo arm64 ;;
armv7l|armhf) echo armv7 ;;
*) die "不支持的架构: $(uname -m)" ;;
esac
}
ensure_dirs() {
mkdir -p "$INSTALL_DIR"/{bin,etc,ui,generated} "$LOG_DIR"
}
resolve_cellular() {
local cell
if ! cell="$(detect_cellular_iface "$CELLULAR_IFACE")"; then
if [[ "$REQUIRE_CELLULAR_IFACE" == "true" ]]; then
die "无法确定数据网卡。请设置 CELLULAR_IFACE= 或运行 scripts/detect.sh"
fi
warn "未找到数据网卡"
cell=""
fi
echo "$cell"
}