<===
2026-03-01 13:44:05
Ниже минимальный «первый вариант»: один bash‑скрипт, который поднимает TUN‑VPN через `ssh -w`, даёт адреса, включает NAT на сервере и делает default route на клиенте. [wiki.archlinux](https://wiki.archlinux.org/title/VPN_over_SSH)
***
## Предпосылки
На **сервере** (Debian 12, от root, один раз):
```bash
# /etc/ssh/sshd_config
PermitTunnel point-to-point
# опционально, но полезно
AllowTcpForwarding yes
```
Перезапуск:
```bash
systemctl restart ssh
```
***
## Скрипт: клиент + сервер
Сохрани, например, как `ssh-vpn.sh` на КЛИЕНТЕ (Manjaro), сделай `chmod +x ssh-vpn.sh` и запускай от root (`sudo ./ssh-vpn.sh up` / `down`). [git.sr](https://git.sr.ht/~greenfoo/vpn_over_ssh)
```bash
#!/usr/bin/env bash
# Простой TUN‑VPN поверх SSH: client <-> VPS
# режим: ./ssh-vpn.sh up | ./ssh-vpn.sh down
set -e
### НАСТРОЙКИ ###
SERVER_HOST="vps.example.com" # IP/дomen VPS
SERVER_USER="root" # юзер на сервере (нужен root/cap_net_admin)
SSH_PORT=22
TUN_ID=0 # tunX на обеих сторонах
CLI_TUN_IP="10.10.10.2" # IP клиента в VPN
SRV_TUN_IP="10.10.10.1" # IP сервера в VPN
VPN_NET="10.10.10.0/24" # сеть VPN (для NAT)
SRV_WAN_IF="eth0" # внешний интерфейс сервера (замени!)
SSH_OPTS="-p ${SSH_PORT} -o ServerAliveInterval=60 -o ServerAliveCountMax=3"
### ФУНКЦИИ ###
up_client_cfg() {
# addr/route на клиенте
ip addr add "${CLI_TUN_IP}/32" peer "${SRV_TUN_IP}" dev "tun${TUN_ID}" || true
ip link set "tun${TUN_ID}" up
# сохранить старый default (для down)
ip route show default > /run/ssh-vpn.old_default 2>/dev/null || true
# новый default через VPN
ip route replace default via "${SRV_TUN_IP}" dev "tun${TUN_ID}"
}
down_client_cfg() {
# вернуть старый default (если сохраняли)
if [ -s /run/ssh-vpn.old_default ]; then
# тупой restore: удалить текущий default и вернуть старый
ip route del default || true
while read -r line; do
ip route add $line || true
done < /run/ssh-vpn.old_default
rm -f /run/ssh-vpn.old_default
fi
ip link set "tun${TUN_ID}" down || true
ip addr del "${CLI_TUN_IP}/32" peer "${SRV_TUN_IP}" dev "tun${TUN_ID}" 2>/dev/null || true
}
up_server_cfg() {
ssh ${SSH_OPTS} "${SERVER_USER}@${SERVER_HOST}" bash -s <<EOF
set -e
ip addr add "${SRV_TUN_IP}/32" peer "${CLI_TUN_IP}" dev "tun${TUN_ID}" || true
ip link set "tun${TUN_ID}" up
# включаем форвардинг
sysctl -w net.ipv4.ip_forward=1 >/dev/null
# NAT для VPN‑сети через внешний интерфейс
iptables -t nat -C POSTROUTING -s "${VPN_NET}" -o "${SRV_WAN_IF}" -j MASQUERADE 2>/dev/null \
|| iptables -t nat -A POSTROUTING -s "${VPN_NET}" -o "${SRV_WAN_IF}" -j MASQUERADE
EOF
}
down_server_cfg() {
ssh ${SSH_OPTS} "${SERVER_USER}@${SERVER_HOST}" bash -s <<EOF
set -e
ip link set "tun${TUN_ID}" down || true
ip addr del "${SRV_TUN_IP}/32" peer "${CLI_TUN_IP}" dev "tun${TUN_ID}" 2>/dev/null || true
iptables -t nat -D POSTROUTING -s "${VPN_NET}" -o "${SRV_WAN_IF}" -j MASQUERADE 2>/dev/null || true
EOF
}
start_ssh_tunnel() {
# поднимаем SSH‑туннель с TUN с обеих сторон
# -f отправляет ssh в фон, -w TUN_ID:TUN_ID создаёт tunX на обеих концах
ssh ${SSH_OPTS} -f -w "${TUN_ID}:${TUN_ID}" "${SERVER_USER}@${SERVER_HOST}" \
"sleep 999999" # просто держим сессию живой
}
stop_ssh_tunnel() {
# глушим все ssh с -w к этому хосту (грубо, но просто)
pkill -f "ssh .* -w ${TUN_ID}:${TUN_ID} .*${SERVER_HOST}" 2>/dev/null || true
}
### MAIN ###
case "$1" in
up)
echo "[*] Старт SSH‑VPN..."
start_ssh_tunnel
sleep 1
up_server_cfg
up_client_cfg
echo "[+] VPN поднят. Проверка: ping ${SRV_TUN_IP}"
;;
down)
echo "[*] Остановка SSH‑VPN..."
down_client_cfg
down_server_cfg
stop_ssh_tunnel
echo "[+] VPN остановлен."
;;
*)
echo "Usage: $0 {up|down}"
exit 1
;;
esac
```
***
## Пояснения по ключевым местам
- `PermitTunnel point-to-point` в `sshd_config` разрешает создавать TUN‑интерфейсы через `ssh -w`. [backreference](https://backreference.org/2009/11/13/openssh-based-vpns/index.html)
- `ssh -w "${TUN_ID}:${TUN_ID}"` создаёт `tun${TUN_ID}` на клиенте и на сервере, по ним пойдут IP‑пакеты. [gist.github](https://gist.github.com/tjunussov/284cc843c88a670e6bb9cb325370b7c9)
- `ip addr add CLI_TUN_IP/32 peer SRV_TUN_IP` делает p2p‑линк (точка‑точка) между двумя TUN‑концами. [std](https://std.rocks/vpn_ssh.html)
- `iptables -t nat -A POSTROUTING -s VPN_NET -o SRV_WAN_IF -j MASQUERADE` даёт клиенту выход в интернет с адреса сервера (как в классическом VPN). [perplexity](https://www.perplexity.ai/search/1a2d4421-64e9-4381-90a4-5aa2c63e6bd0)
- `ip route replace default via SRV_TUN_IP dev tunX` делает VPN дефолтным маршрутом на клиенте. [debian-fr](https://www.debian-fr.org/t/jai-cree-un-vpn-avec-ssh-et-interface-tun-mais-que-peut-on-faire-avec/91153)
############################
Через SSH можно наколбасить несколько разных «VPN‑подобных» схем — от полного TUN/TAP до «бедняцкого VPN» без root. [ssh](https://www.ssh.com/academy/ssh/tunneling)
## 1. L3 TUN‑VPN (то, что уже обсудили)
- `ssh -w` + `tun` (IP point‑to‑point, L3). [github](https://github.com/openssh/openssh-portable/blob/master/README.tun)
- Даёт `tunX` на клиенте и сервере, маршруты, NAT на сервере, default route на клиенте — классический IP‑VPN. [backreference](https://backreference.org/2009/11/13/openssh-based-vpns/index.html)
- Можно автоматизировать через `Tunnel point-to-point`/`TunnelDevice` в `~/.ssh/config`. [backreference](https://backreference.org/tag/tun/index.html)
## 2. L2 TAP/bridge через SSH
- Вместо TUN можно использовать TAP/bridge, если ОС позволяет (tap‑dev, Ethernet‑кадры). [github](https://github.com/openssh/openssh-portable/blob/master/README.tun)
- Схема: `tapX` на обеих сторонах, на одной стороне TAP бриджится с физическим Ethernet, получается почти «одна L2‑сеть» через SSH. [backreference](https://backreference.org/2009/11/13/openssh-based-vpns/index.html)
- Удобно, если нужно прокинуть DHCP, multicast, любые не‑IP протоколы, но оверхед больше и сложнее настройка.
## 3. sshuttle / transparent proxy «poor man’s VPN»
- Инструмент `sshuttle` делает прозрачный VPN‑like туннель поверх обычного SSH, без `tunX`. [linuxconfig](https://linuxconfig.org/sshuttle-a-vpn-like-tool-for-secure-traffic-routing)
- Пример:
```bash
sshuttle -r user@server 0/0 --dns
```
Всё TCP (и DNS) гонится через SSH; root нужен только локально, на сервере достаточно обычного SSH‑доступа. [github](https://github.com/sshuttle/sshuttle)
- Плюсы: минимум конфигурации, обход многих DPI/файрволов; минусы: только TCP/частично UDP, завязка на iptables/iptables‑подобные хаки. [linuxconfig](https://linuxconfig.org/sshuttle-a-vpn-like-tool-for-secure-traffic-routing)
## 4. Полный трафик через динамический SOCKS (ssh -D + tun2socks)
- `ssh -D` поднимает SOCKS5, дальше `tun2socks`/`redsocks` делают TUN‑интерфейс и гонят его трафик через SOCKS. [github](https://github.com/sshuttle/sshuttle)
- По сути:
- `ssh -D 1080 user@server`
- `tun2socks --tundev tun0 --net 10.0.0.0/24 --socks-server 127.0.0.1:1080`
- default route через `tun0`.
- Это обходной путь, когда `PermitTunnel` на сервере нельзя трогать, но SSH+TCP открыт.
## 5. Простой порт‑форвардинг как частичный VPN
- Локальный, удалённый и динамический форвардинг:
- `ssh -L` — проброс нужных портов (RDP, HTTP, БД и т.п.) в приватную сеть. [linuxize](https://linuxize.com/post/how-to-setup-ssh-tunneling/)
- `ssh -R` — дать удалённой стороне доступ назад в твою сеть по выбранному порту. [ssh](https://www.ssh.com/academy/ssh/tunneling)
- `ssh -D` — SOCKS‑прокси, который можно использовать как VPN только для приложений, умеющих SOCKS. [linuxize](https://linuxize.com/post/how-to-setup-ssh-tunneling/)
- Это не полный VPN, но покрывает 80% задач типа «достучаться до внутренней услуги» или «прячем только браузер».
## 6. OpenVPN/WireGuard поверх SSH‑туннеля
- Если DPI гнобит OpenVPN/WG, можно завернуть их в SSH:
- `ssh -L 1194:real-vpn-server:1194 user@gateway` и на клиенте OpenVPN/WG подключается к `127.0.0.1:1194`. [backreference](https://backreference.org/tag/tunnel/index.html)
- Так SSH работает как «обфускация/транспорт» для нормального VPN, а управление маршрутами — на самом OpenVPN/WG.
## 7. Многоскачковый VPN через SSH ProxyCommand
- `ProxyCommand`/`ProxyJump` позволяют строить цепочки: клиент → bastion → dmz → vpn‑gw, и уже там поднимается TUN или sshuttle. [backreference](https://backreference.org/tag/tunnel/index.html)
- Пример: в `~/.ssh/config` описывается `Host gw` с `ProxyCommand ssh bastion nc gw 22`, и TUN/sshuttle используют этот хост как конечный. [github](https://github.com/openssh/openssh-portable/blob/master/README.tun)
Back to list