Pull to refresh

VPN за 5 минут на базе SSH туннелей

Приветствую, Хабрачеловеки! Представляю вашему вниманию интересное решение для VPN, не требующего конфигурации со стороны сервера, а так же заморочек с созданием виртуальных интерфейсов, настроек роутинга и прочего. Сразу предупреждаю, статья ориентирована на *nix пользователей, однако принцип должен работать и в Windows.


Я уже давно использую обычные SSH тоннели, типа

$ ssh -L8080:10.0.0.2:80 user@remote-server

(для тех кто в танке не в теме — в этом примере SSH клиент после подключения к серверу поднимает на локальной машине порт 8080, а все подключения к нему пробрасывает на 10.0.0.2:80, находящийся в удаленной сети).

Решение удобно для случаев, когда надо быстро «проковырять дырку» к удаленной машине закрытой файрволлом, имея доступ к SSH на любой другой машине, находящейся той же сети. Или наоборот, для статических сервисов, например периодической синхронизации двух удаленных SQL серверов, где однажды настроил и забыл. Если же нам нужно несколько «дырок», т.е. когда портов и/или адресов несколько, начинается путаница. Можно конечно для каждой удаленной машины ставить свой набор портов, например

localhost:12135 -> 10.0.0.2:135
localhost:12022 -> 10.0.0.2:22
localhost:13135 -> 10.0.0.3:135
...


но ведь это тоже, согласитесь, не совсем красиво. К тому же есть программы, не позволяющие менять порт подключения. Кроме того, если мы хотим использовать какие-то сервисы как в пределах той сети, так и используя такие тоннели, нам придется иметь два набора настроек подключения, например две разные закладки в браузере для transmission web-gui, или конфига database.yml для Ruby on Rails development базы
Как известно, ssh умеет слушать любой адрес на локальной машине, поэтому родилась идея — делать alias-ы на виртуальный локальный сетевой интерфейс (loopback), вот так:

(Mac OS X, *BSD)
$ sudo ifconfig lo0 alias 10.0.0.2
$ sudo ifconfig lo0 alias 10.0.0.3

(Linux)
$ sudo ifconfig lo:1 10.0.0.2
$ sudo ifconfig lo:2 10.0.0.3


а затем поднимать ssh тоннели на них. И это работает!

Так как я использую привилегированные порты, туннель необходимо поднимать из под root. По моему это единственный серьезный минус сей конструкции.
В /var/root/.ssh/config (я использую Mac OS X 10.6, там именно /var/root) настраиваем тоннели:

# своего рода алиас для ssh клиента, через который мы потом будем совершать подключение:
Host home-vpn
HostName <удаленный хост>
# в случае если используем нестандартный порт для sshd на удаленной машине:
Port 1337
# имя пользователя на сервере:
User art
# тоннели:
LocalForward 10.0.0.1:80 10.0.0.1:80
LocalForward 10.0.0.1:443 10.0.0.1:443

LocalForward 10.0.0.2:22 10.0.0.2:22
LocalForward 10.0.0.2:548 10.0.0.2:548
# к сожалению Mac-овский Screen Sharing не разрешает подключатся к адресу, который
# слушает lo0 стандартному порту VNC, не нашел как убрать эту проверку, видимо hardcoded,
# пришлось все таки использовать нестандартный порт
LocalForward 10.0.0.2:5901 10.0.0.2:5900
LocalForward 10.0.0.2:31337 10.0.0.2:31337

LocalForward 10.0.0.3:22 10.0.0.4:22
LocalForward 10.0.0.3:548 10.0.0.4:548
LocalForward 10.0.0.3:3000 10.0.0.4:3000
LocalForward 10.0.0.3:5432 10.0.0.4:5432


Для поднятия тоннелей я использую тупейший скриптик (для MacOS / BSD):

#!/bin/sh
sudo ifconfig lo0 alias 10.0.0.1 &&
sudo ifconfig lo0 alias 10.0.0.2 &&
sudo ifconfig lo0 alias 10.0.0.3 &&

sudo ssh home-vpn;

sudo ifconfig lo0 -alias 10.0.0.1;
sudo ifconfig lo0 -alias 10.0.0.2;
sudo ifconfig lo0 -alias 10.0.0.3;

В случае если ssh отваливается, алиасы удаляются.

Добавляем в /etc/hosts записи для наших удаленных серверов:


10.0.0.1 poseidon
10.0.0.2 aquamac
10.0.0.3 aquabuntu

и в дальнейшем сможем использовать эти имена как локально, так и через наш VPN. Соответственно, нам не надо несколько настроек для каждой проги.

Для Windows честно говоря не проверял, но поидее должно работать по тому же принципу.

Только потребуется сначала установить loopback интерфейс, прописать на него нужные адреса,
а затем поднять тоннели с помощью Putty -> SSH -> tunnels (или другого ssh клиента)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.