Создание SSH-туннеля. Часть 1 из 4
26.12.2019
Теги: CLI • Linux • SSH • Ubuntu • Windows • Виртуализация • Команда • Конфигурация • Настройка • Сервер
SSH туннель — это туннель, создаваемый посредством SSH соединения и используемый для шифрования туннелированных данных. Используется для того, чтобы обезопасить передачу данных в интернете. Особенность состоит в том, что незашифрованный трафик какого-либо протокола шифруется на одном конце SSH соединения и расшифровывается на другом.
Строго говоря, SSH-туннели не являются полноценными туннелями и это название следует рассматривать как сложившееся в профессиональной среде устойчивое наименование. Официальное название технологии — SSH Port Forwarding — это опциональная возможность протокола SSH, которая позволяет передать TCP-пакет с одной стороны SSH-соединения на другую и произвести в процессе передачи трансляцию IP-заголовка по заранее определенному правилу.
Понять, как работает SSH туннель очень просто: если представить его в виде point-to-point соединения. Так же как и в PPP, любой пакет, попавший в один конец соединения, будет передан и получен на другом конце туннеля. Дальше, в зависимости от адреса получателя, заданного в IP заголовке, пакет будет либо обработан принимающей стороной туннеля (если пакет предназначается непосредственно ей), либо смаршрутизирован дальше в сеть (если адресатом является другой узел сети).
AllowTcpForwarding
в файле конфигурации SSH-сервера. По умолчанию она имеет значение yes
, так что дополнительные настройки не нужны.
Проброс локального соединения на удаленную машину
Синтаксис команды:
$ ssh -L [ЛокальныйАдрес:]ЛокальныйПорт:АдресНазначения:ПортНазначения Пользователь@УдаленныйСервер \_____________ _____________/ \_____________ _____________/ \______ _____/ \/ \/ \/ точка входа пункт назначения точка выхода
После этого все соединения на ЛокальныйАдрес:ЛокальныйПорт
будут перебрасываться удаленному серверу, который будет соединяться с АдресНазначения:ПортНазначения
от своего имени.
Проброс удаленного соединения на локальную машину
Для совершения обратного действия нужно выполнить команду с ключом -R
:
$ ssh -R [УдаленныйАдрес:]УдаленныйПорт:АдресНазначения:ПортНазначения Пользователь@УдаленныйСервер \_____________ _____________/ \_____________ _____________/ \/ \/ точка выхода — хост, где точка входа пункт назначения выполняется эта команда
Команда работает также, как и в вышеописанном случае, только соединения перебрасываются с удаленной машины на локальную.
127.0.0.1
, поэтому его можно опустить, сразу начиная команду с порта точки входа.
Примеры проброса соединения
У меня физический компьютер с двумя виртуальными машинами. На физической машине — Windows 10 и установлены web-сервер Apache и сервер БД MySQL. На виртуальной машине ssh-server
— Ubuntu 18.04 и установлен SSH-сервер. На виртуальной машине web-server
— Ubuntu 18.04 и установлен web-сервер Apache и сервер БД MySQL.
- Физическая машина
TKMCOMP
, ОС Windows 10, ip-адрес 192.168.110.2 - Виртуальная машина
ssh-server
, ОС Ubuntu 18.04, ip-адрес 192.168.110.8 - Виртуальная машина
web-server
, ОС Ubuntu 18.04, ip-адрес 192.168.110.12
Все машины находятся в одной локальной сети — для удобства проведения экспериментов с построением туннелей. Хотя с практической точки зрения нужен компьютер с белым ip-адресом и с установленным ssh-сервером — который будет посредником между двумя компьютерами с серыми ip-адресами.
На виртуальной машине web-server
работает web-сервер Apache — если на физическом компьютере открыть в браузере страницу http://192.168.110.12
, то увидим дефолтную страницу Apache:
На физической машине TKMCOMP
тоже работает web-сервер Apache — если открыть в браузере страницу http://127.0.0.1
, то увидим вывод php-функции phpinfo()
:
На виртуальной машине ssh-server
необходимо открыть порт для ssh-соединений. У меня это — 2222:
$ sudo ufw allow 2222/tcp Правило добавлено Правило добавлено (v6)
$ sudo ufw status verbose Состояние: активен Журналирование: on (low) По умолчанию: deny (входящие), allow (исходящие), disabled (маршрутизированные) В Действие Из ---------------------------------------------------- 2222/tcp ALLOW IN Anywhere 2222/tcp (v6) ALLOW IN Anywhere (v6)
Проброс локального соединения на удаленную машину
Открываем на физической машине PowerShell и выполняем команду:
> ssh -p 2222 -L 127.0.0.1:8080:192.168.110.12:80 evgeniy@192.168.110.8
- точка входа в туннель — физическая машина
TKMCOMP
, интерфейсlocalhost
- точка выхода из туннеля — виртуальная машина
ssh-server
, интерфейсlocalhost
- пункт назначения tcp-пакетов — виртуальная машина
web-server
Теперь у нас есть туннель от 192.168.110.2 до 192.168.110.8: пакеты от физической машины попадают в туннель и будут получены виртуальной машиной ssh-server
. А поскольку пункт назначения 192.168.110.12 — пакеты будут направлены дальше в сеть, к виртуальной машине web-server
.
На физической машине открываем в браузере страницу http://127.0.0.1:8080
— и видим дефолтную страницу Apache:
Проброс удаленного соединения на локальную машину
Открываем на физической машине PowerShell и выполняем команду:
> ssh -p 2222 -R 127.0.0.1:8080:127.0.0.1:80 evgeniy@192.168.110.8
- точка входа в туннель — виртуальная машина
ssh-server
, интерфейсlocalhost
- точка выхода из туннеля — физическая машина
TKMCOMP
, интерфейсlocalhost
- пункт назначения tcp-пакетов — физическая машина
TKMCOMP
(пакеты предназначены ей)
Теперь у нас есть туннель от 192.168.110.8 до 192.168.110.2: пакеты от виртуальной машины ssh-server
попадут в туннель и будут получены физической машиной. Откроем на виртуальной машине ssh-server
браузер и наберем в адресной строке http://192.168.110.8:8080
или http://127.0.01:8080
. Мы видим вывод функции phpinfo()
от web-сервера физической машины:
Однако, если мы откроем браузер на виртуальной машине web-server
и наберем в адресной строке http://192.168.110.8:8080
— то ничего не увидим:
Пакеты от виртуальной машины web-server
придут на сетевой интерфейс enp0s3
(192.168.110.8
) виртуальной машины ssh-server
. А перенаправляются в туннель только те пакеты, которые пришли на интерфейс обратной петли loopback
(127.0.0.1
). Чтобы это исправить, нужно изменить настройки ssh-сервера — отредактировать файл конфигурации /etc/ssh/sshd_config
:
GatewayPorts yes
$ sudo systemctl restart ssh
Но это очень радикальный путь, лучше использовать опцию -g
в команде создания туннеля. Она действует аналогично GatewayPorts
, но уменьшает риск забыть об этой настройке ssh-сервера, когда в ней уже не будет необходимости.
Обновляем страницу http://192.168.110.8:8080
на виртуальной машине web-server
:
Поиск: CLI • Linux • SSH • Ubuntu • Windows • Команда • Туннель • Сервер • Клиент • Порт • Конфигурация • Настройка