Настройка интернет-шлюза с NAT и Port Forwarding на CentOS 7

В этой статье мы рассмотрим процесс организации и настройки простого интернет-шлюза на базе CentOS 7.x. Данный шлюз позволит пользователям из локальной сети выходить в Интернет, а также получать доступ к серверам или компьютерам во внутренней сети снаружи. Для организации маршрутизации и пересылки пакетов мы будем использовать технологию NAT на базе межсетевого экрана iptables. Также рассмотрим, как вести и анализировать логи подключений на интернет-шлюзе при доступе внешних пользователей в локальную сеть.

Схема локальной сети со шлюзом доступа в Интернет, типы NAT

NAT (Network Address Translation) – трансляция IP адресов, это механизм, позволяющий подменять адрес источника и назначения в заголовке IP пакетов, при их прохождении через маршрутизатор, т.е. между разными сетями.

Настраивать NAT будем между внутренней сетью с адресацией 10.2.0.0/24 и внешней сетью Интернет, двух видов:

  • source NAT – это подмена IP адреса источника, в нашем случае, для организации выхода в Интернет через один публичный IP адрес нескольких клиентов.
  • destination NAT — подмена IP адреса назначения, в нашем случае, для обеспечения доступа из внешней сети Интернет через публичный IP адрес к серверам внутренней сети.

Определим элементы сети (рисунок 1), между которыми будет организован NAT:

  • gw-server – сервер шлюз, т.е. наш CentOS Linux сервер, который предоставляет доступ за пределы внутренней сети. У него два интерфейса, первый eth1(10.2.0.1) во внутренней сети, второй eth0(84.201.168.122) с публичным IP адресом и доступом в Интернет;
  • web-server01 – веб сервер внутренней сети, IP адрес 10.2.0.11;
  • my-server01 – личный сервер внутренней сети, IP адрес 10.2.0.12.

схема сети с NAT шлюзом доступа в интернет на базе Linux CentOS

Примечание : для серверов внутренней сети web-server01 и myserver01 маршрут по умолчанию установлен на интерфейс eth1(10.2.0.1) сервера gw-server01 .

Настройка Source NAT: доступ из локальной сети в Интернет

При source NAT для серверов внешней сети, запросы от наших клиентов из внутренней сети будут выглядеть так, как будто с ними общается напрямую сервер шлюз — gw-server01.

В прошлой статье “ Базовая настройка файервола Linux с помощью iptables ” мы рассмотрели азы использования iptables. В этот раз, работать в iptables будем не только с таблицей filter , но и с таблицей nat. В отличие от таблицы для фильтрации трафика filter, таблица nat содержит следующие chains(цепочки):

  • PREROUTING — в этой цепочке обрабатываются входящие IP пакеты, до их разделения на предназначенные для самого сервера или для передачи другому, т.е. до принятия решения о выборе маршрута для IP пакета;
  • OUTPUT – цепочка предназначена для обработки IP пакетов, которые сгенерированы локально приложением на сервере. Локально сгенерированные IP пакеты не проходят цепочку PREROUTING;
  • POSTROUTING — в этой цепочке обрабатываются все исходящие IP пакеты, уже после принятия решения о маршруте для IP пакета.

Отличаются и действия, выполняемые для IP пакетов, в этой таблице:

  • MASQUERADE и SNAT — производит подмену IP адреса источника для исходящих пакетов. Отличием этих действий является то, что SNAT дает возможность задать конкретный IP адрес нового источника, а в случае MASQUERADE это происходит динамически;
  • DNAT — производит подмену IP адреса назначения для входящих пакетов.
Важно : действие MASQUERADE и SNAT задается только для цепочки POSTROUTING, а действие DNAT только для цепочек PREROUTING или OUTPUT .

На рисунке 2 изображены этапы обработки IP пакета из внутренней сети на шлюзе gw-server01 при SNAT на iptables. IP адрес и порт назначения при этом остаются неизменными.

схема цепочек forward postrouting в linuc iptables Рисунок 2

  1. IP пакет поступил на внутренний интерфейс eth1 сервера gw-server01. Так как IP назначения не принадлежит серверу gw-server01, IP пакет переходит к обработке цепочкой FORWARD.
  2. После прохождения цепочки FORWARD, для IP пакета определяется исходящий сетевой интерфейс, с которого он должен быть отправлен, это отмечено желтым цветом
  3. В конце IP пакет проходит цепочку POSTROUTING, в которой происходит подмена IP адреса источника, на IP адрес внешнего интерфейса eth0 сервера gw-server01

Приступим к настройке. Сначала нужно установить параметр ядра, который позволяет передавать пакеты между интерфейсами сервера. Для этого в файл /etc/sysctl.conf добавим переменную:

net.ipv4.ip_forward = 1

Чтобы применить изменения, выполним команду

sysctl -p /etc/sysctl.conf

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

Создадим правило в iptables, разрешающее передачу пакетов между внутренним (eth1) и внешним (eth0) интерфейсом:

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

и разрешим передавать между интерфейсами пакеты, относящиеся к уже установленным соединениям.

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

Предыдущие два правила имеет смысл создавать, только если для цепочки FORWARD по умолчанию установлена политика DROP:

iptables -P FORWARD DROP

Включение SNAT:

iptables -t nat -A POSTROUTING -s 10.2.0.0/24 -o eth1 -j SNAT --to-source 84.201.168.122

  • —to-source должен быть адресом на интерфейсе, с которого планируется выпускать во внешнюю сеть IP пакеты;
  • -s 10.2.0.0/24 задано из расчета, что внутренняя сеть 10.2.0.0/24, но это необязательный параметр, если его не указать, ограничений на источник взаимодействия не будет.

Посмотрим получившуюся конфигурацию для таблицы filter и цепочки FORWARD (вывод обрезан):

iptables -L -n -v

iptables -L -n -v chain forward

и конфигурацию для таблицы nat и цепочки POSTROUTING (вывод обрезан):

iptables -t nat -L -n -v

iptables nat postrouting chain

Для проверки, что наш веб-сервер во внутренней сети получил доступ в Интернет, попробуем подключиться через telnet на адрес 1.1.1.1 (Cloudflare DNS) порт 80:

telnet 1.1.1.1 80

test telnet via iptables nat

Вывод команды Connected 1.1.1.1 , показывает, что подключение прошло успешно.

Настройка Destination NAT и port forwarding: доступ из Интернета в локальную сеть

Теперь рассмотрим обратную ситуацию. Мы хотим, чтобы клиенты снаружи имели возможность попадать на наш сайт во внутренней сети. А также нам нужно заходить на свой личный сервер (или рабочую станцию) из Интернета. Отличие этого случая не только в направлении взаимодействия, но еще и в том, что требуется перенаправить запросы на отдельные порты, 80(TCP) и 3389(TCP), при этом подменять сервер назначения и возможно, порт назначения. Эта техника называется port forwarding (проброс портов).

Порт форвардинг в Windows можно организовать с помощью команды netsh interface portproxy .

Сначала разрешим передачу пакетов с внешнего интерфейса (eth0) на внутренний (eth1) интерфейс:

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

Это правило разрешает передавать IP пакеты между интерфейсами независимо от источника. Но можно отдельным правилом запретить подключение через NAT для отдельных IP адресов или подсетей:

iptables -I FORWARD 1 -o eth1 -s 167.71.67.136 -j DROP

Внимание : здесь в команде используется ключ –I вместо –A. Ключ –I позволяет добавить правило по определенному номеру в последовательности правил цепочки, указав индекс. Например, в команде выше, индекс единица в цепочке FORWARD, то есть, правило будет добавлено в начало цепочки. Если это правило будет добавлено в конец, оно не сработает, так как IP пакет будет обработан предыдущим правилом, разрешающим любые источники взаимодействия, и на этом его прохождение по цепочке FORWARD будет завершено.

Теперь перенаправим все соединения на порт 80 интерфейса внешней сети(eth0) на IP адрес веб сервера внутренней сети web-server01 :

iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to-destination 192.168.0.11

—to-destination — должен быть IP адресом, на который нужно заменить IP адрес назначения.

Для проверки, попробуем подключиться из сети Интернет через telnet на публичный IP адрес сервера gw-server на порт 80:

telnet 84.201.168.122 80

Результатом будет ответ веб сервера web-server01 из нашей внутренней сети:

HTTP/1.1 400 Bad Request_x000D_Server: nginx/1.14.2_x000D_Date: Wed, 31 Jul 2019 10:21:21 GMT_x000D_Content-Type: text/html_x000D_Content-Length: 173_x000D_Connection: close_x000D_

Аналогично можно настроить доступ из интернета на свою рабочую станцию по RDP. Так как доступ по RDP будет нужен ограниченному количеству человек, безопасней будет использовать при подключении нестандартный порт, например 13389, а уже с него перенаправлять на порт 3389 сервера внутренней сети (либо изменить номер RDP порта на Windows компьютере ). Измененный порт назначения указывается через двоеточие после IP адреса:

iptables -t nat -A PREROUTING -p tcp --dport 13389 -i eth0 -j DNAT --to-destination 192.168.0.12:3389

Для проверки, попробуем подключиться из сети Интернет через telnet (или командлет PowerShell Test-NetConnection ) на публичный IP адрес сервера gw-server на порт 13389:

telnet 84.201.168.122 13389

В ответ получим пустой экран и курсор, это говорит о том, что соединение работает.

Анализ логов сетевых подключений NAT в Linux

Одним из моментов, для повышения уровня безопасности после настройки port forwarding на наш личный сервер из внешней сети, будет сборка и анализ логов внешний подключений. Ведь кроме нас, этим доступом может попробовать воспользоваться злоумышленник.

Сначала включим запись в лог файл / var /log/messages все попытки соединений на используемый нами нестандартный RDP порт:

iptables -I INPUT 1 -p tcp --dport 13389 -m state --state NEW -j LOG --log-prefix "NEW RDP SESSION"

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

cat /var/log/messages | grep "NEW RDP SESSION"

kernel: NEW RDP SESSION IN= OUT=eth1 SRC=167.71.67.79 DST=84.201.168.122  LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=16270 DF PROTO=TCP SPT=60836 DPT=13389 WINDOW=29200 RES=0x00 SYN URGP=0

Читать такой лог не очень удобно, тем более каждый день. Поэтому, следующим шагом, автоматизируем анализ логов, чтобы регулярно получать отчеты, на основе нашего фильтра. Для этого воспользуемся утилитой Logwatch , ее установка через стандартный менеджер пакетов yum :

yum install logwatch

Сначала попробуем сгенерировать отчет вручную:

/usr/sbin/logwatch --detail low --service iptables --range today

здесь,

  • —service — задает конкретный сервис, сообщения от которого нужно анализировать, в нашем случае, только от iptables;
  • —range — указывает период выборки данных, today – все события за сегодня;
  • —detail — степень детализация отчета (high, med, low).

По умолчанию logwatch отобразит отчет на экран, получим примерно такой вывод:

--------------------- iptables firewall Begin ------------------------_x000D_Listed by source hosts:_x000D_Logged 2 packets on interface eth1_x000D_From 167.71.45.65 - 2 packets to tcp(13389)_x000D_---------------------- iptables firewall End -------------------------_x000D_

Отчет работает, осталось выполнять его по расписанию , раз день и отправлять себе на email, для этого обновим команду и запишем ее в файл /etc/cron.daily/00logwatch:

/usr/sbin/logwatch --output mail --mailto [email protected] --detail low --service iptables --range yesterday

Здесь добавились опции:

—output — указывает способ вывода отчета, mail – отправить на почту;

—mailto — e-mail адрес получателя отчета.

При пробросе RDP внутрь локальной сети дополнительно нужно уметь анализировать логи RDP подключений непосредственно в Windows .
EnglishRussianUkrainian