The OpenNET Project / Index page

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

Автоматическое изменение правил IPTABLES для IP адресов из записей DynDNS
Возникла задача предоставить сервис для клиентов, использующих внешние динамические адреса. 
Доступ к сервису ограничен правилами IPTABLES.

Клиентам, которым необходимо получить услугу предлагается создать учетную
запись на ресурсе dyndns.org,
клиент получит доменное имя в виде client.dyndns.org.

При каждом изменении ip адреса клиента мы всегда узнаем его адрес по доменному
имени. Если мы добавим
правило в iptables для этого доменного имени, правило будет работать только для
текущего  ip адреса клиента
и при последующем изменении ip адреса, доступ к сервису будет ограничен.

Оригинал решения был найден здесь:
http://dave.thehorners.com/content/view/86/65/ , а мы всего лишь доработаем
этот скрипт.

Создаем несколько каталогов:

   /root/dynhosts/ - общий каталог
   /root/dynhosts/zones/ - здесь будем хранить файлы доменных зон клиентов
   /root/dynhosts/logs/ - лог файлы работы скрипта
   /root/dynhosts/scripts/ - здесь будет находится сам запускаемый скрипт

Создаем лог-файл:

   touch /root/dynhosts/logs/dynhosts.log

Создаем файл зоны клиента:

   touch /root/dynhosts/zones/client.dyndns.org

Создаем сам скрипт /root/dynhosts/scripts/firewall-dynhosts.sh


   #!/bin/bash
   #
   # filename: firewall-dynhosts.sh
   #
   NOW=$(date)
   CHAIN="dynamichosts"  # change this to whatever chain you want.
   IPTABLES="/sbin/iptables"
   
   # create the chain in iptables.
   $IPTABLES -N $CHAIN
   # insert the chain into the input chain @ the head of the list.
   $IPTABLES -I INPUT 1 -j $CHAIN
   # flush all the rules in the chain
   $IPTABLES -F $CHAIN
  
   FILES=`ls --format=single-column /root/dynhosts/zones/`
   
   echo $FILES
  
   for file in $FILES
   do
      HOSTFILE="/root/dynhosts/zones/$file"
      echo $HOSTFILE

      # lookup host name from dns tables
      IP=`/usr/bin/dig +short $file | /usr/bin/tail -n 1`
      if [ "${#IP}" = "0" ]; then
         echo "$NOW Couldn't lookup hostname for $file, failed." >> /root/dynhosts/logs/dynhosts.log

         continue
      fi
 
      OLDIP=""
      if [ -a $HOSTFILE ]; then
         OLDIP=`cat $HOSTFILE`
         echo "CAT returned: $?"
      fi

      # save off new ip.
      echo $IP>$HOSTFILE

      echo "Updating $file in iptables."
      echo "Inserting new rule ($IP)"
      $IPTABLES -A $CHAIN -s $IP/32 -j ACCEPT

   done
   exit0

Запускаем скрипт:

   /root/dynhosts/scripts/firewall-dynhosts.sh

   iptables: Chain already exists
   client.dyndns.org
   CAT returned: 0
   Updating client.dyndns.org in iptables.
   Inserting new rule (213.64.141.6)

Проверяем,

   cat /root/dynhosts/zones/client.dyndns.org
   213.64.141.6

   /sbin/iptables -nL dynamichosts

   Chain dynamichosts
   target     prot opt source               destination
   ACCEPT     all  -  213.64.141.6         0.0.0.0/0

Если такого доменного имени не существует в /root/dynhosts/logs/dynhosts.log
была бы запись следующего содержания:

   Tue Aug 25 09:47:15 MSD 2009 Couldn't lookup hostname for client.dyndns.org, failed.

После того как контракт с клиентом истек достаточно удалить файл его зоны из /root/dynhosts/zones/.

Осталось добавить выполнение скрипта в крон.
 
07.09.2009 , Автор: zaikini , Источник: http://subnets.ru/blog/?p=1007...
Ключи: iptablse, shell, script, dns
Раздел:    Корень / Программисту и web-разработчику / Shell / Готовые скрипты

Обсуждение [ RSS ]
  • 1.1, Nas_tradamus (ok), 13:41, 07/09/2009 [ответить]  
  • +/
    А по логину и паролю или сертификату нельзя было разграничить доступ? :)
     
     
  • 2.2, Аноним (-), 14:01, 07/09/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >А по логину и паролю или сертификату нельзя было разграничить доступ? :)

    Причин может быть много, от желания лишний раз перестраховаться и дополнительно прикрыть сервис фаерволом, до варианта когда за каждым IP сидит домашняя сетка с кучей людей через NAT и им нужно простым способом дать доступ к web/ftp.

     

  • 1.3, Andrey Mitrofanov (?), 17:27, 07/09/2009 [ответить]  
  • +/
    Гм, а прикрутить какой-нибудь port knock демон, "слушающий" не отдельный диапазон портов, а [закрытый по умолчанию] порт охраняемого сервиса, и открывающий его по успешной проверке обратного dyndns разрешения адреса? Ну, плюс какое-нибудь выстраивание проверок в очередь, чтоб не заDOSисли...

    Регистрация на dyndns -> первая попытка соединения -> облом + отработка кнокера -> вторая попытка подключения -> норм.соединение.

    Хотя, выкидывать из разрешающих таблиц тоже как-то надо. ipt_recent - ом "expire"-ить?...

    Главное, чтоб никакого крона. %)

    И кста, об event-драйвен (врагам udev-а: сильно не пинайте, я же даже не написал никаких _пастчей_): даёшь %) ipt_resent-у и ipt_set-у CRUD-hookи-callbackи?

    Интересно, ломящиеся на порт ssh бот-неты такую конструкцию быстро положат? $) А противо-бот-нет-ные костыли придумать...

     
  • 1.7, chodorenko (?), 00:06, 18/09/2009 [ответить]  
  • +/
    а теперь представим ситуацию, я легитимный пользователь получаю IP, регистрирую зону , создаю там запись в автоматическом режиме , пользуюсь интернетом всё хорошо. выключаюсь , и вдруг мой IP выдаётся другому клиенту, скрипт лезет по файлам, находит что IP принадлежит мне(я не удалял запись и не менял её мне инет в данный момент не нужен) и пускает нелегитимного пользователя как меня

    теперь рассмотрим скрипт
    $IPTABLES -F $CHAIN
    те этой строкой мы очищаем таблицу правил для того чтобы создать новую таблицу но !!!!!
    1.время формирования новой таблицы не равно 0 и соответственно мы прерываем все соединения от всех динамических клиентов
    2. если использовать крон то данное действие мы будем производить с определённой периодичностью(чем актуальнее для нас скорость обновления тем чаще будут обрываться соединения)

    исправление разрывов можно избежать добавив первым(для уменьшения нагрузки) правилом
    $IPTABLES -I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPTABLES -I INPUT 2 -j $CHAIN

    REM вот не помню но !! по моему инзерт (-I) сдвигает правила, а не заменяет текущую позицию(-R), посмотрите после N запусков содержимое таблицы INPUT и не удивляйтесь потом почему это у меня такая большая загрузка системы в пространстве ядра

    производить формирование таблицы правил в отдельный файл
    echo #/bin/bash > temp_rules.sh
    chmod 700 temp_rules.sh

    for file in $FILES
    ...Skip...
    echo "$IPTABLES -A $CHAIN -s $IP/32 -j ACCEPT" >> temp_rules.sh
    ...Skip...
    done

    и очистку таблицы $CHAIN производить после обработки всех данных сразу же перед внесением новых правил
    $IPTABLES -F $CHAIN
    temp_rules.sh
    rm -f temp_rules.sh

    ну гдето так :)
    PS: господа если пишем в новости  "а мы всего лишь доработаем этот скрипт" так давайте дорабатывать

     
     
  • 2.8, chodorenko (?), 00:10, 18/09/2009 [^] [^^] [^^^] [ответить]  
  • +/
    строку echo #/bin/bash > temp_rules.sh заменить на echo "#!/bin/bash" > temp_rules.sh
     

  • 1.9, danvyr (ok), 10:16, 19/12/2013 [ответить]  
  • +/
    Мой вариант скрипта для разрешения прохода мимо маршрутизатора нужных хостов на удалёную машину

    #!/bin/bash  
      #
      # filename: firewall-dynhosts.sh
      #
      PATH="/usr/local/sbin/dynhosts"
      NOW=$(/bin/date)
      CHAIN="dynamichosts"  # change this to whatever chain you want.
      IPTABLES="/sbin/iptables"

      # create the chain in iptables.
    $IPTABLES -N $CHAIN -t nat

    FILES='/bin/ls --format=single-column $PATH/zones/'

    echo $FILES

    for file in $FILES
    do
         HOSTFILE="$PATH/zones/$file"
         echo $HOSTFILE

         # lookup host name from dns tables
         IP='/usr/bin/dig +short $file | /usr/bin/tail -n 1'
         if [ "${#IP}" = "0" ]; then
            echo "$NOW Couldn't lookup hostname for $file, failed." >> /$PATH/logs/dynhosts.log

            continue
         fi

         OLDIP=""
         if [ -a $HOSTFILE ]; then
            OLDIP='cat $HOSTFILE'
            echo "CAT returned: $?"
         fi

         # save off new ip.
         echo $IP>$HOSTFILE


         echo "Updating $file in iptables."
         echo "Inserting new rule ($IP)"

         $IPTABLES -I $CHAIN  -t nat  -p tcp -s $IP --dport 6666    -j DNAT --to-destination 192.168.1.1:3389

    done

    #$IPTABLES -F $CHAIN

    NUMFILES='/bin/ls $PATH/zones -1A|/usr/bin/wc -l'

    for file in $FILES
    do
       I=1
       let "SUM=$I+$NUMFILES"
       echo "Deleting $SUM rule from $CHAIN"
       '$IPTABLES -t nat -D $CHAIN  $SUM '
       let "I=$I+1"

    done

    exit

     


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




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

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