Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

   Рубрики
 
 
 
 

 Форуми
» SEO и оптимизация
» Всичко за PHP и Perl
» Всичко за C, C++ и .NET
» Всичко за Java и JSP
» Всичко за SQL и MySQL
» Всичко за XHTML и CSS
» Презентация на сайтове
 Connection tracking
  1. Connection tracking
Inventive
     
Автор  Inventive (05.02.2005 10:32)  съобщение до автора
Погледнат  3331 пъти  добави към любими
Оценка  добави коментар
Гласове  --  изпрати на приятел
Коментари  (1)  абонирай се за Unix
    Страница 1 / 1

 



Превод: Светослав Генов (Inventive)

                              Connection_tracking

Какво е connection tracking?

Connection tracking се обяснява с възможноста да поддържате дадена информация
за връзките в таблица, като предназначение и сорс на IP адресите и сътветните
портове, видове протоколи, изтичане на времето и състояние на връзката. Firewall-и
които правят това са познати като stateful. На stateful firewall-ите им е присъща
по-голяма сигурност отколкото на тяхните "stateless" дубликати ... прости пакетни
филтри.


Connection tracking се извършва със state опцията в iptables. От man страницата:

state
       Този модул когато се комбинира с connection tracking, позволява достъп
       до connection tracking състоянията за този пач.


       --state state
             
              Кадето state е списък разделен със запетайки за в сяка state
              връзка която съвпада. Валидните states са INVALID значещ че пакетът
              е асоцииран като непозната връзка, ESTABLISHED което означава че
              пакетът е асоцииран като връзка която може да вижда пакети и в двете
              посоки, NEW значещ че пакета е започнал нова връзка, или по друг начин
              казано с връзка която не вижда пакети в двете посоки, и RELATED означаващо
              че пакета започва нова връзка, но е асоцииран с вече създадена връзка,
              нещо като FTP дата трансфер, или ICMP грешка.

Connection tracking се изпълнява през PREROUTING веригата, или OUTPUT веригата за
локално генерирани пакети. Connection tracking дефрагментира всички пакети преди
да проследи тяхното положение. Това обяснява защо няма ip_always_defrag както имаше в
2.2 кернела.

State таблицата за udp и tcp връзки се намира в /proc/net/ip_conntrack.
Ще дискутираме съдържанието и по-долу.

Максималният брой връзки които state таблицата може да съдържа се намира в
/proc/sys/net/ipv4/ip_conntrack_max. Първоначално тази стойност твърдо е зададена
от това колко физическа памет имате (на моята 512 Mb машина, ip_conntrack_max по начало е
32760).
 
Как работи connection tracking?

Бърз поглед

За пренасочването на пакети м/ интерфейсите серията от вериги
ще бъде :

1) PREROUTING веригата - DNAT пакета ако е нужно. Разделяме пакетите
ако е нужно. Connection tracking се дефрагментира и проследява (класифицира)
пакета по някакъв начин :

Ако пакетът съвпада с входа от state таблицата то тогава това е част от ESTABLISHED
връзката. Ако е icmp трафик може да бъде RELATED към udp/tcp връзка която вече е в
state таблицата. Пакетът може да стартира NEW връзка, или да не е свързан към
нито една връзка в който случай се смята че е INVALID.

2) FORWARD веригата - Сравнява състоянието на пакетите срещу правилата в таблицата
за филтриране докате първото съвпадне, или докато началната политика на веригата се
изпълни.

3) POSTROUTING веригата - SNAT пакет ако е нужно.

Забележете, че всички пакети се сравняват с правило в филтър таблицата.
Това лесно се доказва - ако имате декларирани в state таблицата и промените
правилото да забранява всичкият трафик, тогава входът вписан в state
таблицата остава, целият трафик е със сигурност отхвърлен както трябва да е.

Повече информация

Ще разгледаме всеки един от трите протокола, udp, tcp и icmp поред.

UDP

Понеже при него липсват редица числа, udp е още познат като 'stateless' протокол.
Както и да е, това не означава че ние не можем да проследим udp връзките. Има още
много полезна информация която можем да използваме. Ето примерен вход от state
таблицата за новоформирана udp връзка :

udp      17 19 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 [UNREPLIED] src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 use=1

За набор от правила създадени в началото на deny базирана конфигурация, този
вход на state таблицата може да бъде направен ако има филтриращо правило от iptables
което позволява NEW връзки, нещо като следното правило което позволява NEW връзки :

iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT

Нещата които можем да разберем от входа на state таблицата са :
  • Протоколът е udp (Номер на IP протокола - 17).
  • Входът на state таблицата има още 19 секунди преди да изтече.
  • Предназначения и сорс адреса и портовете на оригиналната заявка.
  • Предназначения и сорс адреса и портовете на очавканият отговор. Връзката е
  маркирана като UNREPLIED което означава че все още не е приета.

UDP прекъсванията се настройват в /usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.cat по време на компилиране.
Ето това са нещата които трябва да се променят :

#define UDP_TIMEOUT (30*HZ)
#define UDP_STREAM_TIMEOUT (180*HZ)

Единична заявка ще се добави в state за 30*HZ (30 секунди). В примера по-горе,
кадето имаме 19 секунди оставащи, 11 секунди са вече изтекли без да бъде получен
отговор. Веднъж щом отговорът е приет и позволен от правилото ESTABLISHED връзки,
прекъсването се слага отново на 30 секунди и UNREPLIED маркировката се маха. Тук
виждаме връзка която е заела мястото си след няколко секунди :

udp      17 28 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 use=1

Ако имаме много заявки и се появят отговори между едни и същи двойки сокети,
входът се смята като поток и прекъсването се слага на 180 секунди. Тук
виждаме връзката няколко секунди след като е заела мястото си:

udp      17 177 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 [ASSURED] use=1

Можем да видим, че входът е маркиран като ASSURED. Веднъж щом връзката е станала
ASSURED те няма да бъдат прекъснати при голямо претоварване. Ако state таблицата е пълна
например и нова връзка се появи, входовете маркирани като UNREPLIED се прекъсват като превигилировани.

Няма абсолютно прекъсване за udp връзките (или tcp връзките),
трафика си продължава да си тече.
 
TCP

TCP връзката се открива чрез тройно захващена включващо синхронизирана молба от
клиента, синхронизацията и потвърждението от сървъра, и най-накрая потвърждението от клиента.
Следващият трафик течящ между сървъра и клиента е потвърден във всякакъв случай.
Редът изглежда така:

     Client                    Server
      SYN      --->
                     <---     SYN+ACK
      ACK      --->
                     <---         ACK
      ACK      --->
                     .........
                     .........

SYN и ACK се онсаят към сложените флагове в tcp хиидъра. Също така има и 32 бита
ред и потвърждаващи номера в tcp хиидъра, които се подават напред назад и се
преработват по време на сесията.

За да подкарате проследяването на tcp връзката ви трябва правило, което
изглежда така:

iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT

Обяснение

Това, което ще правим сега е да минем през осъществяването на нормална
tcp връзка, да погледе state таблицата за всяко ниво и да ги обсъдим:

1) Веднъж щом осъщественият SYN е пратен към OUTPUT веригата, и приет от правило, което
позволява NEW връзка, входът от таблицата за връзките може да изглежда по следния начин:

tcp      6 119 SYN_SENT src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 [UNREPLIED] src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1

Статусът на TCP връзката е SYN_SENT и е маркирана като UNREPLIED.

2) Сега чакаме да престигне SYN+ACK, след кето state на tcp връзката се
променя на SYN_RECV и UNREPLIED изчезва:

tcp      6 57 SYN_RECV src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1

3) Сега ще чакаме за финалната част от захващането, ACK. Когато пристигне
проверяваме поредицата от номера които съвпадат със ACK от захващането от
сървърът към клиентът. State на tcp връзката сега вече е ESTABLISHED и
входът от state таблицата е маркиран като ASSURED (ASSURED връзките не се
прекъсват от state таблицата когато връзката е твърде натоварена). Тук
виждаме една ESTABLISHED връзка :

tcp      6 431995 ESTABLISHED src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 [ASSURED] use=1

Преспективи на state таблицава на connection tracking

Туко що говорихме доста за state на tcp връзките. Нека сега разгледаме това
от преспективата на connection tracking:

Connection tracking използва само NEW, ESTABLISHED, RELATED и INVALID,
класифицирани както са описани по горе в iptables man страницата. Ще цитирам
Joszef Kadlecsik, който ми помогна за този проблем :

Когато пакет с SYN+ACK флагове се появи като отговор на пакет с SYN connection
tracking си мисли: "Туко що видях пакет с SYN+ACK който отговори с SYN който
видях преди това, така че това е ESTABLISHED връзка."

Важното тук е че conntrack states не са еквивалентни на tcp states.
Вече видяхме че връзката не осъществява tcp връзка със статус ESTABLISHED
докато ACK след SYN+ACK не е получен.

Репрезентацията на tcp state връзката в state таблицата е напълно за прекъсванията.
Можете да си докажете това като изпратите ACK пакет през вашият firewall до несъществуваща
машина (така че да не получите RST обратно). Ще създаде без проблемно вход от state
таблицата защото това е първият пакет от връзката а и също така се смята като NEW
(входът няма да бъде маркиран като ASSURED).

Ако съдим по фактите ACK пакетите могат да създадат входове от state таблицата.
За да се уверите че NEW tcp връзките са пакети с SYN, използвайте следното правило :

iptables -A INPUT -p tcp ! --syn -m state --state NEW-j DROP

Забележете, че правейки това вие ще прекратите idle сесията от продължаване,
веднъж щом те са изтегки от conntrack таблицата. В нормалното "relaxed" виждане
подобни връзки създадени в правилната посока (т.е посоката през която позволявате
NEW пакети да приминат) могат да продължат нормално независимо дали са изтекли в
conntrack, също така първият data/ack пакет продължава връзката идвайки от
правилната посока.

Ако искате наистина stateful филтриране което се нужнае от правилно осъществена
връзка и проследява поредица от номера, добавете tcp-window-tracking пача от patch-o-
matic.

Прекъсвания

Нещо което трябва да спомена, е че прекъсванията се слагат отново на максимум всеки
път връзката види трафик. Прекъсванията се слагат в usr/src/linux/net/ipv4/netfilter
ip_conntrack_proto_tcp.c при компилиране. Ето часта която трябва да се промени :

static unsigned long tcp_timeouts[]
= { 30 MINS,    /*      TCP_CONNTRACK_NONE,     */
    5 DAYS,     /*      TCP_CONNTRACK_ESTABLISHED,      */
    2 MINS,     /*      TCP_CONNTRACK_SYN_SENT, */
    60 SECS,    /*      TCP_CONNTRACK_SYN_RECV, */
    2 MINS,     /*      TCP_CONNTRACK_FIN_WAIT, */
    2 MINS,     /*      TCP_CONNTRACK_TIME_WAIT,        */
    10 SECS,    /*      TCP_CONNTRACK_CLOSE,    */
    60 SECS,    /*      TCP_CONNTRACK_CLOSE_WAIT,       */
    30 SECS,    /*      TCP_CONNTRACK_LAST_ACK, */
    2 MINS,     /*      TCP_CONNTRACK_LISTEN,   */
};

Няма пълно прекъсване за връзките.

Connection termination

Connection termination се среща по два начина. Естественото завършване в краят
на сесията се среща когато клиентът изпраща пакет с FIN и ACK флагове.
Закриването се извършва по следният начин:

       Client                   Server
                        .........
                        .........
    FIN+ACK   --->
                        <---        ACK
                        <---     FIN+ACK
            ACK      --->

Понякога през, или в края на този цикъл, статусът на state таблицата
се промена на TIME_WAIT и входът се премахва след 2 минути по подразбиране.

Друг начин за connection termination се среща ако някоя изпрати пакет
с RST (reset) флаг. RST не се приемат. В този случай статусът на state таблицата
се промена на CLOSE и изтича след 10 секунди. Това често се случва с http заявки,
когато сървърът изпраща RST след период на пасивност.
 
ICMP

На езика на iptables, има само четири вида icmp които могат да се категоризират
като NEW, или ESTABLISHED:

1) Echo request (ping, 8) и echo reply (pong, 0).
2) Timestamp request (13) и reply (14).
3) Information request (15) и reply (16).
4) Address mask request (17) и reply (18).

Заявката във всеки случай е класифицирана като NEW и отговорът като ESTABLISHED.
Други видове на ICMP не са request-reply базирани и могат да бъдат само RELATED
към други връзки.

Нека да разгледаме няколко примера и правила:

iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT

1) icmp echo request е NEW и така е допуснат в OUTPUT веригата.

2) icmp echo reply, стига само да отговаря на echo request, е ESTABLISHED
и така е допустим в INPUT веригата. echo reply не може да се допусне в OUTPUT
веригата заради правилата по горе защото няма NEW в INPUT веригата да позволи
echo заявки и отговорът трябва да бъде в отговор с заявката.

3) icmp redirect, защото не е request-reply базиран и е RELATED, така че
може да бъде допуснат в двете INPUT и OUTPUT вериги стига само да има
вече tcp или udp връзка в state таблицата, която може да съвпадне отново.
 
Connection tracking и ftp

Първоначално трябва да заредите ip_conntrack_ftp модулът.

Предполагайки че имате една домашна машина; просто правило позволяващо
ftp връзките ще бъде:

iptables -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT

(Моля да обърнете внимание, че предполагам че имате отделни правила позволяващи
всякакви icmp RELATED връзки. Моля да видите примерът ми за това).

Това не е цялата история. ftp връзката се нуждае също така от data-channel, който
също така може да бъде един от двата:

1) Active ftp

FTP клиентът изпраща номерът на портът през ftp канал чрез PORT команда към
ftp сървърът. Тогава ftp сървърът се свързва от 20 порт на този порт и изпраща
информация, като файл, или изходът на команда.

За да позволите active ftp без да знаете номерът на портът който се използва, ще
ви трябва правило което позволява връзки от 20 порт от ftp сървъри до големи
портове (портове > 1023) на ftp клиентите. Просто това е толкова общо за да бъде
защитено.

Включете ip_conntrack_ftp модулът. Този модул може да разпознае
PORT команда и да отвори порт. Също така, ftp-data връзката може да се класифицира
като RELATED към оригиналната изхождаща вризка от 21 порт, така че не ни трябва
NEW като state съвпадение за връзката в INPUT веригата. Следните правила ще
обслужат нуждите ни:

iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT

2) Passive ftp

Отново се използва PORT командата, но този път е от сървърът към клиента.
Клиентът се свързва към сървърът за трансфер на данни. Откакто връзката е
със същото значение както оригинална ftp връзка, passive ftp е по защитено
от active ftp, но обърнете внимание, че този път дори незнаем портовете.
Сега имаме връзка м/ почти произволни портове.

Включете още един път ip_conntrack_ftp модула. Този модул може да разпознае
PORT команда и да отвори порт. Вместо NEW в state съвпадението на OUTPUT
веригата, можем да използваме RELATED. Следните правила ще ви задоволят:

iptables -A INPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED,RELATED -j ACCEPT



   


Ключови думи: unix connection tracking prerouting верига output верига dnat пакет postrouting верига


Още уроци от тази рубрика


 
  • Подобни теми от myLinks
 

 За автора: Inventive  
На 14 години съм и се казвам Светослав Генов. Занимавам се с PHP и MySQL предимно. Също така съм и mIRC скирптер. Имам опит и с Adobe Photoshop.
   
 1 посетител чете този урок (0 потребители и 1 гост)  
Активни потребители: ---
   
  

Еmail  
 

Много добра идея да се преведе този материал, но имам някоя и друга забележкапо превода:

 
Понеже при него липсват редица числа, udp е още познат като 'stateless' протокол.
в оригинала пише:
 
Because it lacks sequence numbers,
т.е. става въпрос за номера на пакета известен като sequence number, който от своя страна се избира по случаен начин, но който се интересува може да намери информация, как изглежда TCP хедърът.


 
TCP връзката се открива чрез тройно захващена включващо
да, в повечето случаи буквалният превод трябва да се избягва, но не винаги, както в този случай.
three-way handshake се превежда като "тристранно ръкостискане" - така е прието.
Ако забележа и други ще ги напиша, за да може да се изглади стила.
И още, редно е да се дава източникът, от който е превеждано, ако аз не съм забелязал, кеде го пише, моля за извинение.

  bozho на 07.08.2007 18:58

 

 
  • Интересно от Софтуер
 



IT-PLACE.NET © 2004 - 2008