Я хочу рассмотреть ситуацию, когда локальная сеть имеет выход в интернет через шлюз.
На шлюзе только почта и www.
90-99% трафика в таком случае - это трафик между локалкой и внешним интернетом.
А подключения к портам шлюза - это 1-10% трафика.
Поэтому правила обрабатывающие трафик клиентов можно поставить поближе к началу.
Фаерволл можно настроить так:
100 allow ip from me to me #(система)
# Здесь можно поставить разрешения и запрещения на доступ в интернет пользователей локалки, основанные на используемой биллинговой системе.
# Теперь нужно порезать левый и вредный трафик. Кстати о skipto. Если за шлюзом есть сеть 192.168.0.0/24, то можно хитро фильтровать вредный трафик без вреда для локалки
200 skipto 2000 ip from 192.168.0.0/24 to any
300 skipto 2000 ip from any to 192.168.0.0/24
# а после этого понаставить запрещения на частные или левые адреса
1010 deny ip from 127.0.0.0/8 to any not via lo0
1020 deny ip from any to 127.0.0.0/8 not via lo0
1030 deny ip from 10.0.0.0/8 to any
1040 deny ip from any to 10.0.0.0/8
1050 deny ip from 172.16.0.0/12 to any
1060 deny ip from any to 172.16.0.0/12
1070 deny ip from 192.168.0.0/16 to any
1080 deny ip from any to 192.168.0.0/16
1090 deny ip from 0.0.0.0/8 to any
1100 deny ip from any to 0.0.0.0/8
1110 deny ip from 169.254.0.0/16 to any
1120 deny ip from any to 169.254.0.0/16
1130 deny ip from 192.0.2.0/24 to any
1140 deny ip from any to 192.0.2.0/24
1150 deny ip from 224.0.0.0/4 to any
1160 deny ip from any to 224.0.0.0/4
1170 deny ip from 240.0.0.0/4 to any
1180 deny ip from any to 240.0.0.0/4
# таким образом, если у вас появятся сети, используещие какую-то адресацию, то их можно описать с помощью skipto выше. Чтобы они "перепрыгивали" глобальные запрещения.
# Здесь-же можно запретить левые icmp
${ipfw} add 2010 deny icmp from any to any in icmptype 5,9,13,14,15,16
${ipfw} add 2020 deny icmp from any to any frag
#после этого можно добавить правило для прозрачной прокси.
3010 fwd 127.0.0.1,8080 tcp from any to not me 80 recv ${in}
#Причем указание "to not me" позволяет не иметь проблем с доступок к собственному веб-серверу. А recv ${in} (${in} - СВОЯ переменная в скрипте фаервола) позволяет проксировать только запросы из локалки.
# после этого отправляем запросы в nat
4010 divert 8668 ip from not me to any via ${out}
# "from not me" позволяет не посылать в нат пакеты с самой машины (например с прокси-сервера). Хотя я не сравнивал оптимальность "from not me" и "from any".
#Теперь давайте посмотрим, что мы имеем 1) на внутреннем интерфейсе. Мы уже отправили на проксю запросы на порты 80 серверов инета. Пропустить пакеты на остальные порты серверов инета можно командой
5010 allow ip from not me to not me
# Ибо пакеты из локалки имеют источник - адрес компьютера в локалке, а получатель - адрес сервера в интернете.
# Такая команда пропустит пакеты, которые поступают на внутренний интерфейс, чтобы они пошли дальше на внешний.
# Теперь давайте посмотрим, что мы имеем на внешнем интерфейсе. Пакеты, идущие ИЗ локалки в инет уже прошли через нат и имеют исходным адресом внешний адрес шлюза. Поэтому правило "from not me to not me" они минуют.
# Но, пакеты, которые идут В локалку из инета пройдут через вышестоящий нат и получится, что такие пакеты будут иметь адрес источника - адес какого-нибудь сервера в интернете, а адрес назначения - адрес машины в локалке.
# Таким образом пакеты ходят из локалки в инет и из инета в локалку, при этом обрабатываются натом, форвардятся на проксю 3-4-5-6 правилами.
# Хотя точнее будет заметить, что ещё не указано, как будут идти пакеты после ната в интернет.
# Здесь можно реализовать policy based routing, который хорошо помагает, если у вас больше 1 канала в интернет или в разные локалки.
# здесь можно добавлять разрешения для локалок, до которых шлюз может дотянуться не используя свои шлюзы
6010 allow ip from me to 192.168.0.0/24 xmit ${in}
# можно добавлять 6020 allow ip from me to 172.16.0.0/24 xmit ${other}
# дальше можно добавить описание каналов в инет или другие локалки
7010 fwd ip_адрес_шлюза ip from ваш_ip_адрес to any
# насколько я понимаю, в большинстве случаев используется "классическая" ситуация - локалка-шлюз-инет. Для этой ситуации подойдет одно простое правило
#8010 allow ip from me to any
# Причем, если описаны разрешения для всех локалок и каналов, то это правило можно закомментировать.
# А вот теперь уже можно разрешать доступ к сервисам на самом шлюзе. Например можно сначала описать общедоступные:
# icmp
9000 allow icmp from any to any
#tcp
9010 allow tcp from any to me 25
9020 allow tcp from any to me 53
9030 allow tcp from any to me 80
9040 allow tcp from any to me 110
9050 allow tcp from any to me 113
9060 allow tcp from any to me 119
9070 allow tcp from any to me 587
#udp
10010 allow udp from any to me 53
10020 allow udp from any to me 123
# Исходящие и временные порты
${ipfw} add 11010 allow tcp from any to me 49152-65535
${ipfw} add 11020 allow udp from any to me 49152-65535
# На исходящих и временных портах остановлюсь поподробнее.
# С портами именно из этого диапазона устанавливается соединение, например, при скачке чего-нибудь с ftp сервера шлюза.
# Т.е. открытия 20 и 21 порта для работы ftp срервера недостаточно. Нужно открыть и эти порты.
# Кроме того, сам шлюз, устанавливая соеднения с другими серверами (например их устанавливает работающий прокси-сервер) использует эти порты.
# Могу ещё сказать, что номера 49152-65535 в FreeBSD могут изменяться через sysctl
# Попробуйте запустить команду sysctl -a | grep portrange
# Я знаю, что во FreeBSD 4.11 для одних целей используются порты 49152-65535, а для других 1024-65535
# Во FreeBSD 5.x для обоих целей используется один диапазон 49152-65535
# Лично я в FreeBSD 4.11 просто указал использовать 49152-65535 через sysctl (точнее через sysctl.conf)
# Это были общедоступные порты. Теперь можно описать разрешения к портам для отдельных машин.
# Принтер
12010 allow tcp from 192.168.0.1 to me 515
12020 allow udp from 192.168.0.1 to me 515
# ssh
13010 allow tcp from 192.168.0.1 to me 22
13020 allow tcp from 207.46.130.108 to me 22
13030 allow tcp from 207.46.250.119 to me 22
# ftp
14010 allow tcp from 192.168.0.1 to me 22
14020 allow tcp from 50.60.70.80 to me 22
# ...и так далее. Можно конечно для какого то адреса просто разрешить порты через запятую, например
#12010 allow tcp from 192.168.0.1 to me 20,21,515,10000
# можно делать и так. Это кому как нравится.
# После этого нужно запретить все
13010 deny ip from any to any
Таким образом 90% трафика обрабатывается первыми 5-10% правил.
Ещё замечу, что в FreeBSD 4.x конструкции типа "from not me to not me" не работают.
Поэтому такой фаервол будет работать на 100% на FreeBSD 5.x.
В 4.x нужно такие конструкции заменять другими.
Если вам покажется, что такой фаервол работать не будет и на 5.x, то могу сказать, что именно такой фаервол работает у меня на нескольких серверах.
Перед этим я где-то неделю анализировал хождение пакетов с помощью лога фаервола, tcpdump'а и ручки с тетрадкой.
Результатом стал такой конфиг.
Мне интересны мнения людей, на тему, что оптимальнее использовать,
4010 divert 8668 ip from not me to any via ${out}
или
4010 divert 8668 ip from any to any via ${out}
и вообще, не вызыввет ли использование "not me" больших задержек.
Буду рад услышать мнения людей, которые уже занимались сравнением быстродействия обработки той или иной конструкции.