Проектирование

Скрипт и сервис будет называться 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
2014.02.27 21:45:43
#cid87526

Ответить

Спасибо, очень много времени благодаря Вам сэкономил.

2014.02.28 00:22:33
#cid87535

Ответить

#cid87526, DenKoren

Спасибо, очень много времени благодаря Вам сэкономил.

Пожалуйста :)

Но себе времени я сэкономил ещё больше!!!

imen
2014.03.02 22:04:28
#cid87711

Ответить

Описываемое сильно смахивает на изобретение велосипеда.
Нечто в убунте пакет net-firewall/iptables (или как там его зовут) не включает стартового скрипта?!?

2014.03.05 14:18:54
#cid87876

Ответить

#cid87711, imen

Описываемое сильно смахивает на изобретение велосипеда.
Нечто в убунте пакет net-firewall/iptables (или как там его зовут) не включает стартового скрипта?!?

Убунта использует какой-то другой файрвол, не скажу какой.
Для iptables стартовых скриптов нет ни для убунты, ни для дебиана. Видел скрипт для калькулейта (генту), но он там совсем другой.

imen
2014.03.11 16:52:13
#cid88407

Ответить

#cid87876,

Убунта использует какой-то другой файрвол, не скажу какой.

Внимательнее с терминологией.
В фрюниксах (за коммерческие Unix'ы не скажу, данную подсистему не настраивал) пакетный фильтр реализован на уровне ядра.
Что практически гарантирует сугубую ограниченность доступных реализаций (обычно одна, редко — две, про бОльшее количество вариантов не слышал).
В Linux 2.6+ таковой реализацией является iptables.

То, что ты называешь "файрволлом" является интерфейсом оного.
Где по причине лени я дальше стандартного net-firewall/iptables не смотрел.

Для iptables стартовых скриптов нет ни для убунты, ни для дебиана. Видел скрипт для калькулейта (генту), но он там совсем другой.

С учётом репутации Демьяна выглядит зело странно (но, по моему опыту проработки нюансов реализации не то, чтобы чем-то невероятным).
Ты уверен, что оно не является следствием импринтига убунты?
А с учётом _заявляющейся_ (за реальную работоспособность не скажу) возможности использования в Демьяне openrc (и как следствие — совместимости с кулькуляторским стартовым скриптом) оно как минимум в общем случае неверно.

DenKoren
2014.03.12 17:26:44
#cid88498

Ответить

Ubuntu в качестве решения для управления правилами firewall'а предлагает утилиту ufw - 'uncomplicated firewall' (http://ru.wikipedia.org/wiki/Uncomplicated_Firewall). Ей вполне можно пользоваться, но она создаёт свою сложную структуру правил и для простого "иногда закрыть один порт на сервере", как мне показалось, не очень подходит.

imen
2015.08.12 20:26:58
#cid90873

Ответить

И как обычно:
Во-первых, в заметке не сказано, что история про upstart. Который далеко не является единственной системой инициализации.
И во-вторых, с учётом победного шествия на x86 порождения поттеринга (systemd) к настоящему времени оно… не очень актуально.