от Vladsun(30-10-2006)

рейтинг (26)   [ добре ]  [ зле ]

Printer Friendly Вариант за отпечатване

Целта на статията е да опише начин за дистанционно и отваряне/затваряне на определени портове при това с високо ниво на сигурност. Използва се техника наречена в литературата като "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 >>