mirror of
https://github.com/andrey271192/keenetic_ssh-web.git
synced 2026-09-20 14:42:01 +00:00
`wg setconf` принимает только базовый формат (PrivateKey/ListenPort + [Peer]), без wg-quick-полей (Address/DNS/Table/...). Раньше клиентский wg0.conf содержал `Address = ...`, на котором setconf падал и не дочитывал [Peer]. Интерфейс поднимался, но без peer-а — handshake не отправлялся, сервер не знал endpoint, пинги через туннель не шли. Исправление: - Убираем Address из тела conf, ставим как ip addr add (это уже было). - В init.up добавили проверку: если после wg setconf нет блока `peer:` в `wg show`, печатаем ВНИМАНИЕ — чтобы такая поломка не оставалась тихой.
128 lines
5.0 KiB
Bash
Executable File
128 lines
5.0 KiB
Bash
Executable File
#!/bin/sh
|
||
# tunnel/tunnel-install.sh — установка WireGuard-клиента на роутере (Entware).
|
||
# Запускается с роутера, принимает 4 ENV-переменные (выдаёт kssh-tun add на VPS):
|
||
# VPS_ENDPOINT=<ip>:<port> — публичный endpoint VPS, UDP
|
||
# VPS_PUBKEY=<base64> — публичный ключ сервера
|
||
# CLIENT_IP=10.99.0.X — IP роутера в туннельной подсети
|
||
# CLIENT_PRIVKEY=<base64> — приватный ключ роутера
|
||
# По желанию:
|
||
# WG_IF=wg0 — имя интерфейса (по умолчанию wg0)
|
||
# WG_SUBNET=10.99.0.0/24 — какие IP маршрутизируются через туннель
|
||
# WG_KEEPALIVE=25 — PersistentKeepalive в секундах
|
||
set -e
|
||
|
||
WG_IF="${WG_IF:-wg0}"
|
||
WG_SUBNET="${WG_SUBNET:-10.99.0.0/24}"
|
||
WG_KEEPALIVE="${WG_KEEPALIVE:-25}"
|
||
WG_DIR="/opt/etc/wireguard"
|
||
INIT="/opt/etc/init.d/S50kssh-tunnel"
|
||
|
||
[ -z "$VPS_ENDPOINT" ] && { echo "VPS_ENDPOINT обязателен" >&2; exit 1; }
|
||
[ -z "$VPS_PUBKEY" ] && { echo "VPS_PUBKEY обязателен" >&2; exit 1; }
|
||
[ -z "$CLIENT_IP" ] && { echo "CLIENT_IP обязателен" >&2; exit 1; }
|
||
[ -z "$CLIENT_PRIVKEY" ] && { echo "CLIENT_PRIVKEY обязателен" >&2; exit 1; }
|
||
|
||
echo "==> WireGuard-клиент: $WG_IF $CLIENT_IP → $VPS_ENDPOINT"
|
||
|
||
# wireguard-tools (на Keenetic ядре уже есть модуль wireguard, нужны только утилиты)
|
||
if ! command -v wg >/dev/null 2>&1; then
|
||
if command -v opkg >/dev/null 2>&1; then
|
||
opkg update || echo "(opkg update: частичные ошибки источников — продолжаем)"
|
||
opkg install wireguard-tools >/dev/null 2>&1 || true
|
||
fi
|
||
fi
|
||
if ! command -v wg >/dev/null 2>&1; then
|
||
echo "wg не найден. Установите вручную: opkg install wireguard-tools" >&2
|
||
exit 1
|
||
fi
|
||
|
||
mkdir -p "$WG_DIR"
|
||
chmod 700 "$WG_DIR"
|
||
|
||
CONF="$WG_DIR/$WG_IF.conf"
|
||
umask 077
|
||
# Формат для `wg setconf` — без wg-quick полей (Address/DNS/Table/PostUp...).
|
||
# Address выставляем через `ip addr add` в init-скрипте.
|
||
cat > "$CONF" <<EOF
|
||
# kssh-tunnel client; адрес: $CLIENT_IP/24
|
||
[Interface]
|
||
PrivateKey = $CLIENT_PRIVKEY
|
||
|
||
[Peer]
|
||
PublicKey = $VPS_PUBKEY
|
||
Endpoint = $VPS_ENDPOINT
|
||
AllowedIPs = $WG_SUBNET
|
||
PersistentKeepalive = $WG_KEEPALIVE
|
||
EOF
|
||
chmod 600 "$CONF"
|
||
|
||
# Init-скрипт автозапуска
|
||
cat > "$INIT" <<INIEOF
|
||
#!/bin/sh
|
||
WG_IF="$WG_IF"
|
||
WG_DIR="$WG_DIR"
|
||
CONF="\$WG_DIR/\$WG_IF.conf"
|
||
ADDR="$CLIENT_IP/24"
|
||
SUBNET="$WG_SUBNET"
|
||
|
||
up() {
|
||
ip link show "\$WG_IF" >/dev/null 2>&1 && ip link del "\$WG_IF" 2>/dev/null
|
||
ip link add "\$WG_IF" type wireguard || { echo "ip link add не сработал — нет модуля wireguard в ядре?"; return 1; }
|
||
if ! wg setconf "\$WG_IF" "\$CONF"; then
|
||
echo "wg setconf вернул ошибку — проверьте \$CONF (формат: только PrivateKey + [Peer])"
|
||
return 1
|
||
fi
|
||
ip addr add "\$ADDR" dev "\$WG_IF"
|
||
ip link set "\$WG_IF" up
|
||
ip route add "\$SUBNET" dev "\$WG_IF" 2>/dev/null || true
|
||
if ! wg show "\$WG_IF" | grep -q '^peer:'; then
|
||
echo "ВНИМАНИЕ: peer не появился в \$WG_IF — handshake не состоится."
|
||
echo "Проверьте \$CONF и перезапустите."
|
||
fi
|
||
echo "started \$WG_IF \$ADDR"
|
||
}
|
||
down() {
|
||
ip link del "\$WG_IF" 2>/dev/null || true
|
||
echo "stopped \$WG_IF"
|
||
}
|
||
|
||
case "\$1" in
|
||
start) up ;;
|
||
stop) down ;;
|
||
restart) down; sleep 1; up ;;
|
||
status)
|
||
ip -4 -o addr show "\$WG_IF" 2>/dev/null && wg show "\$WG_IF" 2>/dev/null || echo "(\$WG_IF не поднят)"
|
||
;;
|
||
*) echo "usage: \$0 {start|stop|restart|status}"; exit 1 ;;
|
||
esac
|
||
INIEOF
|
||
chmod +x "$INIT"
|
||
|
||
# Поднять
|
||
"$INIT" restart || true
|
||
|
||
# Автозапуск через rc.d, если поддерживается
|
||
if [ -d /opt/etc/rc.d ] && [ ! -e /opt/etc/rc.d/S50kssh-tunnel ]; then
|
||
ln -sf "$INIT" /opt/etc/rc.d/S50kssh-tunnel 2>/dev/null && \
|
||
echo "==> Автозапуск: /opt/etc/rc.d/S50kssh-tunnel → $INIT"
|
||
fi
|
||
|
||
sleep 1
|
||
echo
|
||
echo "============================================================"
|
||
echo "Туннель $WG_IF поднят: $CLIENT_IP → $VPS_ENDPOINT"
|
||
echo "Конфиг: $CONF"
|
||
echo "Init: $INIT {start|stop|restart|status}"
|
||
echo
|
||
ip -4 -o addr show "$WG_IF" 2>/dev/null | sed 's/^/ /'
|
||
wg show "$WG_IF" 2>/dev/null | sed 's/^/ /'
|
||
echo
|
||
VPS_IP="$(echo "$VPS_ENDPOINT" | cut -d: -f1)"
|
||
SERVER_TUN_IP="$(echo "$WG_SUBNET" | sed 's|0/24$|1|')"
|
||
echo "Проверка: ping -c 2 $SERVER_TUN_IP"
|
||
ping -c 2 -W 2 "$SERVER_TUN_IP" 2>/dev/null | sed 's/^/ /' || echo " (ping не прошёл — проверьте VPS firewall: ufw allow 51820/udp)"
|
||
echo
|
||
echo "Теперь с VPS ($VPS_IP) роутер доступен по адресу: $CLIENT_IP"
|
||
echo "Например, веб-панель: http://$CLIENT_IP:2001"
|
||
echo "============================================================"
|