Настраиваю роутер с NAT. Вроде даже все завелось. Но в том, что касается настройки iptables поначитался всякого - и манов, и статей, в голове каша. Не уверен, что все верно понимаю.
Есть пара вопросов. Если вдруг кому не жаль времени поглядеть - буду благодарен за ответы.
Схема сети следующая: домашние машины => коммутатор => маршрутизатор под управлением Debian с 2 ethernet интерфейсами => внутренняя сеть прова (с различными сервисами, включая DC, игровые серверы и т.п.) => IPsec VPN для доступа в интернет.
Правила настраиваются скриптом '/etc/network/if-pre-up.d/NAT'. Представляет собой компиляцию материалов из нескольких нагугленных статей, плюс некоторые личные дополнения:
#!/bin/bash
# Устанавливаем переменные окружения:
LAN="eth1"
WAN="eth0"
VPN="ppp0"
LAN_IP_RANGE="192.168.110.0/24"
LAN_IP="192.168.110.1"
WAN_IP="172.20.85.281"
LIBER_IP="192.168.110.100"
SNAKE_IP="192.168.110.101"
SSH_PORT="22828"
# Включаем форвардинг пакетов и подгружаем модули:
echo "1" > /proc/sys/net/ipv4/conf/default/rp_filter
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
modprobe iptable_nat
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# Очищаем существующие таблицы правил:
iptables --flush
iptables --delete-chain
iptables --table nat --flush
iptables --table nat --delete-chain
iptables --table mangle --flush
iptables --table mangle --delete-chain
# Устанавливаем политики запрета всего:
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP
# Разрешаем локальный траффик для loopback:
iptables --append INPUT --in-interface lo --jump ACCEPT
iptables --append OUTPUT --out-interface lo --jump ACCEPT
iptables --append INPUT ! --in-interface lo --destination 127.0.0.0/8 --jump REJECT
# Явно разрешаем доступ к SSH из внутренней сети:
iptables --append INPUT --protocol tcp --in-interface $LAN --destination-port $SSH_PORT --jump ACCEPT
# Явно разрешаем пинг:
iptables --append INPUT --protocol icmp --icmp-type 8 --jump ACCEPT
# Запрещаем все пакеты, которые не могут быть идентифицированы и поэтому не могут иметь определенного статуса:
iptables --append INPUT --match state --state INVALID --jump DROP
iptables --append FORWARD --match state --state INVALID --jump DROP
# Приводит к связыванию системных ресурсов, так что реальный обмен данными становится невозможным, запрещаем:
iptables --append INPUT --protocol tcp ! --syn --match state --state NEW --jump DROP
iptables --append OUTPUT --protocol tcp ! --syn --match state --state NEW --jump DROP
# Разрешаем траффик для внутренней сети:
iptables --append INPUT --in-interface $LAN --jump ACCEPT
iptables --append OUTPUT --out-interface $LAN --jump ACCEPT
# Разрешаем входящие пакеты уже инициированных соединений, а также дочерние от них:
iptables --append INPUT --protocol all --match state --state ESTABLISHED,RELATED --jump ACCEPT
# Разрешаем исходящие пакеты новых, а так же уже инициированных и их дочерних соединений:
iptables --append OUTPUT --protocol all --match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
# Разрешаем форвардинг для новых, а так же уже инициированных и их дочерних соединений:
iptables --append FORWARD --protocol all --match state --state NEW,ESTABLISHED,RELATED --jump ACCEPT
# Включаем фрагментацию пакетов. Необходимо из за разных значений MTU:
iptables --insert FORWARD --protocol tcp --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu
# Разрешаем доступ из внутренней сети наружу:
iptables --append FORWARD --in-interface $LAN --out-interface $WAN --jump ACCEPT
iptables --append FORWARD --in-interface $LAN --out-interface $VPN --jump ACCEPT
# Разрешаем доступ снаружи во внутреннюю сеть:
iptables --append FORWARD --in-interface $WAN --out-interface $LAN --jump ACCEPT
iptables --append FORWARD --in-interface $VPN --out-interface $LAN --jump ACCEPT
# NAT-маскарадинг:
iptables --table nat --append POSTROUTING --out-interface $WAN --source $LAN_IP_RANGE --jump MASQUERADE
iptables --table nat --append POSTROUTING --out-interface $VPN --source $LAN_IP_RANGE --jump MASQUERADE
################
#
# Проброс портов
#
# Правила для каждого проброса:
# 1 - Проброс внешнего порта на адрес в LAN
# 2 - Перенаправление пакетов через NAT при обращении LAN-клиента к LAN-службе по ее WAN адресу
# 3 - На случай, если клиент - сам маршрутизатор
# 4 - Разрешающее правило для форвардинга из WAN в LAN
# Greylink DC++
iptables --table nat --append PREROUTING \
--protocol tcp --destination $WAN_IP --dport 22612 --jump DNAT --to-destination $LIBER_IP
iptables --table nat ---append POSTROUTING \
--protocol tcp --destination $LAN_IP --dport 22612 --jump SNAT --to-source $LIBER_IP
iptables --table nat --append OUTPUT \
--protocol tcp --destination $WAN_IP --dport 22612 --jump DNAT --to-destination $LIBER_IP
iptables --insert FORWARD 1 \
--protocol tcp --match tcp --in-interface $WAN --out-interface $LAN \
--destination $LIBER_IP --dport 22612 --jump ACCEPT
iptables --table nat --append PREROUTING \
--protocol tcp --destination $WAN_IP --dport 22682 --jump DNAT --to-destination $LIBER_IP
iptables --table nat ---append POSTROUTING \
--protocol tcp --destination $LAN_IP --dport 22682 --jump SNAT --to-source $LIBER_IP
iptables --table nat --append OUTPUT \
--protocol tcp --destination $WAN_IP --dport 22682 --jump DNAT --to-destination $LIBER_IP
iptables --insert FORWARD 1 \
--protocol tcp --match tcp --in-interface $WAN --out-interface $LAN \
--destination $LIBER_IP --dport 22682 --jump ACCEPT
Собственно вопросы:
1) Если все будет работать и так, то подгрузку модулей (modprobe ...) из скрипта лучше убрать?
2) Правильно ли я понимаю, что политики (iptables --policy) представляют собой нечто вроде глобальных правил по умолчанию? Т.е. если не найдено правило, условия которого соответствуют параметрам IP пакета, то выполняются действия, заданные политиками. Так?
3) Правило:
iptables --append INPUT ! --in-interface lo --destination 127.0.0.0/8 --jump REJECT
наверное, лучше заменить на DROP? Т.е. не будет ли лучшим ответом на такой пакет покерфейс и ледяное молчание?
4) Что касается раздела «Разрешаем доступ снаружи во внутреннюю сеть». При текущих правилах получается такая картина:
Если каким-то чудом на WAN интерфейс попадет пакет с IP назначения из диапазона LAN сети, то он будет пропущен. Но учитывая таблицы маршрутизации на роутерах прова, попасть на него он никак не должен.
С другой стороны, это потенциальная уязвимость, и разрешающие правила на форвардинг лучше давать на каждый конкретный порт при пробросе. Я прав? Как тут лучше поступить? Убрать эти правила и оставить блокировку таких пакетов на откуп политикам?
5) Прошу поглядеть, правильно ли сделан проброс портов. Нет ли ошибок? Попросить посканировать снаружи сейчас некого, а изнутри внешние порты просканировать не получается (пишет, что закрыто, хотя грей включен, а файер на десктопе отрублен). Хотя, по идее, должен сканить, благодаря второму правилу для проброса:
iptables --table nat ---append POSTROUTING \
--protocol tcp --destination $LAN_IP --dport 22612 --jump SNAT --to-source $LIBER_IP
6) Еще по пробросу... Сейчас выглядит довольно неуклюже из-за обилия правил (по правилу для каждого порта). Я в курсе о расширении multiport, но сам его применять не стал, опасаясь напортачить в синтаксисе. Может быть, кто-нибудь сможет привести пример, как добавить порты?
7) И снова о пробросе: допустимо ли применение списка протоколов? Т.е. можно ли указать опцию --protocol tcp,udp и завязать оба протокола на один порт (для того же DC)?
8) Как я понимаю, проброс портов на VPN интерфейсе нужно делать отдельно (для торрент-клиента, например или того же DC++ при подключении к интернет-хабам). У меня сейчас динамический IP, можно ли указать в правиле --in-interface вместо --destination (т.е. название интерфейса вместо его IP)?
P.S. Ну и в целом буду благодарен за общие поправки по перечисленным правилам и указания на корявости и упущения, которые, уверен, я тут наляпал.
Большое спасибо!