Ssh туннель через роутер

Гайд по ssh-туннелированию

1. SSH ТУННЕЛИ: ОРГАНИЗОВЫВАЕМ УДАЛЁННЫЙ ДОСТУП ОДНОЙ КОМАНДОЙ

Для чего всё это нужно?

Каждый системный администратор или сетевой инженер хоть раз в своей практике сталкивался с ситуацией, когда нужно получить доступ из публичной сети Интернет к ресурсам своей рабочей сети, скрытой за NAT и защищённой фаерволом. Конечно, для решения этой задачи можно настроить шифрованный site-to-site туннель или PPTP . Или же воспользоваться сторонним приложением для организации удалённого доступа, например, TeamViewer . Однако есть более простое решение, на реализацию которого уйдет буквально одна минута. К тому же, это решение не требует никакого стороннего программного обеспечения, кроме включённого по умолчанию в 90% Linux/Unix дистрибутивов пакета OpenSSH .

Как это работает?

SSH туннель или SSH Port Forwarding , как его называет man(1) ssh – это опциональный функционал протокола, который работает поверх всем знакомой обычной SSH сессии. SSH туннель позволяет послать TCP пакет с одной стороны SSH соединения на другую его сторону и произвести трансляцию IP заголовка по заранее определенному правилу в процессе передачи.

Понять, как работает SSH туннель очень просто: если представить его в виде point-to-point соединения. Так же, как и в PPP , любой пакет, попавший в один конец соединения, будет передан и получен на другом конце туннеля. Дальше, в зависимости от адреса получателя, заданного в IP заголовке, пакет будет либо обработан принимающей стороной туннеля (если пакет предназначается непосредственно ей), либо смаршрутизирован дальше в сеть (если адресатом является другой узел сети).

Основное отличие SSH туннеля от PPP соединения в том, что в SSH туннель можно завернуть только TCP трафик. (Примечание: есть несколько хаков, как можно передать UDP через TCP -сокет внутри SSH туннеля, но это решение выходит за рамки данной статьи).

Второе отличие состоит в том, что в point-to-point соединении, входящий трафик может быть инициирован с любой стороны, тогда как для SSH туннеля необходимо явно задать «точку входа» для трафика. «Точка входа» – это параметр вида : , указывающий какой сокет открыть для входа в туннель (с локальной или удалённой стороны SSH сессии).

Кроме точки входа дополнительно нужно указать правило вида : , по которому должен быть переписан заголовок (точнее, адрес и порт назначения) TCP пакета в процессе передачи. Точка входа может задаваться с любого конца туннеля. За этот параметр отвечают ключи –L (local) и –R (remote).

Под local и remote подразумеваются стороны туннеля с точки зрения стороны-оригинатора, то есть того хоста, который устанавливает SSH сессию.

Пока выглядит немного запутанно, поэтому давайте разберём на конкретном примере.

Читайте также:  Скорость портов роутера 100

2. ТУННЕЛЬ С ЛОКАЛЬНОЙ ТОЧКОЙ ВХОДА – ОБЕСПЕЧИВАЕМ ДОСТУП К СЕРВЕРУ ЗА NAT

Боб работает системным администратором в маленькой компании Qwerty сakes, занимающейся производством пирогов с капустой. Вся сеть компании находится в одном броадкаст домене 192.168.0.0/24 . Для доступа в интернет используется программный маршрутизатор на базе Linux, адрес которого 192.168.0.1 со стороны сети компании и 1.1.1.1 со стороны сети Интернет. На маршрутизаторе поднят и работает демон OpenSSH , который доступен по сокету 1.1.1.1:22 . Внутри сети на сервере с адресом 192.168.0.2 установлен внутренний корпоративный портал, на котором до завтрашнего утра Бобу нужно сделать изменения через Web интерфейс. Однако Боб не хочет задерживаться на работе допоздна, он хочет получить доступ к порталу из дома со своего домашнего компьютера с адресом 2.2.2.2 .

Боб приходит домой и после ужина устанавливает следующее соединение с маршрутизатором компании:

Что произошло? Боб установил SSH сессию между адресами 2.2.2.2 и 1.1.1.1 , при этом открыв локальную «точку входа» в туннель 127.0.0.1:8080 на своем домашнем компьютере:

bob@Bob-PC:~$ sudo lsof -nPi | grep 8080 ssh 3153 bob 4u IPv4 9862 0t0 TCP 27.0.0.1:8080 (LISTEN)

Любой TCP пакет, который попадёт в сокет 127.0.0.1:8080 со стороны компьютера Боба, будет отправлен по point-to-point соединению внутри сессии SSH , при этом адрес назначения в TCP заголовке будет перезаписан с 127.0.0.1 на 192.168.0.2 , а порт с 8080 на 80. Теперь Бобу, чтобы попасть на портал своей компании, нужно всего лишь набрать в браузере: http://127.0.0.1:8080

Давайте детально разберём, что произошло с TCP пакетом в процессе его прохождения по SSH туннелю:

  • TCP пакет с адресом источника 127.0.0.1 и адресом и портом назначения 127.0.0.1:8080 попал в сокет 127.0.0.1:8080 , открытый процессом ssh ;
  • Процесс ssh получил пакет, в соответствии с правилом трансляции переписал адрес и порт назначения на 192.168.0.2:80 и отправил его внутри SSH сессии удалённой стороне 1.1.1.1 ;
  • Процесс sshd на маршрутизаторе 1.1.1.1 получил пакет и, просмотрев адрес назначения, отправил его хосту 192.168.0.2 , переписав при этом адрес источника с 127.0.0.1 на адрес собственного интерфейса 192.168.0.1 , для того чтобы получатель, который ничего не знает про существование SSH туннеля, вернул пакет роутеру, а не отправил в свой же localhost 127.0.0.1 .
bob@Bob-PC:~$ ssh –L 127.0.0.1:8080:192.0.0.2:80 bob@1.1.1.1

В данном примере, если бы портал или любой другой ресурс, к которому Бобу нужно получить доступ, находился на самом роутере (например, по адресу 192.168.0.1:80 ), то команда выглядела бы следующим образом:

bob@Bob-PC:~$ ssh -L 127.0.0.1:8080:192.0.0.1:80 bob@1.1.1.1

Если сервис доступен по адресу localhost (например, локальный SQL сервер), то и к нему можно получить доступ:

bob@Bob-PC:~$ ssh -L 127.0.0.1:13306:127.0.0.1:3306 bob@1.1.1.1

Конструкции вида -L 127.0.0.1:80:127.0.0.1:80 могут выглядеть, на первый взгляд, довольно странными. Но в них нет ничего сложного, если помнить, что решение о маршрутизации пакета принимается на удалённой стороне туннеля. Нужно помнить основное правило: вторая пара : обрабатывается удалённой стороной туннеля. Поэтому пакет с адресом назначения 127.0.0.1 в правиле трансляции будет обработан второй стороной SSH сессии, и никак иначе. Как вы уже, наверное, догадались, точку входа в туннель можно создавать не только на loopback интерфейсе. Если туннель нужно сделать доступным не только для локального хоста, но и для других участников сети, то в качестве адреса сокета можно указать реальный адрес интерфейса.

bob@Bob-PC:~$ ssh -L 10.0.0.5:8080:192.0.0.2:80 bob@1.1.1.1

Компьютер Боба Bob-PC имеет два сетевых интерфейса с адресами 2.2.2.2 и 10.0.0.5 . В процессе установления сессии ssh откроет сокет 10.0.0.5:8080 на компьютере Bob-PC. Теперь Боб может получить доступ к порталу 192.168.0.2:80 со своего ноутбука с адресом 10.0.0.4 и со всей своей домашней сети 10.0.0.0/24 .

Читайте также:  Мой роутер снижает скорость

3. ТУННЕЛЬ С УДАЛЕННОЙ ТОЧКОЙ ВХОДА – ПУБЛИКУЕМ ЛОКАЛЬНЫЙ СЕРВИС

Как я уже говорил, точку входа в туннель можно открывать не только со стороны оригинатора ssh сессии, но и с удалённой стороны, то есть с той, к которой мы устанавливаем ssh сессию. Для этого вместо параметра -L используется параметр R . Для чего это нужно? Например, для того, чтобы можно было опубликовать локальный сервис для удалённого доступа. На ноутбуке Боба запущен Web сервер apache доступный по адресу 127.0.0.1 с тестовой копией портала компании. Бобу нужно дать доступ к Web серверу своим коллегам для проведения тестирования интерфейса. Вообще, для подобных целей Бобу неплохо было бы реализовать более надёжную тестовую песочницу. Но так как наш Боб не более чем виртуальный персонаж этой статьи, он для демонстрации работы SSH туннеля устанавливает сессию между своим ноутбуком и маршрутизатором Linux. А с помощью параметра -R открывает порт 8080 на внутреннем интерфейсе маршрутизатора с адресом 192.168.0.1 , который ссылается на сокета 127.0.0.1:80 его тестового Web сервера.

Как видите, на маршрутизаторе процесс sshd открыл локальный сокет 8080

bob@Router:~$ sudo lsof -nPi | grep 8080 sshd 17233 bob 9u IPv4 95930 0t0 TCP 192.168.0.1:8080 (LISTEN)

Давайте посмотрим, что произойдёт с TCP пакетом, отправленным с компьютера 192.168.0.200 в сторону тестового портала, опубликованного на 192.168.0.1:8080 :

  • TCP пакет с адресом источника 192.168.0.200 и адресом и портом назначения 192.168.0.1:8080 попадёт в сокет 192.168.0.1:8080 , открытый процессом sshd ;
  • Процесс sshd, получив пакет, в соответствии с правилом трансляции перепишет адрес и порт назначения с 192.168.0.1:8080 на 127.0.0.1:80 и отправит его внутри SSH сессии стороне-оригинатора 2.2.2.2 ;
  • Процесс ssh на ноутбуке Боба, получив пакет и просмотрев адрес его назначения, перепишет адрес отправителя с 192.168.0.200 на адрес своего loopback , и отправит его в локальный сокет 127.0.0.1:80 , открытый процессом apache .

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

Читайте также:  Воруем интернет с роутера

Одно важное замечание, которое я оставил на конец статьи. Если при открытии точки входа в туннель используется localhost вместо адреса реального интерфейса, то его можно опустить, сократив, таким образом, команду с

bob@Bob-PC:~$ ssh -L 127.0.0.1:8080:192.0.0.1:80 bob@1.1.1.1
bob@Bob-PC:~$ ssh -L 8080:192.0.0.1:80 bob@1.1.1.1

Эта важная особенность синтаксиса пригодится нам в следующем примере.

4. ДВОЙНОЕ ТУННЕЛИРОВАНИЕ

Давайте посмотрим на чуть более сложный пример. Пользователю SQL-Tester , находящемуся за NAT , нужно получить доступ к базе данных на SQL сервере, который тоже находится за NAT . SQL-Tester не может установить соединение напрямую к серверу, так как в NAT серверной сети нет соответствующих трансляций. Однако от обоих хостов можно установить SSH сессию с промежуточным сервером 3.3.3.3 .

С SQL сервера устанавливаем SSH соединение с сервером 3.3.3.3 и открываем на loopback интерфейсе сервера 3.3.3.3 порт 13306 , ссылающийся на локальный сервис SQL , запущенный на локальном сокете 127.0.0.1:3306 SQL сервера: dbuser@SQL-server :

~$ ssh -R 13306:127.0.0.1:3306 user1@3.3.3.3

Теперь с клиентского хоста SQL-Tester устанавливаем соединение с 3.3.3.3 и открываем порт 3306 на loopback интерфейсе клиента, который, в свою очередь, ссылается на 127.0.0.1:13306 на сервере 3.3.3.3 , который ссылается на 27.0.0.1:3306 на SQL сервере. Всё просто:

Jtester@SQL-Tester:~$ ssh -L 3306:127.0.0.1:13306 user2@3.3.3.3

5. ТУННЕЛИРОВАНИЕ ЧЕРЕЗ SSHUTTLE

Когда нам требуется пробросить порты сразу к нескольким серверам за NAT , мы можем воспользоваться инструментом sshuttle. Для этого нам потребуется удалённый сервер, доступный по SSH . Допустим, его IP — 1.2.3.4 . Для того чтобы завернуть весь трафик через туннель до этого IP , необходимо выполнить команду:

sshuttle -r root@1.2.3.4 0.0.0.0/0

Это означает, что мы собираемся добавить в нашу таблицу маршрутизации правило, по которому весь исходящий трафик будет отправляться на удалённый сервер, за исключением DNS-запросов. С параметром —dns DNS-запросы также будут направляться на удалённый сервер.

Параметр —daemon можно передать утилите, если мы хотим запустить туннель в фоновом режиме. Если мы хотим использовать тунель только для трафика с определённых IP или для целой подсети, запустить sshuttle можно так:

sshuttle -r root@1.2.3.4 2 2.2.2.0/24

В итоге мы сможем обращаться напрямую, например, к подсети 2.2.2.0/24 , не

пробрасывая нужный порт для каждого хоста. На текущий момент пакет sshuttle удален из стандартного репозитория, но установить его можно самостоятельно. Более подробная информация здесь: https://github.com/sshuttle/sshuttle

6. ЧТО ДЕЛАТЬ ПОЛЬЗОВАТЕЛЯМ MICROSOFT WINDOWS?

Прочитав статью, вы возможно, решите, что все преимущества SSH туннелей доступны только пользователям Unix-like систем. Однако это не так. Практически все терминальные клиенты для Windows работающие по протоколу SSH имеют поддержку туннелирования, например putty , или SecureCRT .

7. ЗАКЛЮЧЕНИЕ

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

Источник

Оцените статью
Adblock
detector