Expertus metuit
SOCKS-прокси через SSH
Опубликовано 2013-05-13 в 18:15

В SSH есть крайне полезная фича, позволяющая организовать прозрачный проброс трафика через практически любой SSH-сервер. Принцип туннелирования простой: подключаемся к ssh-серверу со специальными опциями и получаем SOCKS-прокси, висящий на указанном в опциях порту локальной машины. Что самое приятное — на удалённой машине не надо ставить никакой софт, плюс необязательно быть суперпользователем, достаточно обычного аккаунта.

Дальше я детально опишу сценарий настройки и конфигурации такой системы.

Все команды для «запуска» серверов мы будем делать из терминала, используя стандартный для linux-машины клиент ssh.

Допустим, у нас есть виртуалка в США с адресом us-vps.example.com и мы хотим использовать её в качестве прокси. Всё что для этого нужно — это запустить вот такую команду:

$ ssh -D 127.0.0.1:4000 [email protected]

После установки соединения мы получим работающий SOCKS-прокси на адресе 127.0.0.1 и порту 4000, эти данные мы можем указать в настройках, например, браузера и дальше весь трафик из него пойдёт через удалённую машину. Сразу и http, и https.

Однако каждый раз набирать такие команды, вводить пароль не очень эффективно, поэтому мы процесс оптимизируем. Вот вкратце, что сделаем:

  1. На удалённом сервере создадим выделенного пользователя, специально для туннеля.
  2. Будем использовать ключи вместо паролей.
  3. Вместо полного адреса, пользователя, адреса, порта будем использовать алиас (псевдоним).

Сначала создадим пользователя на удалённом сервере, пароль ему можно задать посложнее, всё равно он не будет использоваться для аутентификации. Я у себя такого пользователя назвал tunnel.

Дальше создаём отдельный ssh-ключик, который у нас будет использоваться только для туннелей; если вас это не напрягает, пароль для ключа можно не указывать:

$ ssh-keygen -f ~/.ssh/id_rsa-TUNNEL

Эта команда создаст в каталоге ~/.ssh пару из публичного и приватного ключа. Эту пару мы будем использовать для подключения к туннелю, сразу же отправим публичный ключ на удалённый сервер:

$ ssh-copy-id -i ~/.ssh/id_rsa-TUNNEL [email protected]

Вводим пароль, затем убеждаемся, что можем подключиться с использованием этого ключа:

$ ssh -i ~/.ssh/id_rsa-TUNNEL [email protected]

Естественно, каждый раз набирать такие команды никакого удовольствия, поэтому воспользуемся очень полезной фичей ssh-клиента — пользовательским конфигом. Конфиг этот лежит в каталоге ~/.ssh и представляет собой файл с именем config, состоящий из опций конфигурации, полную справку по этим опциям можно прочитать в мане (man ssh_config). В конфиге мы для каждого из наших прокси-серверов создадим алиас, к которому прицепим все нужные для подключения параметры, после чего для «запуска» прокси достаточно будет выполнить команду типа:

$ ssh tunnel-us

Для каждого из серверов нужно в файл ~/.ssh/config добавить блок вот такого типа:

Host tunnel-us
    Hostname us-vps.example.com
    User tunnel
    DynamicForward 127.0.0.1:4000
    IdentityFile ~/.ssh/id_rsa-TUNNEL

Естественно, значения в параметре Host должны быть разные для каждого сервера (это и есть алиасы). Адрес и порт локальной точки должны быть одинаковыми для всех прокси-серверов, это позволит не переконфигурировать каждый раз браузер при переключении прокси, а просто взять закрыть текущую сессию и подключиться к новой.

Картинка-памятка:

ssh tunneling cheat sheet

И небольшое дополнение, как сконвертировать SOCKS5-прокси в HTTP-прокси. Для этого используем проект python-proxy:

$ pip3 install pproxy
$ pproxy -r socks5://127.0.0.1:4000 -vv

По умолчанию HTTP-прокси открывается на порту 8080.

Комментарии

Гость: Консультант | 2015-07-22 в 17:57

Вот кстати такой сервис ssh-vpn-provider.ru

Гость: dobbi | 2019-10-07 в 23:12

А можно как-то на сервере запретить режим socks proxy? (ssh -D) При этом оставляя рабочим wget, curl и т.д.

Sergey Stolyarov | 2019-10-07 в 23:26

Формально можно (через параметр AllowTcpForwarding в sshd_config на стороне сервера), но это при желании можно обойти.

Гость: dobbi | 2019-10-08 в 00:25

Спасибо за ответ, не ожидал (статья старая). А каким образом можно обойти? Специально заморачиваться этим точно никто не будет, пользователи не шибко продвинутые, поэтому если это не "два клика", то не страшно.

Sergey Stolyarov | 2019-10-08 в 09:46

Можно скопировать и запустить специальное приложение, которое через обычный STDIN/STDOUT терминала будет гонять любые данные. Штатным клиентом этого не добиться, нужно свой писать.

Гость: dobbi | 2019-10-08 в 11:39

Будет сложно, пользователи в jail, места откуда можно что-то запускать ограничены и запись туда запрещена, кушайте что есть. Всё понял, спасибо ещё раз.

Текст комментария (допустимая разметка: *курсив*, **полужирная**, [ссылка](http://example.com) или <http://example.com>) Посетители-анонимы, обратите внимение, что более чем одна гиперссылка в тексте (включая оную из поля «веб-сайт») приведёт к блокировке комментария для модерации. Зайдите на сайта с использованием аккаунта на twitter, например, чтобы посылать комментарии без этого ограничения.
Имя (обязательно, 50 символов или меньше)
Опциональный email, на который получать ответы (не будет опубликован)
Веб-сайт
© 2006—2024 Sergey Stolyarov | Работает на pyrengine