#!/bin/bash # OpenVPN 连通后拉起 SOCKS5(dante/sockd);仅服务戎行内网代理。 set -euo pipefail VPN_DIR="${VPN_DIR:-/vpn}" SOCKS_HOST="${SOCKS_HOST:-0.0.0.0}" SOCKS_PORT="${SOCKS_PORT:-1080}" RONGXING_HOST="${RONGXING_HOST:-192.168.3.43}" cd "$VPN_DIR" CONF="" for f in *.conf *.ovpn; do if [ -f "$f" ]; then CONF="$f" break fi done if [ -z "$CONF" ]; then echo "[rongxing-vpn] 未在 ${VPN_DIR} 找到 .ovpn/.conf,请挂载证书目录" exit 1 fi echo "[rongxing-vpn] 使用配置: ${CONF}" echo "[rongxing-vpn] 仅路由 ${RONGXING_HOST}/32,SOCKS5 ${SOCKS_HOST}:${SOCKS_PORT}" openvpn \ --config "$CONF" \ --cd "$VPN_DIR" \ --route-nopull \ --route "$RONGXING_HOST" 255.255.255.255 \ --daemon \ --writepid /var/run/openvpn.pid \ --log /var/log/openvpn.log \ --verb 3 for i in $(seq 1 90); do if ip link show tun0 >/dev/null 2>&1; then echo "[rongxing-vpn] tun0 已就绪 (${i}s)" break fi if [ "$i" -eq 90 ]; then echo "[rongxing-vpn] 等待 tun0 超时,OpenVPN 日志:" cat /var/log/openvpn.log || true exit 1 fi sleep 1 done # 生成 dante 配置并后台启动 sockd sed "s/__SOCKS_PORT__/${SOCKS_PORT}/g" /etc/sockd.conf.template > /etc/sockd.conf sockd -f /etc/sockd.conf -D SOCKS_PID="$(pidof sockd | awk '{print $1}')" if [ -z "${SOCKS_PID}" ]; then echo "[rongxing-vpn] sockd 启动失败" exit 1 fi echo "[rongxing-vpn] SOCKS5 已监听 :${SOCKS_PORT} (pid=${SOCKS_PID})" cleanup() { kill "$SOCKS_PID" 2>/dev/null || true if [ -f /var/run/openvpn.pid ]; then kill "$(cat /var/run/openvpn.pid)" 2>/dev/null || true fi } trap cleanup EXIT INT TERM while kill -0 "$(cat /var/run/openvpn.pid)" 2>/dev/null && kill -0 "$SOCKS_PID" 2>/dev/null; do sleep 5 done echo "[rongxing-vpn] OpenVPN 或 SOCKS 已退出" cat /var/log/openvpn.log || true exit 1