FreeBSD-BG
IP Firewall - на български
 
 

   Всяка съвременна сървърна операционна система има механизъм за контрол върху входящите и
изходящи в и от машината пакети - firewall. В дистрибуцията на FreeBSD по принцип има включени
2 такива системи - ipfw (специфична за FreeBSD) i IPFilter (има версии и за други операционни
ситеми - OpenBSD, NetBSD, IRIX ....). Този документ няма за цел да прави сравнение между тези 2
реализации, а да опише в известна степен възможностите на едната от тях - ipfw.
   ipfw е приложението което дава достъп на системния администратор до вградените в ядрото на
FreeBSD firewall и ограничител на трафика (traffic shaper).
   Всеки влизащ в и излизащ от машината пакет минава през списък от правила (rules) докато не се
намери правило което да го обработи. Ако машината е gateway всеки пакет минава по 2 пъти през
ipfw, ако е bridge - по 1 път. При някои по-особени ситуации е възможно пакет да мине и повече
пъти през ipfw. Правилата са номерирани за да могат по-лесно да бъдат добавяни/изтривани от/на
подходящите места и важат за всички interface-и.
   По подразбиране винаги има правило с номер 65535 което не може да бъде изтривано или
променяно и се отнася за абсолютно всички пакети. То може да бъде deny или allow в зависимост от
конфигурацията на ядрото.
  Всички правила имат брояч на пакетите, брояч на байтовете, брояч за log и време на последния
пакет който е отговарял на това правило. Тези стойности могат да бъдат получени или занулени с
параметри на ipfw.

  Ето и един прост пример:

  ipfw add 10 allow tcp from any to 1.2.3.4 80
  ipfw add 20 allow tcp from 1.2.3.4 80 to any
  ipfw add 30 deny tcp from any to any 80
  ipfw add 40 deny tcp from any 80 to any

  1-вото от 3-те правила разрешава tcp пакетите към 192.168.0.1 за 80-ти порт без значение от
кой адрес идва пакета. 2-рото разрешава tcp пакети от 192.168.0.1 от 80-ти към който и да е
адрес. последните 2 правила забраняват всички tcp пакети от и за 80-ти порт без значение от
адресите от които идват и към които отиват. При положение че машината е gateway за някаква
мрежа горните правила ще забранят външния директен достъп до всички web servers в мрежата
освен 1.2.3.4
  Добавянето на нови правила става със следната команда:
  ipfw [-q] add [<  >] <  >
  Опцията -q се използва за да се спре извеждането на информация в терминала (обикновено
когато конфигурацията се извършва от bash или друг скрипт). При положение че се пропусне
номера на правилото, той автоматично се избира да е равен на номера на последното добавено
правило + 100.
  Изтриването на вече съществуващо правило става с командата:
  ipfw [-q] delete <  >

  Тук ще разгледаме по подробно тялото на правилата което се използва при add. То има следния
формат:
  [prob <>] <> [log [logamount <  >]] <> from < >
      to < > [<  >] [<>]

  Всеки пакет може да се филтрира по следната информация:

      интефейс ппез който е получен или през който трябва да бъде пратен (име или адрес на интерфейса)
      направление (входящ, изходящ)
      начален и краен IP адрес (поддържат се и маски на подмрежи)
      протокол (TCP, UDP, ICMP и др.)
      начален и краен порт (могат да бъдат указвани като списък, обхват и с маска)
      TCP флагове
      IP флаг за фрагментиране
      IP опции
      ICMP тип
      User/group ID на socket-а който е асоцииран с пакета

  Забележете че не е удачно да се филтрира по начален адрес или порт в ситуации когато е
вазможен spoof !!!

   [prob <>]
     указва правилото да се изпълни с <> реално число от 0 до 1. Може да се използва
   за случаен drop на пакети или за да се симулира ефект на "multipath" т.е. пакетите да се
   получават непоследователно. В общия случай не се използва.

   <>
     allow - разрешава рутирането на пакета, и прекратява обхождането на останалите правила.
                синоними са pass, permit и accept.
     deny - не допуска пакета до рутиране и прекратява обхождането на останалите правила.
                синоним - drop.
     reject - (deprecated) прави същото като deny, но освен това изпраща ICMP host unreachable
                пакет. Използвайте unreach вместо reject.
     unreach <> - прави същото като deny, но освен това изпраща ICMP unreachable пакет с код
                <>. Кода е число от 0 до 255 или един от следните синоними: net, host, protocol, port,
                needfrag, srcfail, net-unknown, host-unknown, isolated, net-prohib, host-prohib, tosnet,
                toshost, filter-prohib, host-precedence или precedence-cutoff.
     reset - отнася се само за TCP пакети. Прави същото като deny, но освен това изпраща и TCP
                reset (RST) пакет.
     count - само обновява броячите за правилото. Обхождането на правилата продалжава със
                следващото правило.
     check-state - проверява пакета чрез динамичните правила, при успех обхождането се прекратява,
                при неуспех продължава със следващото правило. Ако не е зададено check-state правило
                динамичните правила се проверяват при първото keep-state правило.
     divert <> - изпраща пакетите които отговарят на това правило към divert socket закачен на
                порт <>. Обикновено се използва за natd или специфични приложения за
                филтриране на пакети в user-spacе.
     tee <> - изпраща копие на пакета към divert socket закачен на порт <>. Оригиналния
                пакет се допуска до рутиране и обхождането се прекратява. Ако се използва обезателно
                трябва да се има предвид, че в следващите версии на FreeBSD се очаква пакетът да
                продалжава обхождането !!!
     fwd [,] - сменя next-hop на пакета на . Може да се използва IP адрес
                или hostname. Ако адресът не е директно достижим се използва съответния път от routing
                таблицата. Ако адресът е локален пакетът се пренасочва към локален порт <>, а
                началния адрес се запазва непроменен. По този начин fwd може да се използва при
                "прозрачни" (trasparent) proxy сървъри. Ако адресът не е локален тогава <> се
                пренебрегва и правилото се отнася само за изходящи от машината пакети. Засяга също
                и локално генерираните пакети. Ако не е зададен <> се използжа номера на порт
                от пакета. За да се използва fwd ядрото трябра да е компилирано с
                IPFIREWALL_FORWARD опция.
     pipe <  pipe> - подава пакета на dummynet pipe, който се използва за контрол на трафика
                и ще бъде разгледан по-надолу в този документ. Обхождането може да се прекрати или
                не в зависимост от стойността на sysctl променливата net.inet.ip.fw.one_pass. Ако тя има
                стойност 0 обхождането продължава от следващото правило. При стойност различна от
                0 обхождането се прекратява.
     queue <  queue> - подава пакета на dummynet queue
     skipto <> - прескача всички правила с номер < <>. Обхождането продалжава от
                правило с номер <> или първия по-голям.

    [log [logamount <  >]]
     Ако ядрото е компилирано с IPFIREWALL_VERBOSE опция пакетите отговарящи на правило с
log ключова дума се log-ват през syslogd с LOG_SECURITY facility. По подразбиране се добавят
към /var/log/security. Ако ядрото е компилирано с IPFIREWALL_VERBOSE_LIMIT опция log-ването
престава след като определен брой пакети са били log-нати. sysctl променливата
net.inet.ip.fw.verbose_limit определя този брой, въпреки че ако използвате
logamount <  > можете да го смените и да го нагласите за всяко правило по
отделно. logamount е с приоритет пред sysctl променливата. Стойност 0 премахва limit-а.
Log-ването може да бъде подновено след изчистване на брояча на пакетите или на log брояча.

    <>
     номер или име на протокол. За повече информация вижте /etc/protocols. Ключовите думи ip или
all се използват за да се филтрират всички протоколи.

    < >, < >
     any | me | [not]  [портове]
     any се използва за да се филтрират пакети без значение от IP адреса, правилото важи за
всички пакети без значение какъв е началния или крайния адрес.
     me се използва за IP адресите на самата машина
      може да се оказва по няколко начина:
       ipno         IP адрес във формат 1.2.3.4 - дефинира правило за единичен ip адрес
       ipno/bits   IP адрес със широчина на маската на подмрежа в битове. 1.2.3.4/24 се отнася за
                      адреси от 1.2.3.0 до 1.2.3.255.
       ipno:mask IP адрес и маска във вид 1.2.3..4:255.255.255.0 Примера прави същото нещо като
                      предходния.
     not се използва за да се създават правила, които се отнасят за всички IP адреси без
посочените, не важи за портовете.
     [портове]
       {port | port-port | port:mask }[,port[,.....]]
       - се използва за да се укаже обхват от портове включително с границите
       :mask указва маска по която да бъдат проверявани портовете
       имената на services от /etc/services може да се използват също. Броя на портовете в
списака е ограничен до IP_FW_MAX_PORTS (дефинирано в /usr/src/sys/netinet/ip_fw.h). Backslash
('\') може да се използва за escape-ване на ('-') в имената на services от /etc/services
       Ако се обработват фрагментирани пакети само първия фрагмент може да активира правило
с един или повече портове изброени в него. За повече информация за филтриране на
фрагментирани пакети вижте frag по-надолу.

     [<  >]
       комбинации от следните са разрешени:

       in - филтрират се само входящите пакети
       out - филтрират се само изходящите пакети
       via ifX - филтрират се само пакетите които минават през интерфейс ifX
       via if* - филтрират се само пакети които минават през интерфейс ifX - if0, if1, if2 .....
       via any - филтрират се пакети минаващи през който и да е интерфейс
       via ipno - филтрират се пакети минаващи през интерфейс с IP адрес ipno
       recv и xmit се използват по същия начин като via с тази разлика че recv проверява само
входящия, а xmit само изходящия интерфейс.

     [<>]
       keep-state [method]
         при пакет който отговаря на такова правило firewall-ът създава динамично правило за
двупосочния трафик между началния и крайния IP адрес на пакета за същия протокол.
Динамичното правило има ограничен lifetime, който може да се задава чрез sysctl променливи.
Lifetime-ът се обновява всеки път когато се получи пакет, отговарящ на това правило. Точното
поведение може да се променя чрез различни method-и, но в момента е реализиран само този
който е по подразбиране.
       bridged
         филтрира само bridged пакети. Може да бъде полезно за broadcast или multicast. който иначе
ще мине 2 пъти през firewall-а - един път при bridging и един път когато пакетите се подават към
локалния stack. Освен малките спадове в производителността, това може да се окаже проблем при
използване на pipes или queues понеже пакетите ще се отчетат по 2 пъти.
       frag
         филтрира фрагменти от пакети без първия. Не може да се използва заедно с tcpflags или с
TCP/UDP филтриране по портове.
       ipoptions spec
         филтрира по опции от IP header-а на пакета. опциите се изброяват и се разделят със
запетаики, може да се използва ! за отсъствието на някоя от опциите. поддържат се:
         ssrr(strict source route), lsrr(loose source route), rr(record packet route) и ts(timestamp)
       tcpoptions spec
         използва се както и ipoptions само че се отнася за TCP header-a на пакета. поддържат се:
         mss(maximum segment size), window(tcp window advertisement), sack(selective ack), ts(rfc1323
timestamp) и cc (rfc1644 t/tcp connection count)
       established
         използва се само за TCP пакети. филтрира само пакетите които имат установени RST и ACK
битове
       setup
         използва се само за TCP пакети. филтрира само пакетите които имат установен SYN бит и
нямат установен ACK бит
       tcpflags spec
         използва се подобно на ipoptions i tcpoptions. Поддържаните флагове са:
         fin, syn, rst, psh, ack и urg. Правило което съдържа tcpflags никога не може да филтрира 1вия
фрагмент на фрагментиран пакет.
       icmptypes types
         Използва се само за ICMP пакети. Филтрира пакети ако тяхния type е в списък от изброени
типове разделени със (','). Поддържаните ICMP типове са:
         echo reply (0), destination unreachable (3), source
         quench (4), redirect (5), echo request (8), router adver-
         tisement (9), router solicitation (10), time-to-live
         exceeded (11), IP header bad (12), timestamp request
         (13), timestamp reply (14), information request (15),
         information reply (16), address mask request (17) и
         address mask reply (18).
       uid user
         филтрира TCP или UDP пакети изпратени от или получени за конкретен потребител.
Потребителят се задава чрез име или идентификационен номер (UID)
       gid group
          филтрира TCP или UDP пакети изпратени от или получени за конкретна група .
Групата се задава чрез име или идентификационен номер (GID)