Files
keenetic_ssh-web/tunnel/tunnel-install.sh
Андрей Бобырев 6fafdce1f3 tunnel: client conf без Address — wg setconf не молчал на этой строке
`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`, печатаем ВНИМАНИЕ — чтобы такая поломка не оставалась
  тихой.
2026-04-26 12:05:45 +03:00

128 lines
5.0 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.

#!/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 "============================================================"