Já nějak nechápu smysl těchto fíglů. Jsem asi trochu oldschool, ale mám prostě pocit, že port je místo, na který se připojím, potom jsou ověřena moje oprávnění a potom můžu službu používat.
Pokud mi vadí, že mě na standardním portu pořád otravují boti, nebo se bojím, že by služba mohla být děravá, přesunu ji na jiný port, o kterém vím jenom já.
Technika popsaná v článku prostě přidává jakoby „další heslo navíc“ – principielně je efekt úplně stejnej jako při přesunu na nějaký vysoký port (akorátže to „heslo“ je v tomhle případě delší – sekvence místo jednoho čísla) – přináší to ale reálně nějaké zvýšení bezpečnosti?
A když už chci teda port před někým maskovat a použít další heslo navíc, není daleko čistší a efektivnější použít třeba přihlášení na webové stránce a otevření portu poté?
Pokud to chápu správně – kdybych hledal port, na kterém běží služba, na kterou chci útočit – musím zjistit, které porty jsou ochotny si se mnou povídat. Takto mlčí i port, na kterém ona služba je – navenek je stroj mrtvý, ale oživím jej právě oním zaťukáním na ty správné porty.
Výsledek – zatím co v případě prvním zjistím port a pak už jen řeším, jak nejlépe zaútočit, v případě druhém proklepnu všechny porty a zjistím, že nemám kam útočit, protože stroj je tuhý a nereaguje.
Náhodné vyťukání je možné, ale nepravděpodobné…
Defakto mi to připomíná situaci, kdy si zavolám kamarádovi, aby mi otevřel port na svém PC, abych k němu mohl nakouknout – akorát bez nutnosti telefonu a kamaráda u toho PC.
Ano, to je pravda. Mně ale není jasné, proti komu je vlastně toto opatření zaměřeno.
Stejného efektu bych totiž dosáhl tak, že bych před samotným SSH spojením poslal na jeho port jedno heslo navíc – a teprve podle něj by začal/nezačal SSH protokol. A aby to bylo ještě peprnější, to první heslo posílám nezašifrovaně, takže ho může kdokoli odposlechnout :)
Jinými slovy – hodně podobného efektu dosáhnu, když pro SSH zvolím heslo dlouhé jako součet délek těch dvou hesel…
Možnost s „vyťukáváním“ jednotlivých bytů nějaké zprávy mi už přijde úplně ulítlá – jaký je rozdíl třeba oproti použití UDP?
V případě UDP a firewallu, který packety na neplatný porty zahazuje, žádné rozlišení otevřený/zavřený port neexistuje.
V případě TCP je to tak, jak jsem napsal – abych dosáhl stejného efektu, stačí mi předřadit wrapper, který povolí přístup ke službě jen když dostane správné heslo. Když zadám heslo špatné, tak je port jakoby taky „zavřený“, protože k té službě se prostě nedostanu.
Jemné rozdíly jsou samozřejmě z pohledu nebezpečí DOS apod. – ale vzhledem k tomu, že knockd musí nějak evidovat přístup na porty taky, nevím, kde je ten nárůst bezpečnosti.
Je to asi tak, jako když přijdu k domu, kde jsou všechny dveře zavřené a mám domluveno, že klepnu třikrát na první, dvakrát na druhé a pak mi třetí otevře vrátný a když se mu prokážu občankou, pustí mě dovnitř.
Nechápu, jaký je rozdíl v bezpečnosti oproti klasické situaci, kdy jsou první i druhé dveře zavřené a hluché a třetí sice otevřené a stojí v nich vrátný, ale za ním jsou ještě dveře pancířové, které mi otevře jen když předložím občanku…
Jenže ta „občanka“ (tj. ssh autentizace heslem nebo certifikátem) je podstatně silnější než ten tajný klepací kód. Kdo umí vyrobit falešnou občanku, toho nějaké klepání na dlouho nezastaví…
Jinými slovy, je to prostě jedna vrstva autentizace navíc – tj. (opakuju) je to stejné jako bych měl firewall, který nechtěné UDP zahazuje a na jednom UDP portu chytá heslo… Popsané řešení nepřináší imho NIC navíc oproti tomuhle řešení, které je podstatně jednodušší.
Tak nějak to osobně vidím já v případě použití knockd jako univerzálního auth řešení (zmíněný range 256 portů a třeba asymetrický klíč s timestamp, …).
Port knocking vidím jako skvělou obranu proti DoS u služeb jako SSH. Proto používám sekvenci 3–5 portů a jednoduchý knock. Skript na serveru mi každý týden generuje novou sekvenci na další týden, kterou si syncnu s notebookem (tzn. mám týden na sync, abych se další týden připojil) – čistě pro případ, že by to snad někdo odposlouchával.
V případě odposlechu může totiž přinejhorším „útočník“ získat přístup na port SSH, pořád tam má před sebou key-based auth, kterou asi za ten týden neprolomí. Když tedy pominu, že možnost takového odposlechu je pod 1%.
V mých očích je port knocking JEN obscurity-based řešení, tedy vhodný doplněk běžného zabezpečení, který by měl zůstat jednoduchý v principu. Jakmile totiž útočník zjistí, že někdo „klepal“ (systematicky posílal data na zavřené porty), ihned ví, že daný range monitoruje nějaký daemon a že jakýkoli packet v něm je jistým způsobem (ideálně v userspace) zpracován. A (D)DoS je na světě.
Vím, existují chyby v SSH serverech, stejně tak se značně zvyšuje pravděpodobnost výskytu bugu v knockd, pokud tam někdo začne cpát věci jako RSA. Opět – pokud někdo potřebuje dodatečný security layer mezi službou a port-knock mechanismem, ať si tam strčí nějakou proxy nebo podobné řešení, ale proboha, ať nedělá z jednoduchého klepání orchestr :)
PS ještě k původnímu postu: Jde o to, že při zadání „hesla“ už útočník ví, že na tom portu něco naslouchá a může tomu cpát tuny packetů, které se dostanou do userspace. Naproti tomu knockd může naslouchat třeba na 5 tajných portech a zahazování na všech ostatních obstarává kernel (vlastně to i na těch 5, sk_buff se jen zkopíruje pro knockd, podobně jako u tcpdump), takže při (D)DoS je zátěž CPU daleko menší. Kapacita linky už je další věcí.
U webserveru by to bylo celkem jedno, ale u firemního routeru, u kterého nejsou potřeba žádné veřejně přístupné služby, se to docela hodí.
Nutno podotknout, že současná verze knockd, založená na knihovně pcap, tohle asi nebude umět, a tak se všechny přijaté packety zkopírují pro userspace, ale to je problém implementace.
Nicméně hlavním bonusem zůstává to, že útočník neví, zda vůbec něco na nějakých portech naslouchá.
eer, pletu se – knockd používá pcap, jehož filter sahá přímo na BPF ( http://en.wikipedia.org/…acket_Filter ), a k sestavení filteru používá relativně komplikovanou funkci generate_pcap_filter() (pro podrobnosti vizte zdrojový kód – http://www.zeroflux.org/projects/knock source tarball), tudíž zbytečným kopiím je skutečně zabráněno.
Z dokumentace pcapu:
The process is quite simple. After we have already called pcap_open_live() and have a working sniffing session, we can apply our filter. Why not just use our own if/else if statements? Two reasons. First, pcap's filter is far more efficient, because it does it directly with the BPF filter; we eliminate numerous steps by having the BPF driver do it directly. Second, this is a lot easier :)
Je to asi tak, jako když přijdu k domu, kde jsou všechny dveře zavřené a mám domluveno, že klepnu třikrát na první, dvakrát na druhé a pak mi třetí otevře vrátný a když se mu prokážu občankou, pustí mě dovnitř.
Nechápu, jaký je rozdíl v bezpečnosti oproti klasické situaci, kdy jsou první i druhé dveře zavřené a hluché a třetí sice otevřené a stojí v nich vrátný, ale za ním jsou ještě dveře pancířové, které mi otevře jen když předložím občanku
Nechápete rozdíl mezi pancířovými dveřmi na občanku, a pancířovými dveřmi na občanku o kterých nevíte? Nezapomínejte že v prvním případě jsou dveře také pancířové, port-knocking nějak nesnižuje zabazpečnení dveří (démona) jako takového.
Rozdíl je zcela zásadní – pro port-knocking mohou být (jsou) porty zavřené, nikoliv otevřené. A na zavřený port se nedá připojit, nedá se zaútočit na službu která na něm (ne)běží. V tom je ten rozdíl.
Právěže dá. A tenhle démon jen přináší další level, kde může být nebezpečný kód, přinejhorším vedoucí k tomu, že se tím sshd nebude muset útočník vůbec zabývat.
proto bych to resil primo v iptables, coz uz je davno popsano, ne dalsim deamonem, napr:
-A INPUT -m state –state NEW -p tcp -m tcp –dport 22 –tcp-flags SYN,RST,ACK SYN -m recent –check –seconds 60 –name SSH_ALLOW -j ACCEPT
-A INPUT -m state –state NEW -p tcp -m tcp –dport 123 –tcp-flags SYN,RST,ACK SYN -m recent –set –name SSH_FIRST -j DROP
-A INPUT -m state –state NEW -p tcp -m tcp –dport 234 –tcp-flags SYN,RST,ACK SYN -m recent –check –seconds 10 –rttl –name SSH_FIRST -j SSH_SECOND
-A SSH_SECOND –tcp-flags SYN,RST,ACK SYN -m recent –set –name SSH_SECOND
-A SSH_SECOND –tcp-flags SYN,RST,ACK SYN -m recent –remove –name SSH_FIRST
-A SSH_SECOND -j DROP
-A INPUT -m state –state NEW -p tcp -m tcp –dport 345 –tcp-flags SYN,RST,ACK SYN -m recent –check –seconds 10 –rttl –name SSH_SECOND -j SSH_THIRD
-A SSH_THIRD –tcp-flags SYN,RST,ACK SYN -m recent –set –name SSH_THIRD
-A SSH_THIRD –tcp-flags SYN,RST,ACK SYN -m recent –remove –name SSH_SECOND
-A SSH_THIRD -j DROP
-A INPUT -m state –state NEW -p tcp -m tcp –dport 456 –tcp-flags SYN,RST,ACK SYN -m recent –check –seconds 10 –rttl –name SSH_THIRD -j SSH_FOURTH
-A SSH_FOURTH –tcp-flags SYN,RST,ACK SYN -m recent –set –name SSH_ALLOW
-A SSH_FOURTH –tcp-flags SYN,RST,ACK SYN -m recent –remove –name SSH_THIRD
-A SSH_FOURTH -j DROP
( rychle vygooglovano – http://uhacc.org/…ms/index.php?…)