Expertus metuit
Безопасный ssh-туннель
2016-12-12 13:38

Ранее я уже писал несколько раз об организации ssh-туннелей: SOCKS-прокси через SSH, Туннель через SSH-сервер. В этой статье я расскажу, как максимально безопасно организовать SOCKS-прокси через ssh-туннель.

Обычно, когда делают SOCKS-прокси-туннель, просто добавляют к команде соединения через ssh аргумент типа -D localhost:8008. Потенциально это не очень безопасно по нескольким причинам:

  • вместо авторизации по ключу используется интерактивная авторизация по паролю;
  • на сервере может быть включен X-Forwarding, дыра;
  • авторизация происходит под обычным пользователем в интерактивной сессии.

Интерактивная сессия для туннеля не нужна, более того, если вы позволяете соединяться нескольким клиентам под одним аккаунтом, вы им фактически разрешаете выполнять любые команды на сервере.

Авторизация по паролю также чревата последствиями. Например, если вы хотите разрешить нескольким разным людям подключения с туннелем, вам придётся создать несколько аккаунтов на сервере с разными паролями. Авторизация через ключи решает эту и ещё несколько других проблем.

Также для авторизации для прокси-туннеля можно использовать отдельный ключ с простым паролем, это удобно.

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

Начальные условия:

  • linux-сервер с установленным openssh-server сравнительно актуальной версии;
  • root-доступ к этому серверу;
  • локальный компьютер с linux/macos и терминалом.

Создаём специального системного пользователя для туннеля

На сервере.

Новый юзер будет использоваться только в качестве «туннеля», ему не нужен пароль, однако нужен домашний каталог.

$ sudo adduser --gecos "" --shell /bin/sh --disabled-password tunnel
Adding user `tunnel' ...
Adding new group `tunnel' (1001) ...
Adding new user `tunnel' (1001) with group `tunnel' ...
Creating home directory `/home/tunnel' ...
Copying files from `/etc/skel' ...

Создаём отдельный ssh-ключ для туннеля

На клиентской машине.

Это опциональный шаг, вы можете использовать уже имеющийся ключ. Но на всякий случай тут об этом расскажу, чтобы не искать информацию по другим страницам.

$ ssh-keygen -f ~/.ssh/id_rsa-TUNNEL
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/sigsergv/.ssh/id_rsa-TUNNEL.
Your public key has been saved in /Users/sigsergv/.ssh/id_rsa-TUNNEL.pub.
The key fingerprint is:
SHA256:8tX6AUhejsdaQqwA4vDkUbg/oMN3wtAIgB0aScfKKk8 sigsergv@local
The key's randomart image is:
+---[RSA 2048]----+
|O+*=.            |
|*B++   .         |
|+.*..   + .      |
| =o. . = * .     |
|o.oo  o S B .    |
|=.E+o. o * o     |
|.+. o.  o . .    |
|  .        . .   |
|            .    |
+----[SHA256]-----+

Теперь в файле ~/.ssh/id_rsa-TUNNEL.pub лежит публичный ключ, который мы используем на следующем этапе.

Настраиваем ssh-авторизацию

На сервере.

Сначала базовые шаги:

$ sudo mkdir /home/tunnel/.ssh
$ sudo touch /home/tunnel/.ssh/authorized_keys
$ sudo chown -R tunnel:tunnel /home/tunnel/.ssh
$ sudo chmod 0700 /home/tunnel/.ssh

Теперь нужно отредактировать файл /home/tunnel/.ssh/authorized_keys и прописать туда публичный ssh-ключ с некоторыми дополнительными параметрами. Допустим, публичный ключ лежит в файле ~/.ssh/id_rsa-TUNNEL.pub на локальной машине и имеет вид типа ssh-rsa AAAAB....

Когда добавляется просто ключ в файл authorized_keys, его содержимое выглядит так (это одна строчка, я её для читабельности сократил, в жизни она длиннее):

ssh-rsa AAAAB3Nza...MjI3 sigsergv@local

Опции добавляются перед ключом, в данном случае — перед символами ssh-rsa, для нашей конфигурации опции будут такие (их значение я объясню чуть позже, также помним, что это всё одна строка!):

no-X11-forwarding,no-agent-forwarding,no-pty,command="/bin/true"  AAAAB3Nza...MjI3 sigsergv@local

Опции разделяются запятыми, вот они все с объяснениями (вообще все описаны в man sshd).

no-X11-forwarding
Отключаем X11-forwarding, это нужно сделать обязательно, иначе клиент сможет запустить, например, xterm
no-agent-forwarding
Отключаем перенаправление ssh-agent.
no-pty
Отключаем аллокацию tty (терминала).
command="/bin/true"
Здесь мы задаём команду, которая будет выполняться при старте туннеля и которая не даст юзеру выполнить свою команду.

Создаём файл /home/tunnel/.ssh/rc со следующим содержимым:

echo "Tunnel is active"

По сути это просто сообщение, которое показывается при успешном подключении.

Как подключаться к такому туннелю

На клиентской машине.

Всё как обычно:

$ ssh -i ~/.ssh/id_rsa-TUNNEL -D 127.0.0.1:8000 tunnel@example.com
PTY allocation request failed on channel 1
SSH tunnel session has been started, press CTRL+C to terminate

Туннель (и локальный SOCKS-proxy по адресу 127.0.0.1:8000) будет работать, пока вы не нажмёте Ctrl+C

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

Host tunnel-example
    IdentityFile ~/.ssh/id_rsa-TUNNEL
    Hostname example.com
    DynamicForward 127.0.0.1:8000
    RequestTTY no
    Compression yes
    User tunnel

Теперь для создания туннеля-прокси достаточно набрать команду ssh tunnel-example.

История обновлений

2018-03-14 Уточнены параметры в ~/.ssh/authorized_keys, больше секьюрности. Добавлено упоминание .ssh/rc

Комментарии

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