LINUX.ORG.RU
ФорумAdmin

Несколько вопросов по iptables в debian


1

1

Настраиваю роутер с 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. Ну и в целом буду благодарен за общие поправки по перечисленным правилам и указания на корявости и упущения, которые, уверен, я тут наляпал.

Большое спасибо!



Последнее исправление: Liber (всего исправлений: 1)

И чего все так в правила лезут? ИМХО достаточно общие принципы узнать, что бы в случае чего разобраться, а потом перелазить на спец. утилиты. Тот же fwbuilder. Особенно если несколько машин.

ziemin ★★
()
Ответ на: комментарий от anonymous

уточните пожалуйста, причем здесь Дебиан?

Возможно и не причем. Просто указал ОС. Мало ли, какие различия в реализациях могут быть в разных дистрибах.

И чего все так в правила лезут?

Да хз. Штатная утилита - я ее и использую. В большинстве статей, опять же, описано как поднять NAT именно с ее помощью. Т.е. инфы по ней много, проще разобраться. А сторонние утилиты пока не стал ставить, ибо новичок - с основами бы разобраться...

Liber
() автор топика

1. И так будет работать

2. Да. Тут два выбора: ACCEPT — DROP

3. Зачем такое правило? По этому интерфейсу и ходят только пакеты с заголовками, указанными в правилах. Убирай его, потом могут возникнуть конфликты с программами.

Спрашивай конкретно, всё как-то в одной теме - сложно вникнуть. А лучше - сам. Многие твои вопросы уже освящены в сети, ищи.

leader32
()
Ответ на: комментарий от leader32

Спасибо, за ответ!

3 - да, действительно. Убрал.

Спрашивай конкретно, всё как-то в одной теме - сложно вникнуть

Да, так и выходит. Кому охота читать стены чужих кривых конфигов?

А лучше - сам

Так и пришлось. Правда, на соседнем форуме дали пару советов и подборочку хороших манов на русском.

Ну вот конкретный вопрос. И в манах, и в отдельных статейках натыкался на правила, защищающие от SSH-флуда:

$IPTABLES -N allow-ssh-traffic-in
$IPTABLES -F allow-ssh-traffic-in
#Flood protection
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
  ALL RST --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
  ALL FIN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
  ALL SYN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

Мне не очень понятна суть этой защиты. Как я понимаю, единственное, что эти правила защитят под SYN-флудом - это системный стэк полуоткрытых соединений (от переполнения). Но отказ в обслуживании ведь все равно произойдет? Пакеты, приходящие от «законопослушных» клиентов будут просто теряться в флуде, несмотря на «сито» limit. Особенно, если атакующий будет произвольно изменять поле source_address флуд-пакетов.

Я прав?

Не будет ли лучше устанавливать limit не в 1/second, а, например 50/second (ну или другое число, подобранное так, чтобы стэк успевал высвобождаться)? Ведь так у «честного» клиента будет больше шансов, что его SYN пакет проскочит. Разве нет? Но при этом, в гентушных манах (там iptables неплохо расписан) стоит именно единичка. Их ведь не новички писали. Так чего я не понял?

(При этом я не спрашиваю, как _в принципе_ сторится защита от DoS - конкретный вопрос).

Liber
() автор топика
Ответ на: комментарий от Liber

правила, защищающие от SSH-флуда:

Есть пруф на эти правила? В них указаны правила, разрешающие прохождение пакетов с заданными критериями, но не указано общее правило - DROP, тогда надо ставить политику по умолчанию DROP. И потом, последнее правило я бы поставил самым первым. А так, правила неплохие, только, в них будут попадать пакеты и от нормальных адресов - там ведь не задано, для каких именно ip это правило работает.

Есть у меня ещё несколько вариантов - может, тебе они лучше подойдут, но тут используется ipset, xtables-addons для задания динамического черного списка(стырено с просторов сети):

iptables -A INPUT -p tcp -m state --state NEW --dport 22 -m recent --update --seconds 20 -j TARPIT
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -m recent --set -j ACCEPT

Первое правило проверяет наличие в динамическом списке ip-адреса отправтеля, и запись об этом адресе должна быть “моложе” 20 секунд. Иначе – TARPIT. Второе правило разрешает обращение на 22-й порт и заносит IP-адрес в динамический список.

А вот ещё есть:

iptables -N SSH
iptables -A INPUT -p tcp --dport 22 -j SSH
iptables -A DNS -m recent --update --seconds 20 --hitcount 2 --name ssh-ddos --rsource -j DROP
iptables -A SSH -m recent --set --name dns-ddos --rsource -j ACCEPT
leader32
()
Ответ на: комментарий от leader32

Есть пруф на эти правила?

Участок правил взят отсюда: http://www.gentoo.org/doc/ru/security/security-handbook.xml?part=1&chap=12

Там действительно политики в дроп выставлены.

И потом, последнее правило я бы поставил самым первым.

Я тоже не понял, почему его в конец впихали.

только, в них будут попадать пакеты и от нормальных адресов - там ведь не задано, для каких именно ip это правило работает.

Воооот... Вот именно то, чего я не мог понять. В чем тут защита? (Ну помимо защиты стека от переполнения). Успешный DoS получается. И на мой взгляд, IP тут ничем не поможет, т.к. при SYN-флуде можно совершенно спокойно его спуфить.

По моему, если поставить лимит побольше (в разумных пределах), то при не слишком сильном флуде сервис будет доступнее, чем если оставить единицу.

Есть у меня ещё несколько вариантов

У тебя какая ОС и версия iptables/netfilter? Я в своих манах (Deb.Sq.) не нашел таргета TARPIT. Или он юзерский?

Как я понял, это правила защиты от брута? Я у себя сделал так:

# SSH_DECIDE chain: checks, is SSH access allowed
#       (invoked by SSH_IN_RULES chain)

$iptables --new-chain SSH_DECIDE
$iptables --flush SSH_DECIDE
# SSH-brute protection:
[ "$LOG" = "true" ] && $iptables --append SSH_DECIDE --match conntrack --ctstate NEW --match recent --name bruters --rcheck --seconds $SSH_BRUTE_TIME -$
$iptables --append SSH_DECIDE --match conntrack --ctstate NEW \
        --match recent --name bruters --update --seconds $SSH_BRUTE_TIME --hitcount $SSH_BRUTE_HITS --jump DROP
# SSH-Flood protection:
$( [ "$FLOOD_CONTROL" != "true" ] || [ "$SSH_FLOOD_CONTROL" != "true" ] ) && $iptables --append SSH_DECIDE --jump ACCEPT
$iptables --append SSH_DECIDE --protocol tcp --tcp-flags ALL SYN \
        --match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump ACCEPT
$iptables --append SSH_DECIDE --protocol tcp --tcp-flags ALL FIN \
        --match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump ACCEPT
$iptables --append SSH_DECIDE --protocol tcp --tcp-flags ALL RST \
        --match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump ACCEPT


# SSH_IN_RULES chain: processes SSH access attempts

$iptables --new-chain SSH_IN_RULES
$iptables --flush SSH_IN_RULES
# Allow established connections without limitations:
$iptables --append SSH_IN_RULES --protocol tcp --destination-port $SSH_PORT --match state --state RELATED,ESTABLISHED --jump ACCEPT
# Count and estimate new connections:
$iptables --append SSH_IN_RULES --protocol tcp --in-interface $LAN_IFACE --destination-port $SSH_PORT \
        --match conntrack --ctstate NEW --match recent --name bruters --set --jump SSH_DECIDE
# Kick all other ugly bastards! >:-))
$iptables --append SSH_IN_RULES --protocol tcp --destination-port $SSH_PORT --jump DROP
А в цепь INPUT воткнут джамп на SSH_IN_RULES.

А вот ещё есть:

Любопытный вариант, спасибо. Только не понятно, чо за цепь DNS. Опечатка?

У меня в общем правиле на SYN-флуд тоже бан флудеров предусмотрен (только --rcheck вместо --update - пока насчет ложных срабатываний не уверен):

# SYN_FLOOD_CHECK chain: Limit count of accepted packages

$iptables --new-chain SYN_FLOOD_CHECK
$iptables --flush SYN_FLOOD_CHECK

# Drop packages of banned flooders:
[ "$LOG" = "true" ] && [ "$BAN_SYN_FLOODERS" = "true" ] && {
        $iptables --append SYN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $SYN_FLOODERS_BANTIME --hitcount 1 --match limit --limit 1$
}
[ "$BAN_SYN_FLOODERS" = "true" ] && {
        $iptables --append SYN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $SYN_FLOODERS_BANTIME --hitcount 1 --jump DROP
}
# SYN flood trigger:
$iptables --append SYN_FLOOD_CHECK --match limit --limit $SYN_FLOOD_RATE --limit-burst $SYN_FLOOD_THRESHOLD --jump RETURN
# Limit reached, drop package and add sender to flooders list:
[ "$LOG" = "true" ] && $iptables --append SYN_FLOOD_CHECK --match limit --limit 5/minute --jump ULOG --ulog-prefix "SYN flood: "
$iptables --append SYN_FLOOD_CHECK --match recent --name flooders --set --jump DROP

Только вот есть у меня одно сомнение... Насколько мне известно (вычитал), файервол начинает сильно завешивать систему, если в нем достаточно много правил (около 1,5-2 тыс.). Мне любопытно, как в этом плане расширение recent себя ведет. Ведь даже при слабом DDoS'e табличка flooders забьется вусмерть махом.

Хотя мне кажется это так, баловство по большому счету. Ну или в лучшем случае защита от пионЭрии. Как файервол ни настраивай, под хорошим DDoS'ом сеть (или машина) ляжет враз.

Liber
() автор топика
Ответ на: комментарий от leader32

У меня вот другая проблема сейчас. Не могу понять, почему не работает вот этот участок правил:

$iptables --new-chain ICMP_RULES
$iptables --flush ICMP_RULES
$iptables --append ICMP_RULES --protocol icmp --icmp-type 8 --jump ACCEPT
$iptables --append ICMP_RULES --protocol icmp --icmp-type time-exceeded --jump ACCEPT
$iptables --append ICMP_RULES --protocol icmp --icmp-type destination-unreachable --jump ACCEPT
#$iptables --append ICMP_RULES --protocol icmp --jump ACCEPT
# log and deny others:
#[ "$LOG" = "true" ] && $iptables --append ICMP_RULES --protocol icmp --match limit --limit 1/minute --limit-burst 1 --jump ULOG --ulog-prefix "Bad ICMP"
$iptables --append ICMP_RULES --protocol icmp --jump DROP

^ с таким вот правилом пинговать не хочет. Как только раскомментирую строчку с безусловным разрешением icmp - начинают бегать. Цепь добавлена в --table filter: INPUT, OUTPUT, FORWARD.

Наверное, я выпустил из виду еще какой-то тип ICMP-пакета, который для успешного пингования необходимо пропускать... Но у меня уже мозги закипают. Навскидку не скажешь, какой именно?

Liber
() автор топика
Ответ на: комментарий от Liber

не нашел таргета TARPIT

apt-get install xtables-addons, затем проверяй на «полигонном» правиле:

iptables -A FORWARD -s 1.2.3.4 -d 127.0.0.1 -p tcp --dport 12345 -j TARPIT
цель TARPIT работает только с протоколом tcp. А вообще, на netfilter,org есть целая страничка по всем этим дополнениям, там много интересного найдешь. Если сможешь из них написать интересные правила - выкладывай, обсудим.

чо за цепь DNS. Опечатка?

ага, там были похожие правила для защиты от DNS-Flood'a

# Drop packages of banned flooders:
--match limit --limit 1$

пакеты дают взятки файерволу? но мы-то знаем, что linux - opensource, non-commercial, денег не умеет в принципе брать :) и потом, почему в комменте «Packages»? а не packets?

как в этом плане расширение recent себя ведет

Самому интересно было, все эти правила испытывать, надо бы скрипт написать, «тестовый стенд» собрать, на виртуалках, на физических серверах

под хорошим DDoS'ом сеть (или машина) ляжет враз

может. Тут, мне кажется, надо сетевые экраны выносить до самого сервера, если конечно того позволяют средства и мощности. Ещё где-то читал про сетевые экраны, абсолютно не обнаруживаемые ничем, без ip-адреса, но решения пока что аппаратные.

leader32
()
Ответ на: комментарий от Liber

навскидку...кажется, там нулевой тип - это отправка пинга, а восьмой - ответ на запрос

iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
кстати, пингуешь с локалхоста? или с другой машины? можно посмотреть ещё тут

iptables -p icmp -h

если любишь по манам смотреть, или здесь http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml

leader32
()
Ответ на: комментарий от leader32

навскидку...кажется, там нулевой тип - это отправка пинга, а восьмой - ответ на запрос

Ты оказался прав, спасибо!

Что до остального - обязательно попробую, но позже. Куча всего навалилась, не до настройки фаера.

Liber
() автор топика
Ответ на: комментарий от leader32

пакеты дают взятки файерволу? но мы-то знаем, что linux - opensource, non-commercial, денег не умеет в принципе брать :)

Да это я копировал из терминала, строчка не влезла. Я не заморачивался на оформление логирующих правил (все равно следом правило с такими же критериями) - писал в одну строчку, чтоб глаза не мозолили.

и потом, почему в комменте «Packages»? а не packets?

По наитию писал. Вроде, поправил.

может. Тут, мне кажется, надо сетевые экраны выносить до самого сервера, если конечно того позволяют средства и мощности.

Ну да, по нормальному тут комплексный подход нужен. Я все эти изыски с iptables (защита от флуда, брута и т.п.) рассматриваю больше как упражнения для общего развития и защиту от пионЭрии :)

Liber
() автор топика
Ответ на: комментарий от Liber

А мне вот интересно, насколько хорошо умеет защищаться iptables от DDoS? Всегда анализирую, думаю, когда вижу новые правила, методы защиты от ддоса

leader32
()
Ответ на: комментарий от leader32

Уже доводилось сталкиваться на практике?

Liber
() автор топика
Ответ на: комментарий от leader32

Короче, вот какая байда вышла в результате ковыряния в мануалах и разбора тематических статеек из гугля. Даже сам не ожидал. ))

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

Взгляни, какая фигня получилась в итоге. Хотя интерес тут может представлять, наверное, разве что реализация проброса портов (в конце, лениво мне было для каждого порта по 4 правила вручную писать >:)

#!/bin/bash

# set -x



###
#	Variables definition
###


# Network parameters (interfaces names, IPs and so on)

source /usr/local/include/shared_vars.bash

# Ensure that script will be launched only once on system startup:
#	(if-pre-up event)
[ "$IFACE" = "$WAN_IFACE" ] || exit 0
/usr/local/bin/make-log-entry.bash -n NAT-script \
	-m "Started configuring firewall with $SHELL" \
	-l s,d


# Local parameters

iptables="iptables"
PORTS_MAPPED=0


# Firewall settings

# Default policies:
#POLICY_DEFAULT="ACCEPT"
POLICY_DEFAULT="DROP"
POLICY_INPUT="$POLICY_DEFAULT"
POLICY_OUPUT="ACCEPT"
POLICY_FORWARD="$POLICY_DEFAULT"

# Antiflood settings:
FLOOD_CONTROL="true"
KERNEL_ANTIFLOOD_SETTINGS="false"

SYN_FLOOD_CONTROL="true"
SYN_FLOOD_THRESHOLD=150
SYN_FLOOD_RATE="100/second"
BAN_SYN_FLOODERS="true"
SYN_FLOODERS_BANTIME=60

FIN_FLOOD_CONTROL="true"
FIN_FLOOD_THRESHOLD=150
FIN_FLOOD_RATE="100/second"
BAN_FIN_FLOODERS="true"
FIN_FLOODERS_BANTIME=60

RST_FLOOD_CONTROL="true"
RST_FLOOD_THRESHOLD=150
RST_FLOOD_RATE="100/second"
BAN_RST_FLOODERS="true"
RST_FLOODERS_BANTIME=60

# SSH security settings:
SSH_FLOOD_CONTROL="true"
SSH_FLOOD_THRESHOLD=5
SSH_FLOOD_RATE="1/second"
SSH_BRUTE_TIME=600
SSH_BRUTE_HITS=10

PORTSCAN_CONTROL="true"

# Log level:
LOG_NONE=0	# Disable logging
LOG_IMPORTANT=1	# Log important activity (flood and brute attempts, network errors etc)
LOG_UNKNOWN=2	# Log packets if no rule found
LOG_ALL=3	# Log everything (including previous cases)

LOG=$LOG_IMPORTANT

if [ $LOG -ge $LOG_ALL ]; then
	ACCEPT="LOG_ACCEPT"
	REJECT="LOG_REJECT"
	DROP="LOG_DROP"
else
	ACCEPT="ACCEPT"
	REJECT="REJECT"
	DROP="DROP"
fi


# See also port mapping settings in corresponding section below...



###
#	Set kernel network parameters
###


# Allow forwarding and masquerading

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


# Some others kernel settings

echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts


# Some settings to decrease flood-attacks efficiency

[ "$KERNEL_ANTIFLOOD_SETTINGS" = "true" ] && {
	# Connection closing timeout, seconds (def. 60):
	echo "30" > /proc/sys/net/ipv4/tcp_fin_timeout
	# KeepAlive-connections check frequency, seconds (def. 7200):
	echo "1800" > /proc/sys/net/ipv4/tcp_keepalive_time
	# TCP window (MRU analogue) scaling, flag (def. 1):
	echo "1" > /proc/sys/net/ipv4/tcp_window_scaling
	# Max half-open connections, pieces (def. 512):
	echo "648" > /proc/sys/net/ipv4/tcp_max_syn_backlog
	# Max half-open connections revival attempts, times (def. 5):
	echo "3" > /proc/sys/net/ipv4/tcp_synack_retries
}


###
# 	Sweep rules
###

$iptables --flush
$iptables --delete-chain
$iptables --table nat --flush
$iptables --table nat --delete-chain
$iptables --table mangle --flush
$iptables --table mangle --delete-chain



###
#	Default policies
###

# Policies for default chains of _filter_ table:
$iptables --policy INPUT $POLICY_INPUT
$iptables --policy OUTPUT $POLICY_OUPUT
$iptables --policy FORWARD $POLICY_FORWARD



###
#	Main filter table targets with logging
###


# LOG_ACCEPT chain: log packet and accept it

$iptables --new-chain LOG_ACCEPT
$iptables --flush LOG_ACCEPT
$iptables --append LOG_ACCEPT --jump ULOG --ulog-prefix "Log all, ACCEPT:"
$iptables --append LOG_ACCEPT --jump ACCEPT


# LOG_REJECT chain: log packet (if log_all is enabled) and accept it

$iptables --new-chain LOG_REJECT
$iptables --flush LOG_REJECT
$iptables --append LOG_REJECT --jump ULOG --ulog-prefix "Log all, REJECT:"
$iptables --append LOG_REJECT --jump REJECT


# LOG_DROP chain: log packet (if log_all is enabled) and drop it

$iptables --new-chain LOG_DROP
$iptables --flush LOG_DROP
$iptables --append LOG_DROP --jump ULOG --ulog-prefix "Log all, DROP:"
$iptables --append LOG_DROP --jump DROP

Liber
() автор топика
Ответ на: комментарий от leader32
###
#	Attacks and errors detection chains
###


# DROP_INVALID chain: Drop invalid packages

$iptables --new-chain DROP_INVALID
$iptables --flush DROP_INVALID
# Obviously invalid packages:
$iptables --append DROP_INVALID --match state --state INVALID --jump $DROP
# Suspicious packages:
$iptables --append DROP_INVALID --protocol tcp ! --syn --match state --state NEW --jump $DROP


# SYN_FLOOD_CHECK chain: Limit count of accepted packages

$iptables --new-chain SYN_FLOOD_CHECK
$iptables --flush SYN_FLOOD_CHECK

# Drop packages of banned flooders:
[ $LOG -ge $LOG_IMPORTANT ] && [ "$BAN_SYN_FLOODERS" = "true" ] && {
	$iptables --append SYN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $SYN_FLOODERS_BANTIME --hitcount 1 --match limit --limit 1/minute --jump ULOG --ulog-prefix "SYN flood ban:"
}
[ "$BAN_SYN_FLOODERS" = "true" ] && {
	$iptables --append SYN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $SYN_FLOODERS_BANTIME --hitcount 1 --jump $DROP
}
# SYN flood trigger:
$iptables --append SYN_FLOOD_CHECK --match limit --limit $SYN_FLOOD_RATE --limit-burst $SYN_FLOOD_THRESHOLD --jump RETURN
# Limit reached, drop package and add sender to flooders list:
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append SYN_FLOOD_CHECK --match limit --limit 5/minute --jump ULOG --ulog-prefix "SYN flood: "
$iptables --append SYN_FLOOD_CHECK --match recent --name flooders --set --jump $DROP


# FIN_FLOOD_CHECK chain: Limit count of accepted packages

$iptables --new-chain FIN_FLOOD_CHECK
$iptables --flush FIN_FLOOD_CHECK
# Drop packages of banned flooders:
[ $LOG -ge $LOG_IMPORTANT ] && [ "$BAN_FIN_FLOODERS" = "true" ] && {
	$iptables --append FIN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $FIN_FLOODERS_BANTIME --hitcount 1 --match limit --limit 1/minute --jump ULOG --ulog-prefix "FIN flood ban:"
}
[ "$BAN_FIN_FLOODERS" = "true" ] && {
	$iptables --append FIN_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $FIN_FLOODERS_BANTIME --hitcount 1 --jump $DROP
}
# FIN flood trigger:
$iptables --append FIN_FLOOD_CHECK --match limit --limit $FIN_FLOOD_RATE --limit-burst $FIN_FLOOD_THRESHOLD --jump RETURN
# Limit reached, drop package and add sender to flooders list:
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append FIN_FLOOD_CHECK --match limit --limit 5/minute --jump ULOG --ulog-prefix "FIN flood: "
$iptables --append FIN_FLOOD_CHECK --match recent --name flooders --set --jump $DROP


# RST_FLOOD_CHECK chain: Limit count of accepted packages

$iptables --new-chain RST_FLOOD_CHECK
$iptables --flush RST_FLOOD_CHECK
# Drop packages of banned flooders:
[ $LOG -ge $LOG_IMPORTANT ] && [ "$BAN_FIN_FLOODERS" = "true" ] && {
	$iptables --append RST_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $RST_FLOODERS_BANTIME --hitcount 1 --match limit --limit 1/minute --jump ULOG --ulog-prefix "RST flood ban:"
}
[ "$BAN_RST_FLOODERS" = "true" ] && {
	$iptables --append RST_FLOOD_CHECK --match recent --name flooders --rcheck --seconds $RST_FLOODERS_BANTIME --hitcount 1 --jump $DROP
}
# RST flood trigger:
$iptables --append RST_FLOOD_CHECK --match limit --limit $RST_FLOOD_RATE --limit-burst $RST_FLOOD_THRESHOLD --jump RETURN
# Limit reached, drop package and add sender to flooders list:
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append RST_FLOOD_CHECK --match limit --limit 5/minute --jump ULOG --ulog-prefix "RST flood: "
$iptables --append RST_FLOOD_CHECK --match recent --name flooders --set --jump $DROP


# PORT_SCAN_CHECK chain: Deny port scan attempts

$iptables --new-chain PORT_SCAN_CHECK
$iptables --flush PORT_SCAN_CHECK

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL FIN,URG,PSH --match limit --limit 5/minute --jump ULOG --ulog-prefix "NMAP-XMAS:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL FIN,URG,PSH --jump $DROP

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL ALL --match limit --limit 5/minute --jump ULOG --ulog-prefix "XMAS:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL ALL --jump $DROP

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG --match limit --limit 5/minute --jump ULOG --ulog-prefix "XMAS-PSH:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG --jump $DROP

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL NONE --match limit --limit 5/minute --jump ULOG --ulog-prefix "NULL_SCAN:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags ALL NONE --jump $DROP

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags SYN,RST SYN,RST --match limit --limit 5/minute --jump ULOG --ulog-prefix "SYN/RST:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags SYN,RST SYN,RST --jump $DROP

[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags SYN,FIN SYN,FIN --match limit --limit 5/minute --jump ULOG --ulog-prefix "SYN/FIN:"
$iptables --append PORT_SCAN_CHECK --protocol tcp --tcp-flags SYN,FIN SYN,FIN --jump $DROP



Liber
() автор топика
Ответ на: комментарий от leader32
###
#	Basic chains
###


# SSH rules
#
#	Consists of 3 chains:
#	INPUT -> SSH_IN_RULES -> SSH_FLOOD_CHECK -> SSH_BRUTE_CHECK
#
#	built-in INPUT chain calls SSH_IN_RULES if TCP packet whith SSH dport comes
#	SSH_IN_RULES allows established connections and calls SSH_FLOOD_CHECK for packets
#		from allowed interfaces, drops all others
#	SSH_FLOOD_CHECK catches flooders and let SSH_IN_RULES kick them, calls
#		SSH_BRUTE_CHECK for non-flood packets or if antiflood mode is off.
#	SSH_BRUTE_CHECK catches and bans bruters, lets in others

# SSH_BRUTE_CHECK chain: catches and bans bruters
#	(invoked by SSH_FLOOD_CHECK chain)

$iptables --new-chain SSH_BRUTE_CHECK
$iptables --flush SSH_BRUTE_CHECK
# SSH-brute protection:
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append SSH_BRUTE_CHECK --match conntrack --ctstate NEW --match recent --name bruters --rcheck --seconds $SSH_BRUTE_TIME --hitcount $SSH_BRUTE_HITS --jump ULOG --ulog-prefix "SSH-BRUTE:"
$iptables --append SSH_BRUTE_CHECK --match conntrack --ctstate NEW \
	--match recent --name bruters --update --seconds $SSH_BRUTE_TIME --hitcount $SSH_BRUTE_HITS --jump $DROP
$iptables --append SSH_BRUTE_CHECK --jump $ACCEPT


# SSH_FLOOD_CHECK chain: checks, is SSH access allowed
#	(invoked by SSH_IN_RULES chain)

$iptables --new-chain SSH_FLOOD_CHECK
$iptables --flush SSH_FLOOD_CHECK
# SSH-Flood protection:
$( [ "$FLOOD_CONTROL" != "true" ] || [ "$SSH_FLOOD_CONTROL" != "true" ] ) && $iptables --append SSH_FLOOD_CHECK --jump SSH_BRUTE_CHECK
$iptables --append SSH_FLOOD_CHECK --protocol tcp --tcp-flags ALL SYN \
	--match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump SSH_BRUTE_CHECK
$iptables --append SSH_FLOOD_CHECK --protocol tcp --tcp-flags ALL FIN \
	--match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump SSH_BRUTE_CHECK
$iptables --append SSH_FLOOD_CHECK --protocol tcp --tcp-flags ALL RST \
	--match limit --limit $SSH_FLOOD_RATE --limit-burst $SSH_FLOOD_THRESHOLD --jump SSH_BRUTE_CHECK
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append SSH_FLOOD_CHECK --jump ULOG --ulog-prefix "SSH-FLOOD:"


# SSH_IN_RULES chain: processes SSH access attempts

$iptables --new-chain SSH_IN_RULES
$iptables --flush SSH_IN_RULES
# Allow established connections without limitations:
$iptables --append SSH_IN_RULES --match state --state RELATED,ESTABLISHED --jump $ACCEPT
# Count and estimate new connections:
$iptables --append SSH_IN_RULES --protocol tcp --in-interface $LAN_IFACE \
	--match conntrack --ctstate NEW --match recent --name bruters --set --jump SSH_FLOOD_CHECK
# Kick all other ugly bastards! >:-))
$iptables --append SSH_IN_RULES --jump $DROP


# ICMP_RULES chain: Allow ping & deny other ICMP

$iptables --new-chain ICMP_RULES
$iptables --flush ICMP_RULES
$iptables --append ICMP_RULES --protocol icmp --icmp-type echo-request --jump $ACCEPT
$iptables --append ICMP_RULES --protocol icmp --icmp-type echo-reply --jump $ACCEPT
$iptables --append ICMP_RULES --protocol icmp --icmp-type time-exceeded --jump $ACCEPT
$iptables --append ICMP_RULES --protocol icmp --icmp-type destination-unreachable --jump $ACCEPT
# log and deny others:
[ $LOG -ge $LOG_IMPORTANT ] && $iptables --append ICMP_RULES --protocol icmp --match limit --limit 3/minute --limit-burst 1 --jump ULOG --ulog-prefix "Bad ICMP:"
$iptables --append ICMP_RULES --protocol icmp --jump $DROP


# ALLOW_STATEFULL chain: Allow packages of established and related connections

$iptables --new-chain ALLOW_STATEFULL
$iptables --flush ALLOW_STATEFULL
$iptables --append ALLOW_STATEFULL --protocol all --match state --state ESTABLISHED,RELATED --jump $ACCEPT


# GRINDER chain: Packages fragmentation
#	(needed because of different MTU values)

$iptables --table mangle --new-chain GRINDER
$iptables --table mangle --flush GRINDER
$iptables --table mangle --append GRINDER --protocol tcp --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu



###
#	Networks interaction chains
###


# RESTRICTED_IN: common denial rules for incoming packets

$iptables --new-chain RESTRICTED_IN
$iptables --flush RESTRICTED_IN
# Deny incoming broadcast packets from WAN network:
[ $LOG -ge $LOG_UNKNOWN ] && { # Restricted by policy, append in debug mode to not litter logs
	$iptables --append RESTRICTED_IN --in-interface $WAN_IFACE --destination $WAN_BROADCAST --jump $DROP
}


# RESTRICTED_OUT: common denial rules for outgoing packets

$iptables --new-chain RESTRICTED_OUT
$iptables --flush RESTRICTED_OUT
# Nothing is thought out yet, only template for now


# RESTRICTED_FORWARD: common denial rules for transit packets

$iptables --new-chain RESTRICTED_FORWARD
$iptables --flush RESTRICTED_FORWARD
# Deny transit broadcast packets between internal and external networks:
$iptables --append RESTRICTED_FORWARD --out-interface $WAN_IFACE --destination $WAN_BROADCAST --jump $DROP
[ $LOG -ge $LOG_UNKNOWN ] && { # Restricted by policy, append in debug mode to not litter logs
	$iptables --append RESTRICTED_FORWARD --in-interface $WAN_IFACE --destination $LAN_BROADCAST --jump $DROP
	$iptables --append RESTRICTED_FORWARD --in-interface $INET_IFACE --destination $LAN_BROADCAST --jump $DROP
}


# ALLOWED_IN chain: common premissive rules for incoming packets

$iptables --new-chain ALLOWED_IN
$iptables --flush ALLOWED_IN
$iptables --append ALLOWED_IN --in-interface $LAN_IFACE --jump $ACCEPT


# ALLOWED_OUT chain: common premissive rules for outgoing packets

$iptables --new-chain ALLOWED_OUT
$iptables --flush ALLOWED_OUT
# Allow transit packets from internal networks to external:
[ $LOG -ge $LOG_UNKNOWN ] && { # Allowed by policy, append in debug mode to not litter logs
	$iptables --append ALLOWED_OUT --out-interface $LAN_IFACE --jump $ACCEPT
	$iptables --append ALLOWED_OUT --out-interface $WAN_IFACE --jump $ACCEPT
	$iptables --append ALLOWED_OUT --out-interface $INET_IFACE --jump $ACCEPT
}


# ALLOWED_FORWARD chain: common premissive rules for transit packets

$iptables --new-chain ALLOWED_FORWARD
$iptables --flush ALLOWED_FORWARD
$iptables --append ALLOWED_FORWARD --in-interface $LAN_IFACE --out-interface $WAN_IFACE --jump $ACCEPT
$iptables --append ALLOWED_FORWARD --in-interface $LAN_IFACE --out-interface $INET_IFACE --jump $ACCEPT


#--------------------------------------------------------------------------------------------------#

Liber
() автор топика
Ответ на: комментарий от leader32
###
#	Chains assignment and common rules
#	not suitable for detaching to separate chains
###


# Rules for local loopback traffic:
$iptables --append INPUT --in-interface lo --jump $ACCEPT
$iptables --append OUTPUT --out-interface lo --jump $ACCEPT


# INPUT chain

$iptables --append INPUT --jump DROP_INVALID
$iptables --append INPUT --protocol tcp --destination-port $SSH_PORT --jump SSH_IN_RULES
[ "$FLOOD_CONTROL" = "true" ] && {
	[ "$SYN_FLOOD_CONTROL" = "true" ] && \
		$iptables --append INPUT --protocol tcp --tcp-flags ALL SYN --jump SYN_FLOOD_CHECK
	[ "$FIN_FLOOD_CONTROL" = "true" ] && \
		$iptables --append INPUT --protocol tcp --tcp-flags ALL FIN --jump FIN_FLOOD_CHECK
	[ "$RST_FLOOD_CONTROL" = "true" ] && \
		$iptables --append INPUT --protocol tcp --tcp-flags ALL RST --jump RST_FLOOD_CHECK
}
[ "$PORTSCAN_CONTROL" = "true" ] && $iptables --append INPUT --jump PORT_SCAN_CHECK
$iptables --append INPUT --protocol icmp --jump ICMP_RULES
$iptables --append INPUT --jump ALLOW_STATEFULL
$iptables --append INPUT --jump RESTRICTED_IN
$iptables --append INPUT --jump ALLOWED_IN
[ $LOG -ge $LOG_UNKNOWN ] && $iptables --append INPUT --jump ULOG --ulog-prefix "No INPUT rule, $POLICY_INPUT:"


# OUTPUT chain

$iptables --append OUTPUT --jump DROP_INVALID
$iptables --append OUTPUT --protocol icmp --jump ICMP_RULES
$iptables --append OUTPUT --jump ALLOW_STATEFULL
$iptables --append OUTPUT --jump RESTRICTED_OUT
$iptables --append OUTPUT --jump ALLOWED_OUT
[ $LOG -ge $LOG_UNKNOWN ] && $iptables --append OUTPUT --jump ULOG --ulog-prefix "No OUTPUT rule, $POLICY_OUPUT:"


# FORWARD chain

$iptables --append FORWARD --jump DROP_INVALID
[ "$FLOOD_CONTROL" = "true" ] && {
        [ "$SYN_FLOOD_CONTROL" = "true" ] && \
                $iptables --append FORWARD --protocol tcp --tcp-flags ALL SYN --jump SYN_FLOOD_CHECK
        [ "$FIN_FLOOD_CONTROL" = "true" ] && \
                $iptables --append FORWARD --protocol tcp --tcp-flags ALL FIN --jump FIN_FLOOD_CHECK
        [ "$RST_FLOOD_CONTROL" = "true" ] && \
                $iptables --append FORWARD --protocol tcp --tcp-flags ALL RST --jump RST_FLOOD_CHECK
}
[ "$PORTSCAN_CONTROL" = "true" ] && $iptables --append FORWARD --jump PORT_SCAN_CHECK
$iptables --append FORWARD --protocol icmp --jump ICMP_RULES
$iptables --append FORWARD --jump ALLOW_STATEFULL
$iptables --append FORWARD --jump RESTRICTED_FORWARD
$iptables --append FORWARD --jump ALLOWED_FORWARD
[ $LOG -ge $LOG_UNKNOWN ] && $iptables --append FORWARD --jump ULOG --ulog-prefix "No FORWARD rule, $POLICY_FORWARD:"



###
#	NAT
###


# Enable NAT masquerading for LAN->WAN/INET packets:
$iptables --table nat --append POSTROUTING --out-interface $WAN_IFACE --source $LAN_NETWORK_ADDR --jump MASQUERADE
$iptables --table nat --append POSTROUTING --out-interface $INET_IFACE --source $LAN_NETWORK_ADDR --jump MASQUERADE
# Enable packets fragmentation:
$iptables --table mangle --append FORWARD --jump GRINDER


# Port address translation (port mapping)
#	Adds 4 corresponding firewall rules for each mapped port

PORTS_MAPPED=0
PORTS_MAPPED_LIST=""

map_port() {
	# Parse passed parameters:
	local LAN_ADDR=$( echo -n "$1" | cut -d\; -f1 | sed 's/ \+//g' )
	local LAN_PORT=$( echo -n "$LAN_ADDR" | cut -d\: -f2 )
	local LAN_ADDR=$( echo -n "$LAN_ADDR" | cut -d\: -f1 )
	local EXT_IFACE=$( echo -n "$1" | cut -d\; -f2 | sed 's/ \+//g' )
	local EXT_IP=$( echo -n "$1" | cut -d\; -f3 | sed 's/ \+//g' )
	local EXT_PORT=$( echo -n "$1" | cut -d\; -f4 | sed 's/ \+//g' )
	local PROTO=$( echo -n "$1" | cut -d\; -f5 | sed 's/ \+//g' )
	local DESCR=$( echo -n "$1" | cut -d\; -f6 | sed 's/^ \+//' )

	# Counting:
	PORTS_MAPPED=$(( $PORTS_MAPPED + 1 ))
	
	# Enable NAT if WAN client tries to reach LAN service via service WAN address:
	$iptables --table nat --append PREROUTING \
		--protocol $PROTO --destination $EXT_IP --destination-port $EXT_PORT \
		--jump DNAT --to-destination $LAN_ADDR:$LAN_PORT \
		--match comment --comment "PM: $DESCR" 
	
	# Enable NAT if LAN client tries reach LAN service via service WAN address:
	#	(or service will try to answer directly to LAN client)
	$iptables --table nat --append POSTROUTING \
		--protocol $PROTO --source $LAN_NETWORK_ADDR --destination $LAN_ADDR --destination-port $LAN_PORT \
		--jump SNAT --to-source $LAN_IP \
		--match comment --comment "PM: $DESCR - loop"

	# Allow clients access LAN service via service WAN address:
	$iptables --append ALLOWED_FORWARD \
		--protocol $PROTO --out-interface $LAN_IFACE \
		--destination $LAN_ADDR --destination-port $LAN_PORT --jump $ACCEPT \
		--match comment --comment "PM: $DESCR - allow forwarding"
	
	# Direct packages to LAN addres of service if router itself tries to reach LAN service
	#	via service WAN address	(to simplify routing routines):
	$iptables --table nat --append OUTPUT \
		--protocol $PROTO --destination $EXT_IP --destination-port $EXT_PORT \
		--jump DNAT --to-destination $LAN_ADDR:$LAN_PORT \
		--match comment --comment "PM: $DESCR - redirect"
}

# exit 0

# Liber

# Greylink DC++:
map_port "$LIBER_IP:12340; $WAN_IFACE;  $WAN_IP;  12340; tcp; Liber Greylink DC++ WAN TCP"
map_port "$LIBER_IP:12341; $WAN_IFACE;  $WAN_IP;  12341; udp; Liber Greylink DC++ WAN UDP"
map_port "$LIBER_IP:12342; $WAN_IFACE;  $WAN_IP;  12342; tcp; Liber Greylink DC++ WAN TLS"
map_port "$LIBER_IP:12340; $INET_IFACE; $INET_IP; 12340; tcp; Liber Greylink DC++ INET TCP"
map_port "$LIBER_IP:12341; $INET_IFACE; $INET_IP; 12341; udp; Liber Greylink DC++ INET UDP"
map_port "$LIBER_IP:12342; $INET_IFACE; $INET_IP; 12342; tcp; Liber Greylink DC++ INET TLS"
# uTorrent:
map_port "$LIBER_IP:12343; $WAN_IFACE;  $WAN_IP;  12343; tcp; Liber uTorrent WAN TCP"
map_port "$LIBER_IP:12343; $WAN_IFACE;  $WAN_IP;  12343; udp; Liber uTorrent WAN UDP"
map_port "$LIBER_IP:12343; $INET_IFACE; $INET_IP; 12343; tcp; Liber uTorrent INET TCP"
map_port "$LIBER_IP:12343; $INET_IFACE; $INET_IP; 12343; udp; Liber uTorrent INET UDP"
# Miranda IM:
map_port "$LIBER_IP:12344; $INET_IFACE; $INET_IP; 12344; tcp; Liber Miranda IM INET TCP"
map_port "$LIBER_IP:12345; $INET_IFACE; $INET_IP; 12345; tcp; Liber Miranda IM INET TCP"
map_port "$LIBER_IP:12346; $INET_IFACE; $INET_IP; 12346; tcp; Liber Miranda IM INET TCP"
map_port "$LIBER_IP:12344; $INET_IFACE; $INET_IP; 12344; udp; Liber Miranda IM INET UDP"
map_port "$LIBER_IP:12345; $INET_IFACE; $INET_IP; 12345; udp; Liber Miranda IM INET UDP"
map_port "$LIBER_IP:12346; $INET_IFACE; $INET_IP; 12346; udp; Liber Miranda IM INET UDP"

# Snake

# Greylink DC++:
map_port "$SNAKE_IP:43210; $WAN_IFACE;  $WAN_IP;  43210; tcp; Snake Greylink DC++ WAN TCP"
map_port "$SNAKE_IP:43211; $WAN_IFACE;  $WAN_IP;  43211; udp; Snake Greylink DC++ WAN UDP"
map_port "$SNAKE_IP:43212; $WAN_IFACE;  $WAN_IP;  43212; tcp; Snake Greylink DC++ WAN TLS"
map_port "$SNAKE_IP:43210; $INET_IFACE; $INET_IP; 43210; tcp; Snake Greylink DC++ INET TCP"
map_port "$SNAKE_IP:43211; $INET_IFACE; $INET_IP; 43211; udp; Snake Greylink DC++ INET UDP"
map_port "$SNAKE_IP:43212; $INET_IFACE; $INET_IP; 43212; tcp; Snake Greylink DC++ INET TLS"
# uTorrent:
map_port "$SNAKE_IP:43213; $WAN_IFACE;  $WAN_IP;  43213; tcp; Snake uTorrent WAN TCP"
map_port "$SNAKE_IP:43213; $WAN_IFACE;  $WAN_IP;  43213; udp; Snake uTorrent WAN UDP"
map_port "$SNAKE_IP:43213; $INET_IFACE; $INET_IP; 43213; tcp; Snake uTorrent INET TCP"
map_port "$SNAKE_IP:43213; $INET_IFACE; $INET_IP; 43213; udp; Snake uTorrent INET UDP"

Еще не все отшлифовано (некоторые моменты в коментах и критериях правил сейчас при предпросмотре глаз резанули), а режим LOG=$LOG_ALL даже еще не отдебажен... Но в целом уже работает! )))

TLDR, конечно, но буду благодарен за конструктивную критику, если не лениво. ;)

Liber
() автор топика
Ответ на: комментарий от leader32

Еще вопрос по ULOG. Хочу сделать несколько разных лог-файлов под разные задачи (например, лог ошибок/лог активности юзверей). Как я понял, он не умеет распихивать сообщения из разных nlgroup по разным лог-файлам. То есть, для этого надо запускать несколько экземпляров ulogd с разными конфигами, в которых указаны разные nlgroup и лог-файлы. Что не очень удобно.

Нашел в гугле инфу про тулзу 'specter' (форк от улога с поддержкой нескольких nlgroup одним демоном). Но вот подумал, что может быть есть что-то более новое/удобное. Можешь посоветовать что-то конкретное? Желательно что-то элементарное, навроде ulog'а.

vel, решил, что все-таки зря открыл новую тему. Может, ты еще какой вариант подскажешь?

Спасибо!

Liber
() автор топика
Ответ на: комментарий от Liber

даа...неплохо написано, но главное - работает Единственно, слишком много правил, кажется. Глаз не то что режут, мозг подвисает. Ничего, сначала так будет, со временем научишься лаконично всё описывать.

Можно использовать ipset, но у тебя тогда комменты не пройдут (которые DC++,uTorrent)

leader32
()
Ответ на: комментарий от Liber

конкретно с этим не разбирался, логгирование iptables не изучал настолько глубоко, сказать что-то конструктивное не смогу(

leader32
()
Ответ на: комментарий от leader32

Да, работает, нареканий нет )

А поскольку собственное творчество, так и понимаю достаточно хорошо все, что там делается.

Более того, конструкции с логированием всех пакетов (принятых/брошенных, оставленных политикам) пригодились при отладки IPsec/L2TP.

Глаз не то что режут, мозг подвисает.

Конечно, объем-то изрядный. А оно тебе надо вникать? )

но у тебя тогда комменты не пройдут

Да, с ними мне пока как-то удобнее. Легче iptables -L читать.

В любом случае, спасибо за отзыв! )

Liber
() автор топика
Ответ на: комментарий от leader32

Единственное, с чем был затык - это фрагментирование пакетов (MTU разные на интерфейсах). Но вроде разобрался.

Liber
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.