mirror of
https://github.com/andrey271192/keenetic_ssh-web.git
synced 2026-09-20 14:42:01 +00:00
tunnel: WireGuard VPS↔роутер для серых IP, без правки других сервисов
Решает доступ к роутеру с серым IP через белый VPS — поднимаем WG-туннель (UDP 51820, подсеть 10.99.0.0/24), и любой сервис на VPS обращается к роутеру по 10.99.0.X. SSH, HTTP, что угодно — без проброса портов и без изменений в keenetic_ssh-web/keenetic-unified/Domain Hydra/etc. Что добавлено: - tunnel/server-install.sh — установка WG-сервера на Ubuntu VPS, генерация ключей, запуск wg-quick@wg0, открытие 51820/udp в ufw. - tunnel/kssh-tun — утилита управления peer-ами на VPS: add/list/show/remove. add генерит ключи и IP, печатает ENV-блок с одной командой для роутера. - tunnel/tunnel-install.sh — клиент для роутера (Entware), принимает 4 ENV (VPS_ENDPOINT/VPS_PUBKEY/CLIENT_IP/CLIENT_PRIVKEY), ставит wireguard-tools, поднимает wg0 и init-скрипт автозапуска. - tunnel/README.md — пошаговая инструкция массовой установки. - README.md: краткая ссылка из основного раздела. Параметры подсети/порта/имени репо — через ENV для масштабной установки.
This commit is contained in:
21
README.md
21
README.md
@@ -198,6 +198,27 @@ KEEP_DATA=1 ./uninstall.sh
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Удалённый доступ через VPS (туннель WireGuard)
|
||||||
|
|
||||||
|
Если у роутера **серый IP**, а нужно дотянуться до панели/SSH с интернета — поднимите WireGuard-туннель: см. [tunnel/README.md](tunnel/README.md).
|
||||||
|
|
||||||
|
Кратко:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# На VPS (Ubuntu) — один раз
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/andrey271192/keenetic_ssh-web/main/tunnel/server-install.sh | sudo sh
|
||||||
|
|
||||||
|
# На VPS — для каждого роутера
|
||||||
|
sudo kssh-tun add router-XYZ
|
||||||
|
# → выводит готовую команду с 4 ENV для роутера
|
||||||
|
|
||||||
|
# На роутере — копируете эту команду и выполняете
|
||||||
|
```
|
||||||
|
|
||||||
|
После этого с VPS роутер доступен по `10.99.0.X:любой-порт`. Никаких изменений в `keenetic_ssh-web` и других сервисах не требуется.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Связанные проекты
|
## Связанные проекты
|
||||||
|
|
||||||
- [keenetic-unified](https://github.com/andrey271192/keenetic-unified) — мониторинг и управление с **VPS** по SSH (нужен «белый» IP на WAN для SSH).
|
- [keenetic-unified](https://github.com/andrey271192/keenetic-unified) — мониторинг и управление с **VPS** по SSH (нужен «белый» IP на WAN для SSH).
|
||||||
|
|||||||
168
tunnel/README.md
Normal file
168
tunnel/README.md
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
# tunnel/ — WireGuard-туннель VPS ↔ роутер
|
||||||
|
|
||||||
|
Решает задачу: у вас на роутере **серый IP** (нет публичного), но есть **VPS с белым IP**. Поднимаем WireGuard, и любой сервис на VPS обращается к роутеру по адресу из туннельной подсети (`10.99.0.X`), как если бы они были в одной LAN. SSH, HTTP, что угодно — без проброса портов и без переписывания других сервисов (`Domain Hydra`, `keenetic-unified`, `keenetic_ssh-web`, …).
|
||||||
|
|
||||||
|
```
|
||||||
|
[VPS, белый IP] [Роутер, серый IP]
|
||||||
|
:443 Caddy/Nginx → wg0 10.99.0.1 ⇄ wg0 10.99.0.X → 127.0.0.1:2001 (kssh-web)
|
||||||
|
127.0.0.1:22 (SSH)
|
||||||
|
…и т. д.
|
||||||
|
```
|
||||||
|
|
||||||
|
UDP `51820`, подсеть `10.99.0.0/24`. Параметры можно поменять через ENV.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. На VPS (Ubuntu) — один раз
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/andrey271192/keenetic_ssh-web/main/tunnel/server-install.sh | sudo sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Что делает:
|
||||||
|
|
||||||
|
- `apt install wireguard wireguard-tools curl`
|
||||||
|
- генерит серверные ключи (`/etc/wireguard/server_{private,public}.key`)
|
||||||
|
- создаёт `/etc/wireguard/wg0.conf` (UDP 51820, IP `10.99.0.1/24`)
|
||||||
|
- ставит утилиту `kssh-tun` в `/usr/local/bin/`
|
||||||
|
- открывает `51820/udp` в `ufw`, если он активен
|
||||||
|
- запускает `wg-quick@wg0` и ставит на автозапуск (`systemctl enable`)
|
||||||
|
|
||||||
|
В конце выводит:
|
||||||
|
|
||||||
|
```
|
||||||
|
Endpoint: <PUBLIC_IP>:51820/udp
|
||||||
|
PublicKey: <SERVER_PUB>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. На VPS — добавление каждого роутера
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo kssh-tun add router-andrey-1
|
||||||
|
```
|
||||||
|
|
||||||
|
Утилита:
|
||||||
|
|
||||||
|
- генерит пару ключей клиента
|
||||||
|
- выделяет следующий свободный IP в подсети (`10.99.0.2`, `10.99.0.3`, …)
|
||||||
|
- сохраняет peer-файл в `/etc/wireguard/peers/<name>.peer`
|
||||||
|
- регенерирует `wg0.conf` и применяет без рестарта (`wg syncconf`)
|
||||||
|
- **печатает готовую команду для роутера** — четыре `ENV=…` + `curl …` одной портянкой
|
||||||
|
|
||||||
|
Дополнительно:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo kssh-tun list # список peer-ов
|
||||||
|
sudo kssh-tun show router-andrey-1 # повторно вывести ENV-блок
|
||||||
|
sudo kssh-tun remove router-andrey-1 # удалить peer
|
||||||
|
sudo kssh-tun status # wg show wg0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. На роутере (Keenetic + Entware)
|
||||||
|
|
||||||
|
Скопируйте блок из `kssh-tun add` и выполните на роутере. Пример (значения подставит `kssh-tun add`):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
VPS_ENDPOINT=SERVER_IP:51820 \
|
||||||
|
VPS_PUBKEY='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=' \
|
||||||
|
CLIENT_IP=10.99.0.5 \
|
||||||
|
CLIENT_PRIVKEY='yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy=' \
|
||||||
|
sh -c "curl -fsSL https://raw.githubusercontent.com/andrey271192/keenetic_ssh-web/main/tunnel/tunnel-install.sh | sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
Что делает:
|
||||||
|
|
||||||
|
- `opkg install wireguard-tools` (если ещё нет)
|
||||||
|
- пишет `/opt/etc/wireguard/wg0.conf`
|
||||||
|
- поднимает интерфейс `wg0` с адресом `CLIENT_IP/24`
|
||||||
|
- маршрутизирует `10.99.0.0/24` через `wg0`
|
||||||
|
- ставит init-скрипт `/opt/etc/init.d/S50kssh-tunnel` ({start|stop|restart|status}) и rc.d-симлинк автозапуска
|
||||||
|
- в конце пингует `10.99.0.1` (VPS) для проверки
|
||||||
|
|
||||||
|
Если ping не прошёл — почти всегда дело в фаерволе VPS: `sudo ufw allow 51820/udp` (или эквивалент для iptables/firewalld).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Использование туннеля
|
||||||
|
|
||||||
|
После запуска любые сервисы на VPS обращаются к роутеру по `10.99.0.X`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# С VPS — веб-панель keenetic_ssh-web
|
||||||
|
curl http://10.99.0.5:2001/
|
||||||
|
|
||||||
|
# SSH на роутер с VPS (если у роутера включён SSH)
|
||||||
|
ssh root@10.99.0.5
|
||||||
|
|
||||||
|
# Reverse-proxy на VPS: keenetic.example.com → http://10.99.0.5:2001
|
||||||
|
# (Caddy/Nginx — прозрачно)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Параметры (ENV)
|
||||||
|
|
||||||
|
### `server-install.sh`
|
||||||
|
|
||||||
|
| Переменная | По умолчанию | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `WG_PORT` | `51820` | UDP-порт сервера. |
|
||||||
|
| `WG_SUBNET_PREFIX` | `10.99.0` | Первые три октета подсети `/24`. |
|
||||||
|
| `WG_SERVER_LAST_OCTET` | `1` | Последний октет адреса сервера в туннеле. |
|
||||||
|
| `KSSH_REPO` | `andrey271192/keenetic_ssh-web` | Репо, из которого ставить `kssh-tun` и `tunnel-install.sh`. |
|
||||||
|
| `KSSH_BRANCH` | `main` | Ветка. |
|
||||||
|
|
||||||
|
### `tunnel-install.sh` (на роутере)
|
||||||
|
|
||||||
|
| Переменная | Обязательная | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `VPS_ENDPOINT` | да | `<публичный IP>:<порт>`, UDP. |
|
||||||
|
| `VPS_PUBKEY` | да | PublicKey сервера. |
|
||||||
|
| `CLIENT_IP` | да | IP роутера в туннельной подсети, например `10.99.0.5`. |
|
||||||
|
| `CLIENT_PRIVKEY` | да | PrivateKey роутера (выдаёт `kssh-tun add`). |
|
||||||
|
| `WG_IF` | `wg0` | Имя интерфейса. |
|
||||||
|
| `WG_SUBNET` | `10.99.0.0/24` | AllowedIPs клиента (что маршрутизировать в туннель). |
|
||||||
|
| `WG_KEEPALIVE` | `25` | `PersistentKeepalive` в секундах (нужен из-за NAT провайдера). |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Безопасность
|
||||||
|
|
||||||
|
- WireGuard сам по себе шифрует трафик; но peer-файлы (`/etc/wireguard/peers/*.peer`) содержат **приватные ключи клиентов** в открытом виде — храните VPS чистым.
|
||||||
|
- Закройте `tunnel-install.sh`-команду от посторонних (там есть `CLIENT_PRIVKEY`). В Telegram/мессенджеры лучше не пересылать.
|
||||||
|
- `kssh-tun show <name>` всегда покажет ENV-блок снова — пароль не нужен, повторно сгенерировать ключ не получится. Если ключ утёк — `remove` и заново `add`.
|
||||||
|
- На стороне роутера `tunnel-install.sh` пишет конфиг в `/opt/etc/wireguard/wg0.conf` с правами `600`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Удаление
|
||||||
|
|
||||||
|
На VPS:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo kssh-tun remove <name> # для каждого клиента
|
||||||
|
sudo systemctl disable --now wg-quick@wg0
|
||||||
|
sudo apt remove --purge wireguard wireguard-tools
|
||||||
|
sudo rm -rf /etc/wireguard /usr/local/bin/kssh-tun
|
||||||
|
```
|
||||||
|
|
||||||
|
На роутере:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
/opt/etc/init.d/S50kssh-tunnel stop
|
||||||
|
rm -f /opt/etc/rc.d/S50kssh-tunnel /opt/etc/init.d/S50kssh-tunnel
|
||||||
|
rm -rf /opt/etc/wireguard
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что не входит в этот туннель
|
||||||
|
|
||||||
|
- **NAT с роутера в интернет через VPS**. Здесь VPS лишь видит роутер; чтобы роутер выходил в интернет через VPS, на сервере нужен `MASQUERADE` и `ip_forward`. Не наша цель.
|
||||||
|
- **Доступ из VPS в LAN роутера** (`192.168.1.0/24`). Если нужно — расширьте `AllowedIPs` peer-а на стороне сервера и включите `ip_forward` на роутере.
|
||||||
|
|
||||||
|
В обоих случаях скажите — добавлю в установщик ENV-флаги.
|
||||||
169
tunnel/kssh-tun
Executable file
169
tunnel/kssh-tun
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# kssh-tun — управление peer-ами WireGuard-сервера для keenetic_ssh-web tunnel.
|
||||||
|
# Установлен через tunnel/server-install.sh в /usr/local/bin/kssh-tun.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ENV_FILE="/etc/wireguard/.kssh-tun.env"
|
||||||
|
[ -f "$ENV_FILE" ] || { echo "Сервер не инициализирован. Запустите server-install.sh." >&2; exit 1; }
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$ENV_FILE"
|
||||||
|
|
||||||
|
PEERS_DIR="$WG_DIR/peers"
|
||||||
|
CONF="$WG_DIR/$WG_IF.conf"
|
||||||
|
|
||||||
|
require_root() {
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then echo "Нужны права root (sudo)." >&2; exit 1; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
regen_conf() {
|
||||||
|
umask 077
|
||||||
|
TMP="$(mktemp)"
|
||||||
|
cat > "$TMP" <<EOF
|
||||||
|
[Interface]
|
||||||
|
Address = $WG_SERVER_CIDR
|
||||||
|
ListenPort = $WG_PORT
|
||||||
|
PrivateKey = $(cat "$WG_DIR/server_private.key")
|
||||||
|
SaveConfig = false
|
||||||
|
|
||||||
|
EOF
|
||||||
|
if [ -d "$PEERS_DIR" ]; then
|
||||||
|
for f in "$PEERS_DIR"/*.peer; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
( . "$f"
|
||||||
|
cat <<EOF >> "$TMP"
|
||||||
|
# peer: $NAME ($CLIENT_IP)
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $CLIENT_PUB
|
||||||
|
AllowedIPs = $CLIENT_IP/32
|
||||||
|
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
install -m 600 "$TMP" "$CONF"
|
||||||
|
rm -f "$TMP"
|
||||||
|
if ip link show "$WG_IF" >/dev/null 2>&1; then
|
||||||
|
wg syncconf "$WG_IF" <(wg-quick strip "$WG_IF") 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
next_ip() {
|
||||||
|
USED="$WG_SERVER_IP"
|
||||||
|
if [ -d "$PEERS_DIR" ]; then
|
||||||
|
for f in "$PEERS_DIR"/*.peer; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
ip=$(. "$f"; echo "$CLIENT_IP")
|
||||||
|
USED="$USED $ip"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
for i in $(seq 2 254); do
|
||||||
|
candidate="${WG_SUBNET_PREFIX}.$i"
|
||||||
|
case " $USED " in *" $candidate "*) ;; *) echo "$candidate"; return 0;; esac
|
||||||
|
done
|
||||||
|
echo "Нет свободного IP в подсети ${WG_SUBNET_PREFIX}.0/24" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
print_env_block() {
|
||||||
|
PEER_FILE="$1"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$PEER_FILE"
|
||||||
|
SERVER_PUB=$(cat "$WG_DIR/server_public.key")
|
||||||
|
PUB_IP="$(curl -s4 -m 3 ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')"
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo "Peer '$NAME' → $CLIENT_IP. Скопируйте на роутер ОДНОЙ командой:"
|
||||||
|
echo
|
||||||
|
cat <<EOF
|
||||||
|
VPS_ENDPOINT=$PUB_IP:$WG_PORT \\
|
||||||
|
VPS_PUBKEY='$SERVER_PUB' \\
|
||||||
|
CLIENT_IP=$CLIENT_IP \\
|
||||||
|
CLIENT_PRIVKEY='$CLIENT_PRIV' \\
|
||||||
|
sh -c "curl -fsSL https://raw.githubusercontent.com/${KSSH_REPO}/${KSSH_BRANCH}/tunnel/tunnel-install.sh | sh"
|
||||||
|
EOF
|
||||||
|
echo "============================================================"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd="${1:-}"
|
||||||
|
shift || true
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
add)
|
||||||
|
require_root
|
||||||
|
NAME="${1:-}"
|
||||||
|
[ -z "$NAME" ] && { echo "usage: kssh-tun add <name>" >&2; exit 1; }
|
||||||
|
case "$NAME" in *[!a-zA-Z0-9_-]*) echo "Имя: только [a-zA-Z0-9_-]" >&2; exit 1;; esac
|
||||||
|
mkdir -p "$PEERS_DIR"
|
||||||
|
PEER_FILE="$PEERS_DIR/$NAME.peer"
|
||||||
|
if [ -f "$PEER_FILE" ]; then
|
||||||
|
echo "Peer '$NAME' уже существует — повторно вывожу ENV-блок:"
|
||||||
|
else
|
||||||
|
umask 077
|
||||||
|
CLIENT_IP="$(next_ip)"
|
||||||
|
CLIENT_PRIV="$(wg genkey)"
|
||||||
|
CLIENT_PUB="$(echo "$CLIENT_PRIV" | wg pubkey)"
|
||||||
|
cat > "$PEER_FILE" <<EOF
|
||||||
|
NAME="$NAME"
|
||||||
|
CLIENT_IP="$CLIENT_IP"
|
||||||
|
CLIENT_PRIV="$CLIENT_PRIV"
|
||||||
|
CLIENT_PUB="$CLIENT_PUB"
|
||||||
|
EOF
|
||||||
|
chmod 600 "$PEER_FILE"
|
||||||
|
regen_conf
|
||||||
|
echo "Добавлен: $NAME → $CLIENT_IP"
|
||||||
|
fi
|
||||||
|
print_env_block "$PEER_FILE"
|
||||||
|
;;
|
||||||
|
list)
|
||||||
|
if [ ! -d "$PEERS_DIR" ]; then echo "(нет peer-ов)"; exit 0; fi
|
||||||
|
printf "%-30s %s\n" "NAME" "IP"
|
||||||
|
for f in "$PEERS_DIR"/*.peer; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
( . "$f"; printf "%-30s %s\n" "$NAME" "$CLIENT_IP" )
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
show)
|
||||||
|
NAME="${1:-}"
|
||||||
|
[ -z "$NAME" ] && { echo "usage: kssh-tun show <name>" >&2; exit 1; }
|
||||||
|
PEER_FILE="$PEERS_DIR/$NAME.peer"
|
||||||
|
[ -f "$PEER_FILE" ] || { echo "нет peer-а: $NAME" >&2; exit 1; }
|
||||||
|
print_env_block "$PEER_FILE"
|
||||||
|
;;
|
||||||
|
remove|rm|del)
|
||||||
|
require_root
|
||||||
|
NAME="${1:-}"
|
||||||
|
[ -z "$NAME" ] && { echo "usage: kssh-tun remove <name>" >&2; exit 1; }
|
||||||
|
PEER_FILE="$PEERS_DIR/$NAME.peer"
|
||||||
|
[ -f "$PEER_FILE" ] || { echo "нет peer-а: $NAME" >&2; exit 1; }
|
||||||
|
rm -f "$PEER_FILE"
|
||||||
|
regen_conf
|
||||||
|
echo "Удалён: $NAME"
|
||||||
|
;;
|
||||||
|
_regen)
|
||||||
|
require_root
|
||||||
|
regen_conf
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
if command -v wg >/dev/null 2>&1; then
|
||||||
|
wg show "$WG_IF" 2>/dev/null || echo "(wg-интерфейс $WG_IF не поднят)"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
""|help|-h|--help)
|
||||||
|
cat <<EOF
|
||||||
|
kssh-tun — управление WireGuard-клиентами для keenetic_ssh-web tunnel.
|
||||||
|
|
||||||
|
kssh-tun add <name> добавить peer, вывести ENV-блок для роутера
|
||||||
|
kssh-tun show <name> повторно вывести ENV-блок
|
||||||
|
kssh-tun list список peer-ов
|
||||||
|
kssh-tun remove <name> удалить peer
|
||||||
|
kssh-tun status wg show $WG_IF
|
||||||
|
|
||||||
|
Конфиг: $WG_DIR/$WG_IF.conf (регенерируется автоматически)
|
||||||
|
Peer-файлы: $PEERS_DIR/*.peer
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Неизвестная команда: $cmd. См. kssh-tun help" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
86
tunnel/server-install.sh
Executable file
86
tunnel/server-install.sh
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# tunnel/server-install.sh — установка WireGuard-сервера на Ubuntu VPS.
|
||||||
|
# Поднимает wg0 (UDP 51820, подсеть 10.99.0.0/24) и ставит утилиту kssh-tun
|
||||||
|
# для добавления/удаления клиентов с генерацией ENV-блока для роутера.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WG_PORT="${WG_PORT:-51820}"
|
||||||
|
WG_SUBNET_PREFIX="${WG_SUBNET_PREFIX:-10.99.0}"
|
||||||
|
WG_SERVER_LAST_OCTET="${WG_SERVER_LAST_OCTET:-1}"
|
||||||
|
WG_SERVER_IP="${WG_SUBNET_PREFIX}.${WG_SERVER_LAST_OCTET}"
|
||||||
|
WG_SERVER_CIDR="${WG_SERVER_IP}/24"
|
||||||
|
WG_DIR="/etc/wireguard"
|
||||||
|
WG_IF="wg0"
|
||||||
|
KSSH_REPO="${KSSH_REPO:-andrey271192/keenetic_ssh-web}"
|
||||||
|
KSSH_BRANCH="${KSSH_BRANCH:-main}"
|
||||||
|
RAW="https://raw.githubusercontent.com/${KSSH_REPO}/${KSSH_BRANCH}/tunnel"
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "Запустите через sudo." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> apt: wireguard wireguard-tools curl"
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq wireguard wireguard-tools iproute2 curl
|
||||||
|
|
||||||
|
mkdir -p "$WG_DIR" "$WG_DIR/peers"
|
||||||
|
chmod 700 "$WG_DIR"
|
||||||
|
|
||||||
|
# Серверные ключи (один раз)
|
||||||
|
if [ ! -s "$WG_DIR/server_private.key" ] || [ ! -s "$WG_DIR/server_public.key" ]; then
|
||||||
|
echo "==> Генерация ключей сервера"
|
||||||
|
umask 077
|
||||||
|
wg genkey | tee "$WG_DIR/server_private.key" | wg pubkey > "$WG_DIR/server_public.key"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Сохраняем параметры запуска (используется kssh-tun для регенерации конфига)
|
||||||
|
cat > "$WG_DIR/.kssh-tun.env" <<EOF
|
||||||
|
WG_PORT=$WG_PORT
|
||||||
|
WG_IF=$WG_IF
|
||||||
|
WG_SUBNET_PREFIX=$WG_SUBNET_PREFIX
|
||||||
|
WG_SERVER_IP=$WG_SERVER_IP
|
||||||
|
WG_SERVER_CIDR=$WG_SERVER_CIDR
|
||||||
|
WG_DIR=$WG_DIR
|
||||||
|
KSSH_REPO=$KSSH_REPO
|
||||||
|
KSSH_BRANCH=$KSSH_BRANCH
|
||||||
|
EOF
|
||||||
|
chmod 600 "$WG_DIR/.kssh-tun.env"
|
||||||
|
|
||||||
|
# Установка утилиты kssh-tun (peer management)
|
||||||
|
echo "==> Установка /usr/local/bin/kssh-tun"
|
||||||
|
if [ -f "$(dirname "$0")/kssh-tun" ]; then
|
||||||
|
install -m 755 "$(dirname "$0")/kssh-tun" /usr/local/bin/kssh-tun
|
||||||
|
else
|
||||||
|
curl -fsSL "$RAW/kssh-tun" -o /usr/local/bin/kssh-tun
|
||||||
|
chmod 755 /usr/local/bin/kssh-tun
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Сборка wg0.conf из server-ключа + всех peer-файлов
|
||||||
|
/usr/local/bin/kssh-tun _regen
|
||||||
|
|
||||||
|
# Включить и запустить
|
||||||
|
systemctl enable "wg-quick@${WG_IF}" >/dev/null 2>&1 || true
|
||||||
|
systemctl restart "wg-quick@${WG_IF}"
|
||||||
|
|
||||||
|
# Открыть UDP-порт в UFW, если он активен
|
||||||
|
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q "Status: active"; then
|
||||||
|
ufw allow "${WG_PORT}/udp" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
PUB_IP="$(curl -s4 ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')"
|
||||||
|
SERVER_PUB="$(cat "$WG_DIR/server_public.key")"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo "WireGuard сервер готов."
|
||||||
|
echo " Endpoint: ${PUB_IP}:${WG_PORT}/udp"
|
||||||
|
echo " PublicKey: ${SERVER_PUB}"
|
||||||
|
echo " Server IP: ${WG_SERVER_IP}"
|
||||||
|
echo
|
||||||
|
echo "Добавление клиента (peer):"
|
||||||
|
echo " sudo kssh-tun add <name> # выдаст ENV-блок для роутера"
|
||||||
|
echo " sudo kssh-tun list"
|
||||||
|
echo " sudo kssh-tun show <name>"
|
||||||
|
echo " sudo kssh-tun remove <name>"
|
||||||
|
echo "============================================================"
|
||||||
118
tunnel/tunnel-install.sh
Executable file
118
tunnel/tunnel-install.sh
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
#!/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
|
||||||
|
cat > "$CONF" <<EOF
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = $CLIENT_PRIVKEY
|
||||||
|
Address = $CLIENT_IP/24
|
||||||
|
|
||||||
|
[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
|
||||||
|
wg setconf "\$WG_IF" "\$CONF"
|
||||||
|
ip addr add "\$ADDR" dev "\$WG_IF"
|
||||||
|
ip link set "\$WG_IF" up
|
||||||
|
ip route add "\$SUBNET" dev "\$WG_IF" 2>/dev/null || true
|
||||||
|
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 "============================================================"
|
||||||
Reference in New Issue
Block a user