Проектирование
Скрипт и сервис будет называться iptables. Я хочу от него следующих вещей:
- Автозапуск. Ну, это подразумевается.
- Возможность сохранения текущих правил iptables, чтобы в дальнейшем они подгружались по умолчанию. Значит, нужна опция save.
- Возможность приостановки iptables. То есть, чтобы я мог остановить (сбросить) iptables, сохранив текущие правила, но не меняя правил по умолчанию. То есть, pause.
- Сохранять счётчики пакетов — не надо. Для служебных целей будет достаточно того что есть, а для более подробной информации можно установить ulogd.
Считаю, это — необходимый минимум.
Для хранения служебных файлов сервиса будем использовать каталог /etc/iptables/
. В нём будут находиться следующие файлы:
iptables.save
- правила по умолчанию. В штатном режиме работы правила будут загружаться отсюда.
iptables.pause
- правила, выгруженные при постановке iptables на паузу. В штатном режиме работы этот файл не существует. Если файл существует, то при старте службы загрузка идёт отсюда, после чего файл удаляется.
Теперь разберёмся с опциями командной строки нашего скрипта и опишем, что они будут делать.
start | В штатном режиме: загрузка правил из файла iptables.save При снятии с паузы: загрузка из файла iptables.pause Критерием выбора «чистый старт»/«снятие с паузы» является само существование файла iptables.pause . |
stop | Сброс всех правил. |
restart | Восстановление правил из файла /etc/iptables/iptables.save |
pause | Сохранение текущего состояния iptables во временный файл /etc/iptables/iptables.pause и сброс всех правил. Для снятия с паузы будем использовать команду start |
save | Сохранение текущего состояния iptables в файл /etc/iptables/iptables.save |
Реализация
Пишем скрипт, называем его iptables
, делаем исполняемым и размещаем в /etc/init.d/
/etc/init.d/iptables
#! /bin/sh ### BEGIN INIT INFO # Provides: iptables # Required-Start: $syslog $network # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: iptables # Description: this script is for configuring linux firewall (netfilter) # with help of command-line utility called iptables ### END INIT INFO # Делаем опись используемых бинарников ipt=/sbin/iptables ipt_save=/sbin/iptables-save ipt_restore=/sbin/iptables-restore # Задаём путь к служебному каталогу и имена служебных файлов fcat=/etc/iptables fsave=/etc/iptables/iptables.save fpause=/etc/iptables/iptables.pause [ -x ${ipt} ] || exit 0 [ -d ${fcat} ] || mkdir ${fcat} [ -f ${fsave} ] || ${ipt_save} > ${fsave} # Подключаем дополнительные функции. # Они будут нужны для записи в системный журнал. . /lib/lsb/init-functions # ____ Задаём свои функции ____ # ...сохранение правил в произвольный файл. do_save() { log_daemon_msg "Saving firewall rules to file \"$1\"" "iptables" ${ipt_save} > $1 log_end_msg 0 } # ...загрузка правил из произвольного файла do_load() { log_daemon_msg "Loading firewall rules from file \"$1\"" "iptables" cat $1 | ${ipt_restore} log_end_msg 0 } # ...сброс всех правил и счётчиков do_clear() { log_daemon_msg "Stopping linux firewall" "iptables" 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 } case "$1" in start) log_daemon_msg "Starting linux firewall" "iptables" if [ -f ${fpause} ]; then do_load ${fpause} rm ${fpause} else do_load ${fsave} fi log_end_msg $? ;; stop) [ -f ${fpause} ] && rm ${fpause} do_clear ;; restart) log_daemon_msg "Restarting iptables" "iptables" [ -f ${fpause} ] && rm ${fpause} do_load ${fsave} ;; pause) do_save ${fpause} do_clear ;; save) do_save ${fsave} ;; *) echo "Usage: /etc/init.d/iptables {start|stop|restart|pause|save}" exit 1 esac exit 0
Прописываем сервис в каталогах уровней запуска.
update-rc.d iptables defaults
Это делается однократно; при любом изменении скрипта (кроме блока INIT INFO
) перерегистрировать сервис не нужно.
Комментарии
DenKoren
#cid87526
Ответить
Спасибо, очень много времени благодаря Вам сэкономил.
#cid87535
Ответить
#cid87526, DenKoren
Пожалуйста :)
Но себе времени я сэкономил ещё больше!!!
imen
#cid87711
Ответить
Описываемое сильно смахивает на изобретение велосипеда.
Нечто в убунте пакет net-firewall/iptables (или как там его зовут) не включает стартового скрипта?!?
#cid87876
Ответить
#cid87711, imen
Убунта использует какой-то другой файрвол, не скажу какой.
Для iptables стартовых скриптов нет ни для убунты, ни для дебиана. Видел скрипт для калькулейта (генту), но он там совсем другой.
imen
#cid88407
Ответить
#cid87876,
Внимательнее с терминологией.
В фрюниксах (за коммерческие Unix'ы не скажу, данную подсистему не настраивал) пакетный фильтр реализован на уровне ядра.
Что практически гарантирует сугубую ограниченность доступных реализаций (обычно одна, редко — две, про бОльшее количество вариантов не слышал).
В Linux 2.6+ таковой реализацией является iptables.
То, что ты называешь "файрволлом" является интерфейсом оного.
Где по причине лени я дальше стандартного net-firewall/iptables не смотрел.
С учётом репутации Демьяна выглядит зело странно (но, по моему опыту проработки нюансов реализации не то, чтобы чем-то невероятным).
Ты уверен, что оно не является следствием импринтига убунты?
А с учётом _заявляющейся_ (за реальную работоспособность не скажу) возможности использования в Демьяне openrc (и как следствие — совместимости с кулькуляторским стартовым скриптом) оно как минимум в общем случае неверно.
DenKoren
#cid88498
Ответить
Ubuntu в качестве решения для управления правилами firewall'а предлагает утилиту ufw - 'uncomplicated firewall' (http://ru.wikipedia.org/wiki/Uncomplicated_Firewall). Ей вполне можно пользоваться, но она создаёт свою сложную структуру правил и для простого "иногда закрыть один порт на сервере", как мне показалось, не очень подходит.
imen
#cid90873
Ответить
И как обычно:
Во-первых, в заметке не сказано, что история про upstart. Который далеко не является единственной системой инициализации.
И во-вторых, с учётом победного шествия на x86 порождения поттеринга (systemd) к настоящему времени оно… не очень актуально.