Загрузка правил iptables при запуске (Ubuntu 10.04 - 10.10)

Thanks: 70
Say if this page is useful for you
Author: Sergey Popov (aka azure)
Published on 2011.02.08
Last modified on 2012.01.09

Введение

Итак, хотел я как-то настроить фаерволл в убунте. И что я обнаружил? Что из коробки поддерживается только некий ufw с примитивными возможностями и таким же синтаксисом команд. И все уже сделано для того, чтоб им было удобно пользоваться. Типа, вот вам решение — пользуйте.

Хотим фаервол — включаем его (заодно и помещаем в автозагрузку). Хотим — выключаем (и убираем из автозагрузки):

# ufw start
# ufw stop

iptables vs. ufw

Но позвольте! Ведь ufw не умеет и десятой доли того, что умеет iptables! Возможно, кому-то синтаксис ufw понятней. Но я то не могу настраивать редиректы в таблице nat! Да, существуют обходные меры... Но это такие кривые хаки...

Итак, мотивацией для написания скрипта инициализации netfilter с помощью iptables (кроме зарплаты), стало желание нормально работать с iptables в убунте. Итак, был рожден следующий скрипт:

#! /bin/sh

### BEGIN INIT INFO
# Provides:          iptables
# Required-Start:    
# Required-Stop:     
# Should-Start:      
# Default-Start:     3 4 5
# Default-Stop:      0 1 6
# Short-Description: Linux firewall initialisation and save
# Description:       this script is for configuring linux firewall (netfilter)
#                    with help of command-line utility called iptables
### END INIT INFO

#set -e

DAEMON=/sbin/iptables
ipt=$DAEMON

test -x $DAEMON || exit 0

if [ ! -d /etc/iptables ]; then
        mkdir /etc/iptables
fi

if [ ! -f /etc/iptables/rules.save ]; then
        /sbin/iptables-save -c > /etc/iptables/rules.save
fi

. /lib/lsb/init-functions

case "$1" in
  start)
        log_daemon_msg "Starting linux firewall" "iptables"
        cat /etc/iptables/rules.save | iptables-restore -c
        log_end_msg $?
        ;;
  stop)
        log_daemon_msg "Stopping linux firewall" "iptables"
        /sbin/iptables-save > /etc/iptables/rules.save
        for table in filter nat mangle
        do
        $ipt -t $table -F
        $ipt -t $table -X
        $ipt -t $table -Z
        done

        $ipt -P FORWARD ACCEPT
        $ipt -P INPUT ACCEPT
        $ipt -P OUTPUT ACCEPT

        log_end_msg 0
        ;;

  restart)
            log_daemon_msg "Restarting iptables" "iptables"
        ;;

  status)
        log_daemon_msg "Not implemented" "iptables"
        log_end_msg 0
        ;;
  save)
        log_daemon_msg "Saving firewall rules"
        /sbin/iptables-save > /etc/iptables/rules.save
        log_end_msg 0
        ;;
  *)
        echo "Usage: /etc/init.d/iptables {start|stop|restart|save}"
        exit 1
esac

exit 0

Как пользоваться?

Прежде всего, приведенный код нужно поместить в файл /etc/init.d/iptables и сделать его исполняемым:

chown root:root /etc/init.d/iptables
chmod u+x /etc/init.d/iptables

А теперь надо добавить скрипт в автозагрузку (и в выключение):

update-rc.d iptables defaults

Теперь можно напрямую писать правила iptables и формировать нужные цепочки. При необходимости сохранить текущее состояние (со всеми счетчиками), можно просто использовать:

/etc/init.d/iptables save

При запуске системы вызовется /etc/init.d/iptables start что проинициализирует netfilter сохраненными в файле /etc/iptables/rules.save правилами. При выключении вызовется /etc/init.d/iptables stop, что сохранит текущие правила и счетчики в вышеуказанный файл.

Благодарности

Спасибо всем кто прочитал, спасибо моей любимой за счастье в моей жизни.

Comments:

esveka: Большое спасибо за статью! Ставил fail2ban в Ubuntu 10.10 по мануалу, а на iptables зашел в тупик. Точнее, зашел бы, если б не Вы :)
NeferSky: Ну наконец-то нашелся автор, который написал статью про убунту "из коробки"! А то у всех остальных какие-то постоянно файлы и директории упоминаются, которых у меня и нет в помине! Спасибо огромное!
AHTOXA: Спасибо, пригодилось. Только в скрипте неточность. Забыли таблицы указать. Надо for table in filter nat mangle do $ipt -t $table -F $ipt -t $table -X $ipt -t $table -Z done
azure: Спасибо! Поправил
dxnich: Если я изменил правила, то при /etc/init.d/iptables stop они сохранятся. По-моему такое поведение не вполне корректно.
azure: Сохраниться текущее состояние фаервола в файл и уберуться все правила (т.е. фаервол отключится). А какое поведение по-вашему корректно и почему?
dxnich: На мой взгляд логичнее возврат к последнему сохранённому состоянию. В смысле, чтобы restart (stop start) не сохранял текущие правила, которые в процессе работы могли быть изменены. Пример: добавляем несколько временных правил, которые впоследствии надо будет удалить. А команды для сброса нет. Неудобно. Плюс, если мы забудем удалить правила вручную, они превратятся в постоянные. На мой взгляд, правила сохраняться должны исключительно командой save. То есть, только когда рут этого захочет явно.
dxnich: azure, я выслал вам ответ и он даже появился на сайте, а теперь его нет. Не могу понять - это что-то сбойнуло, или ответ не понравился? )
azure: dxnich, я вручную пропускаю коменты (именно поэтому тут нет спам сообщений). Я просто не успел его заапрувить. Какое-то время неапрувленные сообщения показываются, но только авторам сих сообщений. Так что тут все ок. А теперь что касается ваших замечаний. В принципе, мне вполне понятны ваши аргументы, и я даже в какой-то степени с ними согласен (с тем что явное указание того, что правила надо сохранить лучше неявного их сохранения). Но есть тонкие моменты. Например, счетчики пакетов\байт. Для меня удобно, если после ребута счетчики останутся в последнем состоянии, а не в состоянии от последнего вызова /etc/init.d/iptables save Кроме того, когда сисадмин добавляет правило в фаервол, он уже явным образом изменяет настройки фаерволла, а скрипт лишь восстанавливает состояние фаерволла после ребута. Впрочем, для реализации того, что вы просите достаточно всего лишь закомментировать строку для stop): # /sbin/iptables-save > /etc/iptables/rules.save
dxnich: Если не комментировать, но добавить перед ней [cat /etc/iptables/rules.save | iptables-restore], то вообще всем будет хорошо: и счётчики останутся, и сохранённые правила не изменятся. Но вообще согласен, дело удобства, для конкретного администратора и конкретного сервера. Спасибо за ответ!
dxnich: azure, извиняюсь, был неправ. Счётчики при этом обнулятся. Мне стыдно.
Avari: просто ссылка в тему: http://debian-russian.org/debian-faq/networking/kak-sdelat-avtozapusk-fairvolla-kuda-delsya-etc-init-d-iptables "Это Debian!" =)))
Виталик: Я правильно понимаю, что при restart он ничего не делает? и я бы исправил строчку usage на echo "Usage: /etc/init.d/iptables {start|stop|restart|save}"
azure: Виталик, да правильно понимаете. Спасибо за замечание, исправил.
Конрад: Спасибо за скрипт, очень полезно. Интересно, а при рестарте почему нельзя снова прочитать rules.save и внедрить ресторнуть?
Конрад: Как же мне переменную из скрипта притащить в rules.save ? Хочется как минимум EXTIP притащить туда.
Конрад: Наверное нужно что-то типа "while read line do eval "echo ${line}" done < /etc/iptables/rules.save | /sbin/iptables-restore -v" впихнуть в старт...
Конрад: да, работает так. извиняюсь за флуд ))

Nickname:
Creative Commons License This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License