Как то так сложилось исторически, что для меня сервер вне зависимости от возложенных на него функций является фаерволом. Скорее всего это связано с безопасностью. Не важно, сайт на нем крутится или почтарик или просто это шлюз в интернет для небольшой компании — он должен быть защищен и точка. Я уже писал о фаерволе средствами PF, но есть в нем некоторые минусы и сложности. В любом случае опыт лишним не бывает. Вот и решил освоить хотя бы минимально работу с IPFW — родным фаерволом во фряхе. Да и очевидно же, что такая качественная система не может за основу взять некачественный фаервол. Кроме того изучения сравнительных характеристик показали очевидное превосходство IPFW. Пора заставить себя использовать только лучшее.
Для теста была выбрана самая свежая на тот момент версия — FreeBSD 9.1. Во время установки никаких сложностей не возникло. Первим же делом я обновил порты (привычка) и решил собрать своё ядро не с модульной а нативной поддержкой IPFIREWALL. Никаких трудностей, все по стандарту.
Копируем GENERIC ядро и начинаем править его под свои нужды:
cd /usr/src/sys/i386/conf/ cp GENERIC IPFW
Так как ядро пересобираем для нормальной поддержки ipfw, то ничего удалять не будем, а лишь добавим опции отвечающие за оного
ident IPFW options IPFIREWALL options IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_FORWARD options IPFIREWALL_VERBOSE options IPFIREWALL_VERBOSE_LIMIT=100 options IPFIREWALL_NAT options LIBALIAS options ROUTETABLES=2 options DUMMYNET options HZ="1000"
сохраняем и занимаемся непосредственно сборкой
config IPFW cd ../compile/IPFW/ && make cleandepend && make depend && make && make install && reboot
В /etc/rc.conf необходимо добавить следующие строки:
gateway_enable="YES" # наш сервер будет шлюзом ifconfig_sk0="inet 192.168.4.57 netmask 255.255.255.0" # настройки внешнего интерфейса ifconfig_rl0="inet 192.168.7.1 netmask 255.255.255.0" # настройки внутреннего интерфейса defaultrouter="192.168.4.222" # дефолтный шлюз для самого сервера firewall_enable="YES" # активируем фаервол firewall_nat_enable="YES" # активируем NAT dummynet_enable="YES" # активируем средство ограничения трафика firewall_type="/etc/ipfw-nat" # файл с правилами фаервола
Дальше создание файла конфигурации для нашего пакетного фильтра. Для этого создадим указанный выше файл и внесём в него следующие строки:
add 1 allow ip from any to any via rl0 nat 1 config log if sk0 reset same_ports add 2 nat 1 ip from any to any via sk0
Этого было бы достаточно что бы просто работал NAT. Дальше немного добавим безопасности.
# Разрешаем весь трафик по внутреннему интерфейсу (петле) add allow ip from any to any via lo0 # Блокируем попытки lo0 куда-то лезть и откуда-то лезть на lo0 add deny ip from any to 127.0.0.0/8 add deny ip from 127.0.0.0/8 to any # Блокируем частные сети на внешнем интерфейсе add deny ip from any to 10.0.0.0/8 in via sk0 add deny ip from any to 172.16.0.0/12 in via sk0 add deny ip from any to 0.0.0.0/8 in via sk0 # Блокируем автоконфигуреную частную сеть add deny ip from any to 169.254.0.0/16 in via sk0 # Блокируем мультикастовые рассылки add deny ip from any to 240.0.0.0/4 in via sk0 # Блокируем фрагментированные icmp add deny icmp from any to any frag # Блокируем широковещательные icmp на внешнем интерфейсе add deny log icmp from any to 255.255.255.255 in via sk0 add deny log icmp from any to 255.255.255.255 out via sk0 # отправляем всех на прозрачный squid add fwd 127.0.0.1,3128 tcp from 192.168.7.0/24 to any 80 via sk0 # пропускаем траффик через трансляцию сетевых адресов (NAT) nat 1 config log if sk0 reset same_ports add nat 1 ip from any to any via sk0 # Блокируем траффик к частным сетям через внешний интерфейс add deny ip from 10.0.0.0/8 to any out via sk0 add deny ip from 172.16.0.0/12 to any out via sk0 add deny ip from 0.0.0.0/8 to any out via sk0 # Блокируем автоконфигуреную частную сеть add deny ip from 169.254.0.0/16 to any out via sk0 # Блокируем мультикастовые рассылки add deny ip from 224.0.0.0/4 to any out via sk0 add deny ip from 240.0.0.0/4 to any out via sk0 # разрешаем все установленные соединения add allow tcp from any to any established # разрешаем весь исходящий траффик add allow ip from me to any out xmit sk0 # разрешаем DNS снаружи add allow udp from any 53 to any via sk0 # разрешаем DNS входящий снаружи - если на этой машине работает named # и держит какую-то зону. add allow udp from any to any 53 via sk0 # разрешаем некоторые типы ICMP траффика - эхо-запрос, эхо-ответ и время жизни пакета истекло add allow icmp from any to any icmptypes 0,8,11 # открываем снаружи порты (WEB, SMTP, SSH, IMAP соответственно) add allow tcp from any to me 80 via sk0 add allow tcp from any to me 25 via sk0 add allow tcp from any to me 22 via sk0 add allow tcp from any to me 143 via sk0 # разрешаем весь tcp трафик внутри локалки (на внутреннем интерфейсе) add allow tcp from any to any via rl0 # разрешаем весь udp траффик внутри локалки (на внутреннем интерфейсе) add allow udp from any to any via rl0 # разрешаем весь icmp траффик внутри локалки (на внутреннем интерфейсе) add allow icmp from any to any via rl0 # запрещаем всё и всем. add deny ip from any to any
Применить изменения можно перезапустив фаервол:
root@ipfw:/usr/home/gleb # /etc/rc.d/ipfw restart net.inet.ip.fw.enable: 1 -> 0 net.inet6.ip6.fw.enable: 1 -> 0 Flushed all rules. 00100 allow ip from any to any via lo0 00200 deny ip from any to 127.0.0.0/8 00300 deny ip from 127.0.0.0/8 to any 00400 deny ip from any to ::1 00500 deny ip from ::1 to any 00600 allow ipv6-icmp from :: to ff02::/16 00700 allow ipv6-icmp from fe80::/10 to fe80::/10 00800 allow ipv6-icmp from fe80::/10 to ff02::/16 00900 allow ipv6-icmp from any to any ip6 icmp6types 1 01000 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136 01100 allow ip from any to any via lo0 01200 deny ip from any to 127.0.0.0/8 01300 deny ip from 127.0.0.0/8 to any 01400 deny ip from any to 10.0.0.0/8 in via sk0 01500 deny ip from any to 172.16.0.0/12 in via sk0 01600 deny ip from any to 0.0.0.0/8 in via sk0 01700 deny ip from any to 169.254.0.0/16 in via sk0 01800 deny ip from any to 240.0.0.0/4 in via sk0 01900 deny icmp from any to any frag 02000 deny log logamount 100 icmp from any to 255.255.255.255 in via sk0 02100 deny log logamount 100 icmp from any to 255.255.255.255 out via sk0 ipfw nat 1 config if sk0 log same_ports reset 02200 nat 1 ip from any to any via sk0 02300 deny ip from 10.0.0.0/8 to any out via sk0 02400 deny ip from 172.16.0.0/12 to any out via sk0 02500 deny ip from 0.0.0.0/8 to any out via sk0 02600 deny ip from 169.254.0.0/16 to any out via sk0 02700 deny ip from 224.0.0.0/4 to any out via sk0 02800 deny ip from 240.0.0.0/4 to any out via sk0 02900 allow tcp from any to any established 03000 allow ip from 192.168.4.57 to any out xmit sk0 03100 allow udp from any 53 to any via sk0 03200 allow udp from any to any dst-port 53 via sk0 03300 allow icmp from any to any icmptypes 0,8,11 03400 deny tcp from any to 192.168.4.57 dst-port 80 via sk0 03500 allow tcp from any to 192.168.4.57 dst-port 25 via sk0 03600 allow tcp from any to 192.168.4.57 dst-port 22 via sk0 03700 allow tcp from any to 192.168.4.57 dst-port 143 via sk0 03800 allow tcp from any to any via rl0 03900 allow udp from any to any via rl0 04000 allow icmp from any to any via rl0 04100 deny ip from any to any Firewall rules loaded.
После этого все норм. Интернет на локальных машинках за натом есть. «Что и требовалось доказать»