# Пример правил для шлюза локальной сети.
# Для непосредственного использования не годится!
# На шлюзе два сетевых интерфейса:
#     enp2s2 --- локальный, IP 192.168.1.1
#     enp2s3 --- глобальный, IP 88.99.100.200
# Все IP адреса и доменные имена вымышленные. Вместо них подставлять свои.

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[0:0] -A PREROUTING -d 88.99.100.200/32 -p tcp -m tcp --dport 10300 -j DNAT --to-destination 192.168.1.38:10300
[0:0] -A POSTROUTING -s 192.168.1.0/24 -o enp2s3 -j SNAT --to-source 89.99.100.200
COMMIT
# В сеции nat два правила. Первое --- пример DESTINATION NAT: все TCP пакеты,
# адресованные на реальный IP шлюза, на порт 10300, перенаправляются в локальную
# сеть, адрес получателя на IP "конверте" переписывается на адрес локального
# узла 192.168.1.38, на то-же порт 10300. Второе правило --- пример SOURCE NAT.
# Для всех пакеты, источником которых являются узлы локальной сети, переписывается
# адрес отправителя на IP "конверте", локальный адрес заменяется статическим
# реальным адресом внешнего интерфейса.

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

# Таблица filter. Программа iptables, если не указать другой таблицы,
# будет размещать правила здесь.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:enp2s2_in - [0:0]
:enp2s2_out - [0:0]
:enp2s3_in - [0:0]
:enp2s3_out - [0:0]
# Политика фильтрации по умолчанию для трёх основных цепочек:
# --- для входящих в систему пакетов;
# --- для транзитных пакетов, следующих с интерфейса на интерфейс,
#     минуя систему;
# --- для пакетов, исходящих из системы.
# Запрещено всё, что не разрешено. То есть в фильтрующих цепочках
# в идеале должны стоять разрешающие правила.
# Создание своих собственных цепочек в таблице filter. Для входящих и
# исходящих пакетов, применительно к каждому интерфейсу отдельно.
# Можно этого не делать, но так удобнее: у глобального интерфейса
# свои правила фильтрации, у локального --- свои.
[0:0] -A INPUT -i lo -j ACCEPT
# Локальный закольцовывающий интерфес безопасен, пропускаем все пакеты
# от него в систему.
[0:0] -A INPUT -p icmp -j ACCEPT
# Пропускать в систему все ICMP пакеты без ограничений. Можно и не ограничивать.
#### Старый синтаксис, ниже новый. [0:0] -A INPUT ! -p icmp -m state --state INVALID -j DROP
[0:0] -A INPUT ! -p icmp -m conntrack --ctstate INVALID -j DROP
# Если состояние пакета определить не удалось (мусор), "молча" уничтожить его. 
[0:0] -A INPUT -d 255.255.255.255/32 -j DROP
[0:0] -A INPUT -d 224.0.0.0/4 -j DROP
#### [0:0] -A INPUT -d 88.99.100.206/32 -j DROP
[0:0] -A INPUT -d 192.168.1.255/32 -j DROP
# Уничтожение широковещательных пакетов на всех интерфейсах.
[0:0] -A INPUT -i enp2s3 -j enp2s3_in
# Пакеты поступившие на глобальный интерфейс, направляются в свою цепочку.
[0:0] -A INPUT -i enp2s2 -j enp2s2_in
# Для пакетов поступивших на локльный интерфейс тоже есть своя цепочка.
# Дальше никакой пакет просто не пройдёт, но если пройдёт, то в
# соответствии с политикой будет уничтожен.

# Далее --- фильтрация транзитных пакетов, следующих с одного интерфейса
# на другой. Правила должны быть максимально точными и "узкими".
# Беспорядочный транзитных пропуск пакетов опасен!!!
[0:0] -A FORWARD -p icmp -j ACCEPT
# Пропуск пингов и понгов, а также пакетов программы traceroute.
# Свободный пропуск пингов и понгов может нести в себе угрозу!!!
#### Старый синтаксис, ниже новый. [0:0] -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Транзитные пакеты, принадлежащие уже установленной сессии пропустить
# беспрепятственно.
[0:0] -A FORWARD -i enp2s2 -p tcp -m multiport --dports 22 -j ACCEPT
# Транзитные TCP пакеты, направляемые на порт 22, пропускать
# беспрепятственно. Опасно!
[0:0] -A FORWARD -s 192.168.1.10/32 -d online.payment-system.com -i enp2s2 -p tcp -m multiport --dports 80,443 -j ACCEPT
# Хорошее правило. От конкретного узла локальной сети беспрепятсвенно
# пропускать HTTP и HTTPS пакеты на адрес, связанный с доменным именем
# какой-то платёжной системы. Преобразование имени в адрес осуществляется
# единожды, при загрузке правил. Если платёжная система сменит IP адрес,
# правила будет необходимо перезагрузить.
[0:0] -A FORWARD -s 192.168.1.41/32 -d host.taxcom.ru -i enp2s2 -p tcp -m multiport --dports 25,110,5025,5110 -j ACCEPT
[0:0] -A FORWARD -s 192.168.1.41/32 -d 55.66.77.88 -i enp2s2 -p tcp --dport 443 -j ACCEPT
# Пакеты, не соответствующие разрешающим правилам, неминуемо
# доберутся до этой точки, и попадут на правило, отправляющее
# информацию в системный журнал.
[0:0] -A FORWARD -j LOG --log-prefix "iptables:FORWARD:REJECT:" --log-level 6
# Это единственное неостанавливающее правило!
# После него --- политика по умолчанию, и попытка прорваться наружу
# будет пресечена.

# Фильтрация пакетов исходящих из системы. Для шлюза локальной сети,
# при наличии толики здравого смысла, фильтровать тут практически
# нечего.
[0:0] -A OUTPUT -o lo -j ACCEPT
[0:0] -A OUTPUT ! -p icmp  -m conntrack --ctstate INVALID -j REJECT
[0:0] -A OUTPUT -p icmp -j ACCEPT
[0:0] -A OUTPUT -o enp2s3 -j enp2s3_out
[0:0] -A OUTPUT -o enp2s2 -j enp2s2_out
# Дальше --- политика по умолчанию. 

# Нестандартная цепочка для фильтрации пакетов поступающих из
# локальной сети.
# Это беспрепятственный пропуск пакетов, для которых удалось установить
# принадлежность к сессии. Вместо традиционного --state лучше писать так:
#### Старый синтаксис, ниже новый. [0:0] -A enp2s2_in -m state --state RELATED,ESTABLISHED -j ACCEPT
[0:0] -A enp2s2_in -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A enp2s2_in -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j DROP
# Уничтожение явно фальшивых пакетов, у которых флаг не соответствует состоянию.
[0:0] -A enp2s2_in -p tcp -m conntrack --ctstate NEW -m multiport --dports 22,25,110,3128 -j ACCEPT
# К шлюзу позволен удалённый доступ по SSH. На шлюзе работает SQUID, и это очен правильно.
# И "по своместительству" шлюз ещё и почтовым сервером работает, пропускаем все пакеты
# POP3 и SMTP.
[0:0] -A enp2s2_in -s 192.168.1.24/32 -p tcp -m conntrack --ctstate NEW -m multiport --dports 20,21 -j ACCEPT
# На шлюзе есть и FTP, но доступ к нему из локальной сети открыт не всем.
[0:0] -A enp2s2_in -p udp -m conntrack --ctstate NEW -m udp --dport 53 -j ACCEPT
# На шлюзе работает DNS-серврер. Это правильно, и всем локальным узлам
# можно пользоваться его услугами.
[0:0] -A enp2s2_in -j LOG --log-prefix "iptables:enp2s2_in:REJECT:" --log-level 6
# Разрешающие правила кончились. Записываем в журнал, но уничтожать пакет
# "молча", в соответствии с политикой, нельзя: в локальной сети работают
# наши коллеги, нужно им дать знать, что их запрос выполнить нельзя.
[0:0] -A enp2s2_in -j REJECT

[0:0] -A enp2s2_out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A enp2s2_out -j ACCEPT

[0:0] -A enp2s3_in -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A enp2s3_in -p tcp -m tcp ! --tcp-flags SYN,RST,ACK SYN -m conntrack --cstate NEW -j DROP
[0:0] -A enp2s3_in -p tcp -m conntrack --ctstate NEW -m multiport --dports 22,25 -j ACCEPT
[0:0] -A enp2s3_in -p tcp -m conntrack --ctstate NEW -m multiport --dports 20,21,10300 -j ACCEPT
[0:0] -A enp2s3_in -j LOG --log-prefix "iptables:enp2s3_in:DROP:" --log-level 6

[0:0] -A enp2s3_out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A enp2s3_out -j ACCEPT
COMMIT
