SSH-туннели: безопасный удаленный доступ и переадресация портов
SSH — это протокол связи, который позволяет нам получать доступ к удаленным хостам и безопасно передавать данные по незащищенным сетям благодаря зашифрованным соединениям. Используя технику туннелирования SSH, мы можем перенаправлять TCP-трафик от и к локальному компьютеру, обходя ограничения брандмауэра. В этом уроке мы узнаем разницу между локальными и удаленными SSH-туннелями и узнаем, как их создавать.
В этом уроке вы узнаете:
- В чем разница между локальным и удаленным SSH-туннелем
- Как создать локальные и удаленные SSH-туннели
Создание локального SSH-туннеля
Используя локальный SSH-туннель, мы можем перенаправлять любой трафик с заданного TCP-порта на локальном компьютере на заданный адрес и порт удаленного хоста. Это может быть полезно, когда мы хотим получить доступ к сервису, который недоступен напрямую из нашей сети, но доступен с другого компьютера. Вот пример: предположим, что на машине работает экземпляр сервера Apache, который недоступен из внешней сети, а доступен только с других хостов внутри его собственной частной сети. Локальный IP-адрес этого компьютера — 192.168.1.6
. На нем веб-сервер Apache прослушивает порт 80.
Хотя мы не можем подключиться к машине напрямую через Интернет, мы можем установить SSH-соединение с другой машиной, которая находится в той же частной сети, и к которой можно получить внешний доступ, используя полное доменное имя serverone.mydomain.com
:
Создав локальный SSH-туннель, мы можем получить доступ к веб-странице, обслуживаемой Apache на удаленном компьютере, как если бы она работала на нашей машине и прослушивала порт 8000
. Чтобы создать локальный туннель, мы вызываем клиент ssh
с опцией -L
и передаем сопоставления хостов в качестве аргумента, используя следующий синтаксис:
[local-address]:local-port:remote-address:remote-port
Локальный адрес не является обязательным: если мы его не предоставим, перенаправленный порт будет доступен на всех интерфейсах. В этом случае мы будем говорить явно и использовать 192.168.0.39
. Чтобы создать туннель, мы запускаем:
$ ssh -N -L 192.168.0.39:8000:192.168.1.6:80 user@serverone.mydomain.com
Вы можете заметить, что мы использовали опцию -N
в приведенной выше команде: она необходима, чтобы указать, что мы не хотим запускать какую-либо команду, а просто хотим установить соединение с удаленным сервером. Как только соединение будет установлено, мы сможем получить доступ к содержимому, обслуживаемому Apache на удаленном частном сервере, открыв веб-браузер и перейдя по адресу http://192.168.0.39:8000.
Создание удаленного SSH-туннеля
Удаленный или «обратный» SSH-туннель работает в направлении, противоположном локальному туннелю. Используя удаленный SSH-туннель, мы можем указать, что соединения с данным удаленным адресом и TCP-портом должны перенаправляться на локальный хост и порт. В какой ситуации нам может понадобиться создать удаленный SSH-туннель?
Предположим, мы разрабатываем веб-сайт и у нас есть экземпляр веб-сервера Apache, работающий на нашем ноутбуке и прослушивающий порт 80
. Локальный IP-адрес нашей машины снова: 192.168.0.39
. Поскольку машина находится за брандмауэром NAT, доступ к ней из внешнего мира невозможен. Тем не менее, время от времени мы хотим иметь возможность показать третьей стороне, как развивается наш проект, без прямого раскрытия сервиса. Как мы можем достичь нашей цели? Мы могли бы создать удаленный SSH-туннель!
Мы подключаемся через SSH к общедоступному серверу, который, помимо порта 22
, также предоставляет внешнему миру порт 8888
. С помощью удаленного SSH-туннеля мы перенаправляем весь TCP-трафик, который происходит на этом порту, на порт 80
на нашем компьютере, который является портом, который прослушивает наш локальный веб-сервер Apache. Сторонний клиент сможет видеть страницы, обслуживаемые экземпляром нашего локального веб-сервера по адресу http://serverone.mydomain.com:8888:
Поскольку мы хотим разрешить внешним клиентам доступ к порту, перенаправленному через SSH, для того, чтобы наш туннель работал, нам необходимо убедиться, что для параметра GatewayPorts
установлено значение «да» в конфигурации SSH-сервера. Директива обычно комментируется в строке 88 файла /etc/ssh/sshd_config
:
#AllowTcpForwarding yes
GatewayPorts yes
#X11Forwarding no
Чтобы изменения вступили в силу, нам нужно перезапустить службу ssh:
$ sudo systemctl restart sshd
Теперь, чтобы создать удаленный SSH-туннель, на нашем локальном компьютере мы запускаем ssh с опцией -R
и передаем сопоставления хост-порта:
[remote-address]remote-port:local-address:local-port
Где «удаленный адрес» и «удаленный порт» — это, соответственно, адрес и порт, по которому клиент сможет получить доступ к службе, а «локальный адрес» и «локальный порт» — это локальный адрес и порт, который прослушивает сервер. Чтобы создать удаленный туннель, мы запускаем:
$ ssh -N -R serverone.mydomain.com:8888:192.168.0.39:80 user@serverone.mydomain.com
Заключительные мысли
В этом уроке мы узнали разницу между локальными и удаленными SSH-туннелями и увидели, как их создавать в Linux. Локальные туннели полезны, когда мы хотим получить доступ к услуге, недоступной напрямую через Интернет; вместо этого, используя удаленные туннели, мы можем предоставить кому-либо доступ к службе, работающей на нашей локальной машине, даже если она находится за брандмауэром NAT.