The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Реализация идеи "port knocking" на bash для Linux iptables (port security shell linux iptables)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: port, security, shell, linux, iptables,  (найти похожие документы)
From: Коротков Евгений <zhokuzma[at]bigfoot.com> Newsgroups: email Date: Mon, 13 Oct 2003 14:31:37 +0000 (UTC) Subject: Реализация идеи "port knocking" на bash для Linux iptables В связи с последними уязвимостями openssh и идеями навеянными статьей на http://www.linuxjournal.com о "стуке в порты" ("port knocking") http://www.linuxjournal.com/article.php?sid=6811 решил написать пару скриптов с собственной реализацией (призванной быть более безопасной) сервера и клиента на bash для осуществления ssh соединения (так же могут использоваться с небольшой доработкой для соединения по другим протоколам ftp,telnet и т.п.) Сервер делает следующее: - считывает из лог файла информацию о "стуке" на заданный диапазон закрытых портов (port0:port+4095) - секретные порты из этого диапазона зависят от пароля и временной метки (защита от прослушивания) - временная метка считается с точностью до n секунд (по умолчанию 100) - при правильной последовательности портов (до истечения этих n секунд эта последовательность больше не принимается) - открывает на некоторое время ssh порт для получения запросов на соединение - все остальное время разрешено только ESTABLISHED соединение на ssh порту листинг сервера: ++++++++++++++++++ #!/bin/bash # base port of knocking (range from port0 to port0+4095 must be free) port0=10000 # password pass="some_password" # unique string of knocking logs id_string="PORT_KNOCKING" # knocking log file log_file="/var/log/some/file.log" # ip of our interface our_ip="xxx.xxx.xx.xxx" # ------------------------------- # allowing only one connect from ip in this time period (seconds) # and also in other words max period of client and server clock desynchronisation time_period=100 # max time (in seconds) between two knocks in knocking sequence delta=2 # time period (in seconds) when door is open sleep_time=10 # don't touch time_flag=0 used_time=0 cnt=0 # iptables initialisation for knocking listening port1=$(($port0+4095)) # default policy is DROP iptables -A INPUT -s 0.0.0.0/0 -d $our_ip -p tcp --syn --dport $port0:$port1 -j LOG --log-level notice --log-prefix "$id_string " # if policy is ACCEPT #iptables -A INPUT -p tcp --dport $port0:$port1 -j DROP # allow only established ssh connection iptables -A INPUT -s 0.0.0.0/0 -d $our_ip -m state --state ESTABLISHED -p tcp --dport 22 -j ACCEPT tail -n1 --follow=name --retry $log_file | { # read no using line read # main cycle of reading log lines while [ 1 == 1 ] do read str # get time in seconds since `00:00:00 1970-01-01 UTC' time=`date +%s` # check is it our log line ok=`echo $str | grep $id_string` if [ -z "$ok" ]; then # to next iteration of main cycle continue fi # extract source ip and destination port from log line for fld in $str do case "${fld:0:4}" in "SRC=") sip=${fld:4} ;; "DPT=") dport=${fld:4} esac done # calculate secure combination of ports and time up to which this combinaton is valid if [ $time -ge $used_time ]; then time_stamp=$(($time/$time_period)) sum=`echo $pass$time_stamp | md5sum` i=0 sec_ports="" while [ $i -lt 16 ] do j=${sum:$i*2:2} port=$(($port0+0x$j*16+$i)) sec_ports="$sec_ports $port" i=$((i+1)) done remainder=$(($time%$time_period)) used_time=$(($time-$remainder+$time_period)) used_ips="" fi # time period from last successsful processing dtime_flag=$(($time-$time_flag)) if [ $dtime_flag -gt $delta -o $cnt -eq 0 ]; then # check if our ip already processed in current time period ok=`echo $used_ips | grep $sip` if [ "$ok" ]; then # to next iteration of main cycle continue fi # begin processing for this ip cur_ip=$sip ports="" cnt=0 else # not allowed simultaneously process more then one ip if [ $sip != $cur_ip ]; then # to next iteration of main cycle continue fi fi # time label of successful processing time_flag=$time # list of processing ports ports="$dport $ports" # port counter cnt=$((cnt+1)) # it's time to check port sequence if [ $cnt -eq 16 ]; then cnt=0 # check if incoming knocking correct for port in $sec_ports do ok=`echo $ports | grep $port` if [ -z "$ok" ]; then continue fi done # open our door for some time if [ "$ok" ]; then used_ips="$used_ips $cur_ip" # turn on incoming ssh connects # if policy is ACCEPT # iptables -D INPUT -p tcp --dport 22 -j DROP iptables -A INPUT -s $cur_ip -d $our_ip -p tcp --syn --dport 22 -j ACCEPT # if policy is ACCEPT # iptables -A INPUT -p tcp --dport 22 -j DROP sleep $sleep_time # turn off incoming ssh connects iptables -D INPUT -s $cur_ip -d $our_ip -p tcp --syn --dport 22 -j ACCEPT fi fi done } ++++++++++++++++++++++++ конец листинга сервера Клиент делает следующее - срашивает первый порт диапазона за которым следит сервер - спрашивает пароль (известный только серверу) - "стучит" в заданные порты (зависящие от пароля и временной метки) - пытается осуществить ssh соединение листинг клиента : --------------- #!/bin/bash # program to knock (telnet or netcat) prog="telnet" # must be equal to time period on knocking server time_period=100 # period between knocking sequence and ssh connect sleep_period=2 # ssh user username=$1 # destination ip ip=$2 if [ $# -ne 2 ]; then echo "usage: ./clientname username ip_address" exit fi read -p "enter base port of knocking: " -s port0 echo read -p "enter knocking password: " -s pass echo # calculate secure sequence of ports time=`date +%s` time_stamp=$(($time/$time_period)) sum=`echo $pass$time_stamp | md5sum` i=0 ports="" while [ $i -lt 16 ] do j=${sum:$i*2:2} port=$(($port0+0x$j*16+$i)) ports="$ports $port" i=$((i+1)) done # start knocking ( for port in $ports do $prog $ip $port & done pkill $prog ) >/dev/null 2>&1 echo "knocking done" sleep $sleep_period echo "trying to ssh ..." ssh -l $username $ip --------------------- конец листинга клента Так же можно написать стартовый скрипт что типа этого --------------- #!/bin/bash export PATH="/bin:/usr/bin:/sbin:/usr/sbin" knocking_server.sh & --------------- запускаться который должен после запуска firewall но до запуска syslog демона Существующие недостатки : - необходимость синхронизации часов на сервере и клиенте с точностью до заданной величины (по умолчанию 100 секунд) - возможно проведение DoS - в коментариях могут быть языковые ошибки :) Все остальные тонкости о которых не было упомянуто - в коде скриптов.

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
  • 1, le (?), 13:09, 03/05/2009 [ответить]  
  • +/
    http://www.zeroflux.org/projects/knock ?
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру