<===

ProNotes

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)   
← Previous
Back to list