#!/bin/sh
# /etc/rc.d/rc.firewall, define the firewall configuration, invoked from
# rc.local.

# Ссылка на этот файл конфигурации firewall помещена в файл загрузки
# системы rc.local . Часть функций firewall реализована ввиде модулей,
# поэтому сначала мы загружаем все необходимые нам модули.
/sbin/depmod -a
/sbin/modprobe ip_masq_ftp
/sbin/modprobe ip_masq_raudio
/sbin/modprobe ip_masq_irc
/sbin/modprobe ip_masq_cuseeme
/sbin/modprobe ip_masq_vdolive

# Сброс правил подсчета траффика.
ipfwadm -A -f

# Этот абзац задает правила по умолчанию (запрет) для всех цепочек.
# Flush and set default policy of deny. 
ipfwadm -I -f
ipfwadm -I -p deny
ipfwadm -O -f
ipfwadm -O -p deny
# Следует иметь ввиду, что пока не указано обратного, по умолчанию,
# правила forwarding'а используются.
ipfwadm -F -f
ipfwadm -F -p deny

# В сети частенько встречаются люди которые любят похулиганить - эта
# строчка как раз для таких людей имеющих постояный IP адрес - запрет
# любого траффика с этого хоста. Нет необходиости записывать аналогичное
# правило для выходящих пакетов - они, обычно, идут в ответ на пакеты
# "атакующего", так что через небольшое время будет не на что отвечать.
ipfwadm -I -P all -i deny -S 195.46.168.168/32 -D 195.218.173.129

# в следующем абзаце дается разрешение на проход пакетов с адресов
# внутренней сети, включая dialup адреса (sl* , ppp*). Опция -V введена 
# для того , чтобы отсечь другие интерфейсы, к которым клиенты
# подключены быть не могут.
# Введен также параметр с названием интерфейса-шлюза - eth0. Это может
# иметь смысл с той точки зрения, что различные устройства могут иметь
# одинаковый  IP адрес,а маршрутизация может идти при этом, например, по
# оценке "стоимости" отсылки пакета на iface.
# Важно отметить еще один аспект - я предпочитаю задавать имя машин в
# цифровом виде, поскольку иначе работа firewall будет зависеть от
# корректной работы сервера имен.

#IP addr. of eth0,lo & ppp0
eth0=192.168.0.3
ppp0=195.218.173.129
lo=127.0.0.1

# mashine addresses
kbg=192.168.0.5
klay=192.168.0.2
vproxy=192.168.0.4
guest=192.168.0.8
acer=192.168.0.10
alex=192.168.0.25
# Для мобильного пользователя подключающегося через локальную сеть.
notebook=192.168.3.5

# Наличие такого количества dialup адресов объясняется тем, что по модему могут
# звонить разные клиенты с разными настройками.

# dialups w/ almost same options:
dialup0=192.168.4.120
dialup1=192.168.4.121
dialup2=192.168.4.122
# restricted dialup:
dialup3=192.168.4.123
# dialup allowed to connect the LAN (**): 
dialup4=192.168.4.124
# address of anywhere. :)
any=0.0.0.0/0


# Все что угодно приходящее для нас через внешний iface на адрес этого 
# iface пропускается, если нет запрета (добавляем в конец правил)
ipfwadm -I -a accept -V $ppp0 -S $any -D $ppp0/32

# C loopback принимаем пакеты в любое место (ниже - ограничения)
ipfwadm -I -a accept -V $lo   -S $any -D $any

# ethernet
ipfwadm -I -a accept -V $eth0     -W eth0 -S $kbg/32      -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $klay/32     -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $vproxy/32   -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $guest/32    -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $acer/32     -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $alex/32     -D $any -v -n
ipfwadm -I -a accept -V $eth0     -W eth0 -S $notebook/32 -D $any -v -n
# dialup
ipfwadm -I -a accept -V $dialup0  -W ppp1 -S $dialup0/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup0  -W sl0  -S $dialup0/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup1  -W ppp1 -S $dialup1/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup1  -W sl0  -S $dialup1/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup2  -W ppp1 -S $dialup2/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup2  -W sl0  -S $dialup2/32 -D $any -v -n
# для ограничения доступа не далее шлюзового компьютера(server'a)
# надо задавать в destination address (-D) адрес одного из interface'ов
# вместо маски включающей все адреса:
ipfwadm -I -a accept -V $dialup3  -W ppp1 -S $dialup3/32 -D $eth0 -v -n
ipfwadm -I -a accept -V $dialup3  -W sl0  -S $dialup3/32 -D $eth0 -v -n
# Для того, чтобы пользователи dialup соединения могли работать
# с сетью ethernet нужно задать еще правило accept для адреса eth0
# Однако в данном примере такой адрсе уже входит в спецификацию $any.
ipfwadm -I -a accept -V $dialup4  -W ppp1 -S $dialup4/32 -D $any -v -n
ipfwadm -I -a accept -V $dialup4  -W sl0  -S $dialup4/32 -D $any -v -n


# для остальных имеющихся iface'ов имеет смысл задать точные запрещающие
# правила, несмотря на default policy of deny это может предохранить от
# возможных ошибок.. Нижеследующий абзац направлен против подстановки
# неверных адресов источника пакетов. Обратите внимание, что запрещаются
# пакеты не для хоста, а для сети и запрет вставляется в начало цепочки.
# Одно из очень хороших нововведений ipchains - расширенный синтаксис - 
# возможность производить логические операции с указанным IP параметром,
# например отрицание (не), впрочем ipchains здесь не рассматривается.. 

ipfwadm -I -i deny -V $ppp0     -S $dialup0/32  -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $dialup1/32  -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $dialup2/32  -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $dialup3/32  -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $dialup4/32  -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $eth0/32     -D $any -o -v -n
ipfwadm -I -i deny -V $ppp0     -S $notebook/24 -D $any -o -v -n

ipfwadm -I -i deny -V $eth0     -S $dialup0/24  -D $any -o -v -n
ipfwadm -I -i deny -V $eth0     -S $dialup1/24  -D $any -o -v -n
ipfwadm -I -i deny -V $eth0     -S $dialup2/24  -D $any -o -v -n
ipfwadm -I -i deny -V $eth0     -S $dialup3/24  -D $any -o -v -n
ipfwadm -I -i deny -V $eth0     -S $dialup4/24  -D $any -o -v -n

ipfwadm -I -i deny -V $lo       -S $dialup0/24  -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $dialup1/24  -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $dialup2/24  -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $dialup3/24  -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $dialup4/24  -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $lo       -S $notebook/24 -D $any -o -v -n

ipfwadm -I -i deny -V $dialup0  -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup0  -S $notebook/24 -D $any -o -v -n
ipfwadm -I -i deny -V $dialup0  -S $lo/24       -D $any -o -v -n
ipfwadm -I -i deny -V $dialup0  -S $ppp0/24     -D $any -o -v -n

ipfwadm -I -i deny -V $dialup1  -S $ppp0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup1  -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup1  -S $notebook/24 -D $any -o -v -n
ipfwadm -I -i deny -V $dialup1  -S $lo/24       -D $any -o -v -n

ipfwadm -I -i deny -V $dialup2  -S $ppp0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup2  -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup2  -S $notebook/24 -D $any -o -v -n
ipfwadm -I -i deny -V $dialup2  -S $lo/24       -D $any -o -v -n

ipfwadm -I -i deny -V $dialup3  -S $ppp0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup3  -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup3  -S $notebook/24 -D $any -o -v -n
ipfwadm -I -i deny -V $dialup3  -S $lo/24       -D $any -o -v -n

ipfwadm -I -i deny -V $dialup4  -S $eth0/24     -D $any -o -v -n
ipfwadm -I -i deny -V $dialup4  -S $lo/24       -D $any -o -v -n
ipfwadm -I -i deny -V $dialup4  -S $notebook/24 -D $any -o -v -n
ipfwadm -I -i deny -V $dialup4  -S $ppp0/24     -D $any -o -v -n


# Следующие строки запрещают некоторые развлекательные сервисы интернет:
####Deny all Real Audio to all:
ipfwadm -I -P tcp -i deny -S $any 7070 -D $any      -o -v -n 
ipfwadm -O -P tcp -i deny -S $any      -D $any 7070 -o -v -n
ipfwadm -I -P udp -i deny -S $any 7070 -D $any      -o -v -n
ipfwadm -O -P udp -i deny -S $any      -D $any 7070 -o -v -n
####
####Deny all mp3 Audio to all:
ipfwadm -I -P tcp -i deny -S $any 8000 -D $any       -o -v -n
ipfwadm -O -P tcp -i deny -S $any      -D $any 7070  -o -v -n
ipfwadm -I -P udp -i deny -S $any 8000 -D $any       -o -v -n
ipfwadm -O -P udp -i deny -S $any      -D $any 7070  -o -v -n
####
####Deny all Real Video to all:
ipfwadm -I -P tcp -i deny -S $any 554  -D $any       -o -v -n
ipfwadm -O -P tcp -i deny -S $any      -D $any 7070  -o -v -n
ipfwadm -I -P udp -i deny -S $any 554  -D $any       -o -v -n
ipfwadm -O -P udp -i deny -S $any      -D $any 7070  -o -v -n
####
####Deny irc for vproxy
ipfwadm -I -P tcp -i deny -S $vproxy/24 -D $any 6667 -o -v -n
ipfwadm -I -P udp -i deny -S $vproxy/24 -D $any 6667 -o -v -n
####

# Cдесь стоит отметить, что правила запрещающие по принципу "один из
# всех" на мой взгляд лучше писать в начало цепочки - немного ускорит
# обработку - запрещенные пакеты будут отсеиваться раньше,да и вообще
# схема в которой пакеты сначала отвергаются, и только оставшиеся
# разрешаются, причем как можно более четкими правилами, является
# наиболее жффективным продолжением политики задаваемой опцией '-p deny'.

# Ну и наконец правило, запрещающее проход любых не разрешенных пакетов,
# которые мы забыли запретить отдельной записью:
ipfwadm -I -a deny -S $any -D $any -o -v -n

# Теперь определим ограничения для входящего траффика

# Локальный interface, любой выходящий от нас пакет следует разрешить, оговорив
# исключения отдельно, поскольку иначе могут возникунуть проблемы при
# добавлении записей в таблицу маршрутизации.
ipfwadm -O -a accept -V $eth0 -S $any -D $eth0/24      -v -n
ipfwadm -O -a accept -V $eth0 -S $any -D $notebook/24  -v -n

# Поскольку выбранные нами локальные адреса не дожны ходить через
# internet , то можно запретить проход вовне всех пакетов на адреса,
# находящиеся внутри, а заодно и вовсе на весь список  адресов , которые
# зарезервированы для локальных сетей.
ipfwadm -O -i deny   -V $ppp0 -S $any -D $eth0/24     -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any -D $notebook/24 -o -v -n

# Запрет выхода заспуффенных пактов из локальной сети (в HOWTO также
# называетсяng stuffed routing) вовне
ipfwadm -O -i deny   -V $ppp0 -S $eth0/24     -D $any        -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $notebook/24 -D $any        -o -v -n

# То-же для dialup:
ipfwadm -O -i deny   -V $ppp0 -S $dialup0/24 -D $any         -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $dialup1/24 -D $any         -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $dialup2/24 -D $any         -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $dialup3/24 -D $any         -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $dialup4/24 -D $any         -o -v -n

# То-же для loopback:
ipfwadm -O -i deny   -V $ppp0 -S $lo/24      -D $any         -o -v -n

# Следует отметить, что когда $dialup* в одной подсети достаточно одной записи.

# Запрет выхода заспуффенных пакетов через внешний iface в локальную
# сеть ( в HOWTO также называетсяng stuffed masqerading)
ipfwadm -O -i deny   -V $ppp0 -S $any -D $eth0/24 -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any -D $notebook/24 -o -v -n

# То-же для dialup:
ipfwadm -O -i deny   -V $ppp0 -S $any        -D $dialup0/24  -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any        -D $dialup1/24  -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any        -D $dialup2/24  -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any        -D $dialup3/24  -o -v -n
ipfwadm -O -i deny   -V $ppp0 -S $any        -D $dialup4/24  -o -v -n

# То-же для loopback:
ipfwadm -O -i deny   -V $ppp0 -S $any         -D $lo         -o -v -n

# Все остальное выходящее с внешнешнего iface разрешено.
ipfwadm -O -a accept -V $ppp0 -S $ppp0/32 -D $any

# Пакеты с loopback пропускаем куда угодно (кроме указанных выше ограничений)
ipfwadm -O -a accept -V $lo   -S $any -D $any

# Как и для цепочки правил выходящих сообщений имеет смысл указать правило 
# запрещающее все что мы, возможно, забыли запретить. :)
ipfwadm -O -a deny -S $any -D $any -o

# Forwarding (то чего не было в предыдущем примере).
# Masquerade from local net on local interface to anywhere.

# Описание правил для конкретных хостов:
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $klay/32      -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $vproxy/32    -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $kbg/32       -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $guest/32     -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $acer/32      -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $alex/32      -D $any -o -v -n
ipfwadm -F -m -a accept -W ppp0 -V $ppp0 -S $notebook/32  -D $any  -o -v -n

# тоже для dialup клиенетов:
ipfwadm -F -m -a accept -W ppp1 -V $dialup0 -S $dialup0/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W sl0  -V $dialup0 -S $dialup0/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W ppp1 -V $dialup1 -S $dialup1/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W sl0  -V $dialup1 -S $dialup1/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W ppp1 -V $dialup2 -S $dialup2/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W sl0  -V $dialup2 -S $dialup2/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W ppp1 -V $dialup3 -S $dialup3/32 -D $eth0 -o -v -n
ipfwadm -F -m -a accept -W sl0  -V $dialup3 -S $dialup3/32 -D $eth0 -o -v -n
ipfwadm -F -m -a accept -W ppp1 -V $dialup4 -S $dialup4/32 -D $any  -o -v -n
ipfwadm -F -m -a accept -W sl0  -V $dialup4 -S $dialup4/32 -D $any  -o -v -n

# В используемой автором версии ipfwadm в man не было документировано, что 
# запись `-F -m -a` accept эквивалентна `-F -a masquerade`, однако несмотря 
# на то, что такая возможность существует, я предпочел воспользоваться немного
# более краткой и документированной записью.

# И, уже не раз упомянутый, принцип запретить все, что не разрешали:
# catch all rule, all other forwarding is denied and logged.
ipfwadm -F -a deny -S $any -D $any -o -v -n

# Без этой строки роутинг для этой сети будет по умолчанию на другой 
# (обычно внешний) iface.
route add -net 192.168.3.0 eth0
