В этой статье мы рассмотрим процесс организации и настройки простого интернет-шлюза на базе 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.
Настройка 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 адреса назначения для входящих пакетов.
На рисунке 2 изображены этапы обработки IP пакета из внутренней сети на шлюзе gw-server01 при SNAT на iptables. IP адрес и порт назначения при этом остаются неизменными.
Рисунок 2
- IP пакет поступил на внутренний интерфейс eth1 сервера gw-server01. Так как IP назначения не принадлежит серверу gw-server01, IP пакет переходит к обработке цепочкой FORWARD.
- После прохождения цепочки FORWARD, для IP пакета определяется исходящий сетевой интерфейс, с которого он должен быть отправлен, это отмечено желтым цветом
- В конце 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
и конфигурацию для таблицы nat и цепочки POSTROUTING (вывод обрезан):
iptables -t nat -L -n -v
Для проверки, что наш веб-сервер во внутренней сети получил доступ в Интернет, попробуем подключиться через telnet на адрес 1.1.1.1 (Cloudflare DNS) порт 80:
telnet 1.1.1.1 80
Вывод команды Connected 1.1.1.1, показывает, что подключение прошло успешно.
Настройка Destination NAT и port forwarding: доступ из Интернета в локальную сеть
Теперь рассмотрим обратную ситуацию. Мы хотим, чтобы клиенты снаружи имели возможность попадать на наш сайт во внутренней сети. А также нам нужно заходить на свой личный сервер (или рабочую станцию) из Интернета. Отличие этого случая не только в направлении взаимодействия, но еще и в том, что требуется перенаправить запросы на отдельные порты, 80(TCP) и 3389(TCP), при этом подменять сервер назначения и возможно, порт назначения. Эта техника называется port forwarding (проброс портов).
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
Теперь перенаправим все соединения на порт 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 Server: nginx/1.14.2 Date: Wed, 31 Jul 2019 10:21:21 GMT Content-Type: text/html Content-Length: 173 Connection: close
Аналогично можно настроить доступ из интернета на свою рабочую станцию по 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 ------------------------ Listed by source hosts: Logged 2 packets on interface eth1 From 167.71.45.65 - 2 packets to tcp(13389) ---------------------- iptables firewall End -------------------------
Отчет работает, осталось выполнять его по расписанию, раз день и отправлять себе на email, для этого обновим команду и запишем ее в файл /etc/cron.daily/00logwatch:
/usr/sbin/logwatch --output mail --mailto [email protected] --detail low --service iptables --range yesterday
Здесь добавились опции:
—output — указывает способ вывода отчета, mail – отправить на почту;
—mailto — e-mail адрес получателя отчета.