LINUX-BG   Адрес : http://www.linux-bg.org
Забрана за SSH логин от случайни/атакуващи потребители
От: Vladsun
Публикувана на: 30-10-2006
Адрес на статията: http://www.linux-bg.org/cgi-bin/y/index.pl?page=article&id=advices&key=374186810
Целта на статията е да опише начин за дистанционно и отваряне/затваряне на определени портове при това с високо ниво на сигурност. Използва се техника наречена в литературата като "port knocking", т.е. чрез строго определена комбинация от опити за връзки към определени портове на отдалечената машина се променят правилата на защитната й стена, като по този начин се дава достъп до определени сървърни приложения.
По същество описаната техника може да се използва за много и различни цели, но тук ще разгледаме приложението й за противодействие срещу атаки насочени към SSH приложенията. Повечето администратори виждат огромни логове за неуспешни (дай боже;) ) опити за SSH логин чрез използване на слаби пароли и често срещани потребителски имена. С увеличаването на броя на потребителите, които се нуждаят от SSH достъп до конзолата се увеличава и вероятността от пробив. Най-лесното решение би било да се отказва TCP връзка на случайните потребители (прим. по ИП адрес), но това би било свързано с недостатъчно добра гъвкавост на управлението на потребителите. Поради това смятам, че предложеното тук решение (или по-скоро имплементация на решението - идеята не е моя :) ) е доста по-добро по отношение както на сигурност, така и на гъвкавост. Все пак, реализацията със сигурност не е идеална и подлежи на промяна.

Системни изисквания
Идеята е реализиран чрез използване на Perl модулите и iptables с добавен "recent match".

Инсталиране и употреба
На отдалечената машина (към която искаме да се свържем) се копират следните два Perl файла:

knockoff.pl
#!/usr/bin/perl
 
 $exist = `iptables -nL INPUT | grep SSH_KNOCK`;
 
 if ($exist ne '')
 {
         `iptables -D INPUT -m state --state NEW -p tcp -j SSH_KNOCK`;
         `iptables -F SSH_KNOCK`;
         `iptables -X SSH_KNOCK`;
         print "[+] Port knocking rules deactivated.\n";
 }
 else
 {
         print "[-] Port knocking rules have been already deactivated.\n";
 }


knockon.pl
#!/usr/bin/perl
 
 if (@ARGV < 1) {         
         print "Usage:\r\n";         
         print "Specify passkey! \r\n\r\n";
         exit(); 
 }   
 $port = 0;  
 srand($ARGV[0]);  
 $exist = `iptables -nL INPUT | grep SSH_KNOCK`;  
 if ($exist ne '') {   
         `iptables -F SSH_KNOCK`; 
 } else { 
         `iptables -N SSH_KNOCK`;
         `iptables -I INPUT -m state --state NEW -p tcp -j SSH_KNOCK`; 
 }  
 `iptables -A SSH_KNOCK -p tcp --dport 22 -m recent --rcheck --name SSHK -j ACCEPT`;
 `iptables -A SSH_KNOCK -m recent --rcheck --name SSHK -j RETURN`; 
 # A potential bug here - not checking if there are successive random generated port numbers 
 for ($i=0; $i<5; $i++) {         
         $port = int(rand(40000) + 1024);
         $prev_port = $port - 1;
         $next_port = $port + 1; 
         `iptables -A SSH_KNOCK -p tcp --dport $port -m recent --name SSHK --set -j DROP`;         
         `iptables -A SSH_KNOCK -p tcp --dport $prev_port -m recent --name SSHK --remove -j DROP`;         
         `iptables -A SSH_KNOCK -p tcp --dport $next_port -m recent --name SSHK --remove -j DROP`; 
 }
 `iptables -A SSH_KNOCK -p tcp --dport 22 -j DROP`;  
 print "[+] Port knocking rules activated.\n"; 


А на локалната машина се копира файла:

knock.pl
#!/usr/bin/perl
 
 use IO::Socket;
 
 if (@ARGV < 2) {         
         print "Usage:\r\n";         
         print "Specify host !\r\n";
         print "Specify passkey! \r\n\r\n";
         exit(); 
 }
 $serv = $ARGV[0];
 $serv =~ s/http:\/\///ge;
 $port = 0;
 srand($ARGV[1]);
 for ($i=0; $i<5; $i++) {
         $port = int(rand(40000)+1024);
         $sock = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$serv", PeerPort=>"$port", Timeout=>"1");
         close($sock);
 }
 
 print "[+] Port knocking finished.\n";
 
 $sock = IO::Socket::INET->new(Proto=>"tcp", PeerAddr=>"$serv", PeerPort=>"22")
 or die "[-] Port 22 - SSH NOT open.\n";
 close($sock);
 print "[+] Post 22 - SSH is now open.\n";


За пускането на описаната защитна система се изпълнява на отдалечената машина:

knockon.pl 12345
където 12345 е поредица от числа, която ще се използва за разрешаване на достъпа от локалната машина. След изпълняването на тази команда порт 22 при сканиране се определя като "филтриран" и SSH връзка не може да се осъществи.

За да се разреши SSH достъпа от локалната машина се пуска:

knock.pl 12345
Цифровите низове трябва да са еднакви за да се получи разрешение.
С това порт 22 на отдалечената машина е отворен при това само за ИП адреса, от който сме поискали разрешение за достъп. За да активираме защитата отново е необходимо преди да излезем от шела да стартираме пак:
knockon.pl 12345
Защитата е така направена, че при последователно сканиране на портове да не се дава достъп. При сканиране със случайно избран ред на портовете вероятността за даване на достъп е изключително малка.

Проблеми за които се знае:

1) За да се стартира защитата от друг потребител освен root е необходимо да се дадат права за изпълнение на iptables като root - прим. със sudo или чрез chmod 6755, което не е добре :(
2) Може да се получи припокриване на разрешаващите и забраняващите портове при генерирането на псевдо-случайната поредица - изберете друг код :)

<< Как да форматираме Windows дялове | amaroK - next generation multimedia player >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са copyleft т.е. могат свободно да бъдат копирани и разпространявани с изискването изрично да се упоменава името на автора, както и да се публикува на видно място, че те са взети от оригиналния им URL-адрес на този сървър (http://www.linux-bg.org). Авторските права на преводните материали принадлежат на техните автори. Ако с публикуването тук на някакъв материал неволно са нарушени нечии права - след констатирането на този факт материалът ще бъде свален.

All trademarks, logos and copyrights mentioned on this site are the property of their respective owners.
Linux is copyright by Linus Torvalds.
© Линукс за българи ЕООД 2007
© Slavei Karadjov 1999 - 2006

All rights reserved.

Изпълнението отне: 0 wallclock secs ( 0.17 usr + 0.02 sys = 0.19 CPU)