Linux сервер за nat

Как получить доступ к серверу Linux за NAT через обратный туннель SSH

Оригинал: How to access a Linux server behind NAT via reverse SSH tunnel
Автор: Dan Nanni
Дата публикации: May 4, 2015
Перевод: Н.Ромоданов
Дата перевода: сентябрь 2015 г.

Вы запустили Linux-сервер дома, который находится за маршрутизатором NAT или защищен брандмауэром. Теперь, когда вы находитесь не дома, вам нужен доступ к домашнему серверу через SSH. Как это настроить? Возможным вариантом будет, безусловно, перенаправление на порт SSH. Однако перенаправление портов может оказаться более сложным в случае, если у вас среда с несколькими вложенными NAT. Кроме того, на выбранное решение могут оказывать влияние различные ограничения, устанавливаемые интернет-провайдерами, например, ограничительные брандмауэры провайдеров, которые блокируют перенаправление портов или NAT с трансляцией адресов, что позволяет пользователям одновременно пользоваться одними и теми же адресами IPv4.

Что такое обратное туннелирование SSH?

Одной из альтернатив перенаправлению портов SSH является обратное туннелирование SSH. Концепция реверсного туннелирования SSH сравнительно проста. Для этого вам понадобится еще один хост (так называемый «хост релея»), находящийся за пределами защищенной домашней сети, к которому вы можете подключиться через SSH из либого места независимо от того, где вы находитесь. Вы можете настроить хост релея на отдельном экземпляре виртуального частного сервера VPS, использующего общедоступный адрес IP. После этого все, что вам потребуется сделать, это настроить постоянный туннель SSH туннель от сервера в вашей домашней сети на хост общественного релея. Благодаря этому вы можете подключаться «в обратном направлении» к домашнему сервера с хоста релея (именно поэтому такой туннель называется «обратным» туннелем). Д тех пор, пока хост релея доступен для вас, вы можете подключиться к домашнему серверу из любого места, где бы вы не находились, причем независимо от того, используется ли в вашей домашней сети ограничивающий NAT или брандмауэр.

Настройка в Linux обратного туннелирования SSH

Давайте посмотрим, каким образом можно создавать и использовать обратный туннель SSH. Предположим следующее. Мы будем настраивать обратный туннель SSH от домашнего сервера homeserver к серверу релея relayserver , так что мы можем получать доступ через SSH к homeserver через relayserver с некоторого другого компьютера, который называется клиентским компьютером clientcomputer . Общедоступным адресом сервера релея relayserver является 1.1.1.1.

На сервере homeserver открываем соединение SSH к серверу релея relayserver следующим образом.

Здесь порт 10022 является портом с любым номером, который вы выберите. Просто убедитесь, что на сервере relayserver этот порт не используется другими программами.

Параметр «-R 10022:localhost:22» определяет ревесный туннель. Он перенаправляет трафик с порта 10022 сервера relayserver на порт 22 на сервере homeserver

Благодаря параметру «-fN» SSH уйдет в фоновый режим сразу, как только вы успешно пройдете проверку подлинности на сервере SSH. Этот параметр полезен в случае, если вы не хотите на удаленном сервере SSH выполнять какие-либо команды, а просто хотите, как в нашем случае, использовать перенаправление портов.

После запуска указанной выше команды вы вернетесь обратно к командной строке сервера homeserver .

Войдите на сервер relayserver и убедитесь, что 127.0.0.1:10022 привязан к sshd . Если это так, то это означает, что обратный туннель настроен правильно.

Теперь с любого другого компьютера (например, с клиента clientcomputer ) войдите на сервер relayserver . Затем получите доступ к серверу homeserver следующим образом.

Единственное, на что следует обратить внимание, это то, что логин/пароль, который вы набираете для localhost , должен быть для сервера homeserver , а не для серевера relayserver , поскольку вы через локальную конечную точку туннеля вошли на сервер homeserver . Так что не вводите логин/пароль для сервера relayserver . После успешного входа в систему, вы будете находиться на сервере homeserver .

Читайте также:  Куда сохраняются обновления для windows

Прямое подключение к серверу с NAT через обратный туннель SSH

Хотя описанный выше метод позволяет вам получить доступ к серверу homeserver , который находится за NAT, вам протребуется входить дважды: сначала — на сервер relayserver , а затем — на сервер homeserver . Это связано с тем, что конечная точка туннеля SSH на сервере relayserver привязана к адресу loopback (127.0.0.1).

Но на самом деле, есть способ получить доступ к серверу homeserver , который закрыт NAT, с помощью одного входа на сервер relayserver . Для этого вам нужно сделать, чтобы sshd, расположенный на сервере relayserver , мог перенаправлять порт не только с адреса loopback но и с внешнего хоста. Это достигается путем указания параметра GatewayPorts в sshd , работающего на сервере relayserver .

Откройте файл /etc/ssh/sshd_conf на сервере relayserver и добавьте к нему следующее.

В системе на основе Debian:

В системе на основе Red Hat:

Теперь давайте инициализируем обратный туннель SSH из homeserver следующим образом.

Войдите на сервер relayserver и убедитесь с помощью команды netstat в том, что обратный туннель SSH успешно установлен.

В отличие от предыдущего случая, конечной точкой туннеля теперь является 1.1.1.1:10022 (общедоступный адрес IP сервера relayserver ), а не 127.0.0.1:10022. Это означает, что конечная точка туннеля доступна с внешнего хоста.

Теперь для того, чтобы получить доступ к серверу homeserver , защищенному NAT, введите на любом другом компьютере (например, на клиентском компьютере clientcomputer ), следующую команду.

Хотя в приведенной выше команде 1.1.1.1 является общедоступным адресом IP сервера relayserver , homeserver_user должен быть учетной записью на сервере homeserver . Это связано с тем, что реальный хост, на который вы входите, это homeserver , а не relayserver . Последний просто ретранслирует ваш трафик SSH трафик на сервер homeserver .

Настройка в Linux постоянного обратного туннеля SSH

Теперь, когда вы понимаете, как создать обратный туннель SSH, давайте сделаем туннель «постоянным», так что туннель поднимался и работал постоянно (независимо от временной повышенной загрузки сети, тайм-аута SSH, перезагрузки хоста релея, и т.д.). Поскольку, если туннель поднимается не всегда, то у вас не будет надежного подключения к вашему домашнему серверу.

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

В качестве первого шага, давайте установим возможность беспарольного входа через SSH с сервера homeserver на сервер relayserver . Таким образом, программа autossh сможет без вмешательства пользователя перезапускать пропавший обратный туннель SSH.

Затем на сервере homeserver , откуда начинается туннель, установите программу autossh .

На сервере homeserver запустите autossh со следующими аргументами с тем, чтобы создать постоянный туннель SSH, действующий в направлении сервера relayserver .

Параметр «-M 10900» указывает порт на сервере relayserver , для которого будет осуществляться мониторинг и который будет использоваться для обмена тестовыми данными при контроле сессии SSH. Этот порт не должен на сервере relayserver использоваться какой-либо другой программой.

Параметр «-fN» перенаправляется в команду ssh , что позволит туннелю SSH работать в фоновом режиме.

Параметр «-o XXXX» сообщает команде ssh следующее:

  • Использовать ключ аутентификации, а не парольную аутентификацию.
  • Автоматически принимать (неизвестные) ключи хоста SSH
  • Каждые 60 секунд обмениваться сообщениями keep-alive.
  • Отправлять до трех сообщений keep-alive без получения каких-либо ответов.
Читайте также:  Repair all windows errors

Остальные параметры обратного туннелирования SSH те же самые, что и в предыдущих примерах.

Если вы хотите, чтобы туннель SSH автоматически поднимался при загрузке системы, вы можете в /etc/rc.local добавить указанную выше команду autossh .

Заключение

В этой статье было рассказано о том, как можно использовать обратный туннель SSH для доступа к серверу Linux, который находится за брандмауэром или шлюзом NAT, защищающего сеть от внешнего мира. Было продемонстрировано, как это сделать для случая домашней сети с помощью общедоступного виртуального частного сервера VPS. Вы должны быть внимательны при использовании этого приема для корпоративных сетей. Такой туннель может рассматриваться как нарушение корпоративной политики, поскольку он позволяет обойти корпоративные брандмауэры и может открыть корпоративные сети для внешних атак. Существует большая вероятность, что этот подход может использоваться неправильно или с заведомо плохими целями. Так всегда помнить, что прежде всего вы сами ответственны за все настройки, которые вы осуществляете.

Источник

Быстрый роутинг и NAT в Linux

Немного истории

Тема исчерпания адресного пространства IPv4 уже не нова. В какой-то момент в RIPE появились очереди ожидания (waiting list), затем возникли биржи, на которых торговали блоками адресов и заключались сделки по их аренде. Постепенно операторы связи начали предоставлять услуги доступа в Интернет с помощью трансляции адресов и портов. Кто-то не успел получить достаточно адресов, чтобы выдать «белый» адрес каждому абоненту, а кто-то начал экономить средства, отказавшись от покупки адресов на вторичном рынке. Производители сетевого оборудования поддержали эту идею, т.к. этот функционал обычно требует дополнительных модулей расширения или лицензий. Например, у Juniper в линейке маршрутизаторов MX (кроме последних MX104 и MX204) выполнять NAPT можно на отдельной сервисной карте MS-MIC, на Cisco ASR1k требуется лицензия СGN license, на Cisco ASR9k — отдельный модуль A9K-ISM-100 и лицензия A9K-CGN-LIC к нему. В общем, удовольствие стоит немалых денег.

IPTables

Задача выполнения NAT не требует специализированных вычислительных ресурсов, ее в состоянии решать процессоры общего назначения, которые установлены, например, в любом домашнем роутере. В масштабах оператора связи эту задачу можно решить используя commodity серверы под управлением FreeBSD (ipfw/pf) или GNU/Linux (iptables). Рассматривать FreeBSD не будем, т.к. я довольно давно отказался от использования этой ОС, так что остановимся на GNU/Linux.

Включить трансляцию адресов совсем не сложно. Для начала необходимо прописать правило в iptables в таблицу nat:

Операционная система загрузит модуль nf_conntrack, который будет следить за всеми активными соединениями и выполнять необходимые преобразования. Тут есть несколько тонкостей. Во-первых, поскольку речь идет о NAT в масштабах оператора связи, то необходимо подкрутить timeout’ы, потому что со значениями по умолчанию размер таблицы трансляций достаточно быстро вырастет до катастрофических значений. Ниже пример настроек, которые я использовал на своих серверах:

И во-вторых, поскольку по умолчанию размер таблицы трансляций не рассчитан на работу в условиях оператора связи, его необходимо увеличить:

Также необходимо увеличить и количество buckets для хэш-таблицы, хранящей все трансляции (это опция модуля nf_conntrack):

После этих нехитрых манипуляций получается вполне работающая конструкция, которая может транслировать большое количество клиентских адресов в пул внешних. Однако, производительность этого решения оставляет желать лучшего. В своих первых попытках использования GNU/Linux для NAT (примерно 2013 год) я смог получить производительность около 7Gbit/s при 0.8Mpps на один сервер (Xeon E5-1650v2). С того времени в сетевом стеке ядра GNU/Linux было сделано много различных оптимизаций, производительность одного сервера на том же железе выросла практически до 18-19 Gbit/s при 1.8-1.9 Mpps (это были предельные значения), но потребность в объеме трафика, обрабатываемого одним сервером, росла намного быстрее. В итоге были выработаны схемы балансировки нагрузки на разные серверы, но всё это увеличило сложность настройки, обслуживания и поддержания качества предоставляемых услуг.

Читайте также:  Как сделать приветствие при включении компьютера windows 10

NFTables

Сейчас модным направлением в программном «перекладывании пакетиков» является использование DPDK и XDP. На эту тему написана куча статей, сделано много разных выступлений, появляются коммерческие продукты (например, СКАТ от VasExperts). Но в условиях ограниченных ресурсов программистов у операторов связи, пилить самостоятельно какое-нибудь «поделие» на базе этих фреймворков довольно проблематично. Эксплуатировать такое решение в дальнейшем будет намного сложнее, в частности, придется разрабатывать инструменты диагностики. Например, штатный tcpdump с DPDK просто так не заработает, да и пакеты, отправленные назад в провода с помощью XDP, он не «увидит». На фоне всех разговоров про новые технологии вывода форвардинга пакетов в user-space, незамеченными остались доклады и статьи Pablo Neira Ayuso, меинтейнера iptables, про разработку flow offloading в nftables. Давайте рассмотрим этот механизм подробнее.

Основная идея заключается в том, что если роутер пропустил пакеты одной сессии в обе стороны потока (TCP сессия перешла в состояние ESTABLISHED), то нет необходимости пропускать последующие пакеты этой сессии через все правила firewall, т.к. все эти проверки всё равно закончатся передачей пакета далее в роутинг. Да и собственно выбор маршрута выполнять не надо — мы уже знаем в какой интерфейс и какому хосту надо переслать пакеты пределах этой сессии. Остается только сохранить эту информацию и использовать ее для маршрутизации на ранней стадии обработки пакета. При выполнении NAT необходимо дополнительно сохранить информацию об изменениях адресов и портов, преобразованных модулем nf_conntrack. Да, конечно, в этом случае перестают работать различные полисеры и другие информационно-статистические правила в iptables, но в рамках задачи отдельного стоящего NAT или, например, бордера — это не так уж важно, потому что сервисы распределены по устройствам.

Конфигурация

Чтобы воспользоваться этой функцией нам надо:

  • Использовать свежее ядро. Несмотря на то, что сам функционал появился еще в ядре 4.16, довольно долго он было очень «сырой» и регулярно вызывал kernel panic. Стабилизировалось всё примерно в декабре 2019 года, когда вышли LTS ядра 4.19.90 и 5.4.5.
  • Переписать правила iptables в формат nftables, используя достаточно свежую версию nftables. Точно работает в версии 0.9.0

Если с первым пунктом всё в принципе понятно, главное не забыть включить модуль в конфигурацию при сборке (CONFIG_NFT_FLOW_OFFLOAD=m), то второй пункт требует пояснений. Правила nftables описываются совсем не так, как в iptables. Документация раскрывает практически все моменты, также есть специальные конверторы правил из iptables в nftables. Поэтому я приведу только пример настройки NAT и flow offload. Небольшая легенда для примера: , — это сетевые интерфейсы, через которые проходит трафик, реально их может быть больше двух.

— начальный и конечный адрес диапазона «белых» адресов.

Конфигурация NAT очень проста:

С flow offload немного сложнее, но вполне понятно:

Вот, собственно, и вся настройка. Теперь весь TCP/UDP трафик будет попадать в таблицу fastnat и обрабатываться намного быстрее.

Результаты

Чтобы стало понятно, насколько это «намного быстрее», я приложу скриншот нагрузки на два реальных сервера, с одинаковой начинкой (Xeon E5-1650v2), одинаково настроенных, использующих одно и тоже ядро Linux, но выполняющих NAT в iptables (NAT4) и в nftables (NAT5).

На скриншоте нет графика пакетов в секунду, но в профиле нагрузки этих серверов средний размер пакета в районе 800 байт, поэтому значения доходят до 1.5Mpps. Как видно, запас производительности у сервера с nftables огромный. На текущий момент этот сервер обрабатывает до 30Gbit/s при 3Mpps и явно способен упереться в физическое ограничение сети 40Gbps, имея при этом свободные ресурсы CPU.

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

Источник

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