Как переадресовывать порты через шлюз Linux с помощью Iptables

Вступление

  • NAT *, или трансляция сетевых адресов, является общим термином для искажения пакетов для перенаправления их на альтернативный адрес. Обычно это используется, чтобы позволить трафику выходить за границы сети. Хост, который реализует NAT, обычно имеет доступ к двум или более сетям и настроен для маршрутизации трафика между ними.

  • Переадресация порта * - это процесс пересылки запросов для определенного порта на другой хост, сеть или порт. Поскольку этот процесс изменяет место назначения пакета в полете, он считается типом операции NAT.

В этом руководстве мы продемонстрируем, как использовать + iptables + для переадресации портов на хосты за брандмауэром с использованием методов NAT. Это полезно, если вы настроили частную сеть, но по-прежнему хотите разрешить определенный трафик внутри через назначенный шлюз. Мы будем использовать два хоста Ubuntu 14.04, чтобы продемонстрировать это.

Предпосылки и цели

Чтобы следовать этому руководству, вам понадобятся два хоста Ubuntu 14.04 в одном центре данных с включенной частной сетью. На каждой из этих машин вам необходимо настроить учетную запись пользователя без полномочий root с правами + sudo +. Вы можете узнать, как создать пользователя с привилегиями + sudo +, следуя нашим Ubuntu 14.04 начальным настройкам сервера руководство.

Первый хост будет функционировать как наш брандмауэр и маршрутизатор для частной сети. В демонстрационных целях второй хост будет настроен с веб-сервером, доступным только через его частный интерфейс. Мы будем настраивать компьютер брандмауэра для пересылки запросов, полученных через его общедоступный интерфейс, на веб-сервер, который он получит через свой частный интерфейс.

Детали хоста

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

Поиск информации о вашей сети

Чтобы узнать подробности о ваших собственных системах, начните с поиска сетевых интерфейсов. Вы можете найти интерфейсы на ваших машинах и адреса, связанные с ними, набрав:

ip -4 addr show scope global
Sample Output2: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /18 brd 45.55.191.255 scope global eth0
      valid_lft forever preferred_lft forever
3: : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   inet /16 brd 10.132.255.255 scope global eth1
      valid_lft forever preferred_lft forever

Выделенные выходные данные показывают два интерфейса (+ eth0 + и + eth1 +) и адреса, назначенные каждому (+ 192.51.100.45 + и + 192.168.1.5 + соответственно). Чтобы узнать, какой из этих интерфейсов является вашим общедоступным интерфейсом, введите:

ip route show | grep default
Outputdefault via 111.111.111.111

Показанный интерфейс (+ eth0 + в этом примере) будет интерфейсом, подключенным к вашему шлюзу по умолчанию. Это почти наверняка ваш публичный интерфейс.

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

Пример данных для этого руководства

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

Детали сети веб-сервера:

  • Публичный IP-адрес: ++

  • Частный IP-адрес: ++

  • Открытый интерфейс: ++

  • Частный интерфейс: ++

Детали сети брандмауэра:

  • Публичный IP-адрес: ++

  • Частный IP-адрес: ++

  • Открытый интерфейс: ++

  • Частный интерфейс: ++

Настройка веб-сервера

Мы начнем с хоста нашего веб-сервера. Войдите, чтобы начать с вашего пользователя + sudo +.

Установить Nginx

Первый процесс, который мы завершим, - это установим + Nginx + на наш хост веб-сервера и заблокируем его, чтобы он слушал только свой частный интерфейс. Это обеспечит доступность нашего веб-сервера только в том случае, если мы правильно настроим переадресацию портов.

Начните с обновления локального кэша пакетов и использования + apt + для загрузки и установки программного обеспечения:

sudo apt-get update
sudo apt-get install nginx

Ограничить Nginx в частной сети

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

sudo nano /etc/nginx/sites-enabled/default

Внутри найдите директиву + listen +. Вы должны найти его дважды подряд в верхней части конфигурации:

/ И т.д. / Nginx / сайты с поддержкой / по умолчанию

server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;

   . . .
}

В первой директиве «+ listen» добавьте частный IP-адрес вашего веб-сервера и двоеточие перед «+ 80 +», чтобы Nginx мог прослушивать только частный интерфейс. В этом руководстве мы только демонстрируем пересылку IPv4, поэтому мы можем удалить вторую директиву listen, которая настроена для IPv6.

В нашем примере мы изменили директивы listen, чтобы они выглядели так:

/ И т.д. / Nginx / сайты с поддержкой / по умолчанию

server {
   listen :80 default_server;

   . . .
}

Сохраните и закройте файл, когда вы закончите. Проверьте файл на наличие синтаксических ошибок, набрав:

sudo nginx -t

Если ошибки не отображаются, перезапустите Nginx, чтобы включить новую конфигурацию:

sudo service nginx restart

Проверьте ограничение сети

На этом этапе полезно проверить уровень доступа к нашему веб-серверу.

С нашего сервера * firewall *, если мы пытаемся получить доступ к нашему веб-серверу через частный интерфейс, он должен работать:

curl --connect-timeout 5
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Если мы попытаемся использовать открытый интерфейс, мы увидим, что мы не можем подключиться:

curl --connect-timeout 5
curl: (7) Failed to connect to 203.0.113.2 port 80: Connection refused

Это именно то, чего мы ожидаем.

Настройка брандмауэра для переадресации порта 80

Теперь мы можем работать над реализацией переадресации портов на нашем компьютере с брандмауэром.

Включить пересылку в ядре

Первое, что нам нужно сделать, это включить пересылку трафика на уровне ядра. По умолчанию в большинстве систем переадресация отключена.

Чтобы включить переадресацию портов только для этого сеанса, введите:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Чтобы включить перенаправление портов постоянно, вам нужно отредактировать файл + / etc / sysctl.conf +. Откройте файл с привилегиями + sudo +, набрав:

sudo nano /etc/sysctl.conf

Внутри найдите и раскомментируйте строку, которая выглядит следующим образом:

/etc/sysctl.conf

net.ipv4.ip_forward=1

Сохраните и закройте файл, когда вы закончите. Вы применяете настройки в этом файле, набрав:

sudo sysctl -p
sudo sysctl --system

Настройка основного брандмауэра

Мы будем использовать брандмауэр в th guide как основные рамки для правил в этом уроке. Чтобы начать настройку, просмотрите руководство на компьютере с брандмауэром. По окончании у вас будет:

  • Установил + iptables-persistent +

  • Сохраненный набор правил по умолчанию в + / etc / iptables / rules.v4 +

  • Научились добавлять или корректировать правила, редактируя файл правил или используя команду + iptables +

Когда у вас настроен базовый брандмауэр, продолжайте ниже, чтобы мы могли настроить его для переадресации портов.

Добавление правил пересылки

Мы хотим настроить наш брандмауэр так, чтобы трафик, поступающий в наш общедоступный интерфейс (+ eth0 +) через порт 80, был перенаправлен на наш частный интерфейс (+ eth1 +).

Наш базовый брандмауэр имеет цепочку + FORWARD +, по умолчанию настроенную на трафик + DROP +. Нам нужно добавить правила, которые позволят нам перенаправлять соединения на наш веб-сервер. В целях безопасности мы довольно плотно заблокируем это, чтобы разрешались только те соединения, которые мы хотим переадресовать.

В цепочке + FORWARD + мы будем принимать новые соединения, предназначенные для порта 80, которые приходят из нашего общедоступного интерфейса и переходят в наш частный интерфейс. Новые соединения идентифицируются расширением + conntrack + и будут конкретно представлены пакетом TCP SYN:

sudo iptables -A FORWARD -i  -o  -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

Это позволит первый пакет, предназначенный для установления соединения, через брандмауэр. Нам также необходимо разрешить любой последующий трафик в обоих направлениях в результате этого соединения. Чтобы разрешить трафик + ESTABLISHED + и + RLEATED + между нашими публичным и частным интерфейсами, введите:

iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Мы можем дважды проверить, что наша политика в цепочке + FORWARD + установлена ​​в + DROP, набрав:

sudo iptables -P FORWARD DROP

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

Правильное добавление правил NAT к прямым пакетам

Далее мы добавим правила, которые сообщат + iptables, как маршрутизировать наш трафик. Нам нужно выполнить две отдельные операции, чтобы + iptables + правильно изменил пакеты, чтобы клиенты могли обмениваться данными с веб-сервером.

Первая операция, называемая + DNAT i, будет выполняться в цепочке` + PREROUTING` таблицы + nat +. + DNAT + - это операция, которая изменяет адрес назначения пакета, чтобы обеспечить его правильную маршрутизацию при передаче между сетями. Клиенты в общедоступной сети будут подключаться к нашему серверу брандмауэра и не будут знать о топологии нашей частной сети. Нам нужно изменить адрес назначения каждого пакета, чтобы при отправке в нашей частной сети он знал, как правильно связаться с нашим веб-сервером.

Поскольку мы только настраиваем переадресацию портов и не выполняем NAT для каждого пакета, который попадает в наш брандмауэр, мы хотим сопоставить порт 80 в нашем правиле. Мы сопоставим пакеты, предназначенные для порта 80, с частным IP-адресом нашего веб-сервера (в нашем примере + 192.0.2.2 +):

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

Это заботится о половине картины. Пакет должен быть правильно направлен на наш веб-сервер. Однако прямо сейчас пакет будет по-прежнему иметь исходный адрес клиента в качестве адреса источника. Сервер попытается отправить ответ непосредственно на этот адрес, что сделает невозможным установление законного TCP-соединения.

Note

Чтобы настроить правильную маршрутизацию, нам также нужно изменить исходный адрес пакета, поскольку он покидает брандмауэр по пути к веб-серверу. Нам нужно изменить адрес источника на частный IP-адрес нашего сервера брандмауэра (в нашем примере это + 192.0.2.15 +). Затем ответ будет отправлен обратно в брандмауэр, который затем может переслать его обратно клиенту, как и ожидалось.

Чтобы включить эту функцию, мы добавим правило в цепочку + POSTROUTING + таблицы + nat +, которое оценивается непосредственно перед отправкой пакетов в сети. Мы сопоставим пакеты, предназначенные для нашего веб-сервера, по IP-адресу и порту:

sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d  -j SNAT --to-source

Как только это правило вступит в силу, наш веб-сервер должен быть доступен, указав нашему веб-браузеру на публичный адрес компьютера брандмауэра:

curl
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
   body {
       width: 35em;
       margin: 0 auto;
       font-family: Tahoma, Verdana, Arial, sans-serif;
   }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

Наша настройка переадресации портов завершена.

Регулировка постоянного набора правил

Теперь, когда мы настроили переадресацию портов, мы можем сохранить это в нашем постоянном наборе правил.

Если вы не заботитесь о потере комментариев, которые есть в вашем текущем наборе правил, просто используйте сервис + iptables-persistent для сохранения ваших правил:

sudo service iptables-persistent save

Если вы хотите сохранить комментарии в своем файле, откройте его и отредактируйте вручную:

sudo nano /etc/iptables/rules.v4

Вам нужно будет настроить конфигурацию в таблице + filter + для добавленных правил цепочки + FORWARD +. Вам также необходимо настроить раздел, в котором настраивается таблица + nat +, чтобы вы могли добавлять свои правила + PREROUTING + и + POSTROUTING +. Для нашего примера это будет выглядеть примерно так:

/etc/iptables/rules.v4

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable



# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT


# Commit the changes

COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]





# Web server network details:

# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
#
# Firewall network details:
#
# * Public IP Address:
# * Private IP Address:
# * Public Interface:
# * Private Interface:
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination
-A POSTROUTING -d  -o eth1 -p tcp --dport 80 -j SNAT --to-source

COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Сохраните и закройте файл, как только вы добавите вышеизложенное и скорректируете значения, чтобы они отражали вашу собственную сетевую среду.

Проверьте синтаксис вашего файла правил, набрав:

sudo iptables-restore -t < /etc/iptables/rules.v4

Если ошибок не обнаружено, загрузите набор правил:

sudo service iptables-persistent reload

Убедитесь, что ваш веб-сервер по-прежнему доступен через публичный IP-адрес брандмауэра:

curl

Это должно работать так же, как и раньше.

Заключение

К настоящему времени вам должно быть удобно перенаправлять порты на сервер Linux с помощью + iptables +. Процесс включает в себя разрешение переадресации на уровне ядра, настройку доступа, чтобы разрешить пересылку трафика конкретного порта между двумя интерфейсами в системе брандмауэра, и настройку правил NAT для правильной маршрутизации пакетов. Это может показаться громоздким процессом, но оно также демонстрирует гибкость инфраструктуры фильтрации пакетов `+ netfilter + 'и брандмауэра + iptables +. Это может использоваться для маскировки топологии вашей частной сети, позволяя служебному трафику свободно проходить через ваш межсетевой экран шлюза.

Related