Файрвол

Материал из Bryansk Linux Users Group.

Перейти к: навигация, поиск

Содержание

Зачем нужен файрвол

Межсетевой экран или брандмауэр (жарг. файрвол или файервол) — комплекс аппаратных и/или программных средств, осуществляющий контроль и фильтрацию проходящих через него сетевых пакетов на различных уровнях модели OSI в соответствии с заданными правилами. Основной задачей сетевого экрана является защита компьютерных сетей или отдельных узлов от несанкционированного доступа. Также, сетевые экраны часто называют фильтрами, т.к. их основная задача — не пропускать (фильтровать) пакеты не подходящие под критерии, определенные в конфигурации.

Некоторые сетевые экраны (в их число входит и линуксовый iptables), также позволяют делать трансляцию адресов — динамическую замену адресов назначения (редиректы) или источника (мапинг (biNAT), NAT).

Политики по умолчанию

Существует два типа политики разрешения/запрещения:

  • разрешать все, что не запрещено,
  • запрещать все что не разрешено.

Второй тип более предпочтителен.

Способы управления правилами файрвола

Существует довольно большое количество программ и скриптов для генерации iptables-правил. Но наибольшую гибкость предоставляют самодельные init-скрипты, но они и нуждаются в повышенном внимании и понимании производимых действий.

Типовой файрвол

Рассмотрим банальный фарвол. В его функции входит фильтрация доступа извне к портам хоста, защита от пинг-флуда. Управлять файрволом будем через самодельный init-скрипт, который установит нужные правила при загрузке системы

В нашем случае разрешенными портами для доступа извне (например из сети Интернет) являются 22 tcp порт (SSH), 80 tcp порт (HTTP-сервер). Также добавим правило для разрешения доступа к PostgreSQL-серверу из локальной сети (192.168.0.0/24)

Создадим файл firewall.sh в директории /etc/init.d со следующим содержимым:

#!/bin/sh

startFirewall() {

echo -n "Starting iptables (created by KMyFirewall)...       "
if [ "$verbose" = "1" ]; then
echo -n "
Loading needed modules...          "
fi

$MOD ip_tables
$MOD ip_conntrack
$MOD ipt_LOG
$MOD ipt_limit
$MOD ipt_state
$MOD ip_conntrack_ftp
$MOD ip_conntrack_irc

$MOD iptable_filter
$MOD iptable_mangle
if [ "$verbose" = "1" ]; then
echo "Done."
fi

#  Rules:
if [ "$verbose" = "1" ]; then
echo "Settup Rules in Table FILTER:"
fi

#  Define Rules for Chain: INPUT
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: INPUT"
fi

$IPT -t filter -A INPUT --source 127.0.0.1 -j ACCEPT || \
{ status="1"; echo " Setting up Rule: dns_startstop FAILED! "; exit 1; }
#Разрешаем все пакеты с локалхоста (а то может чего-нибудь отказаться работать)

$IPT -t filter -A INPUT -p icmp --icmp-type echo-request --match limit --limit 5/second --limit-burst 5 -j ACCEPT || \
{ status="1"; echo " Setting up Rule: icmp FAILED! "; exit 1; }
# защищаемся от ping-флуда

$IPT -t filter -A INPUT -p tcp --destination-port 22 -j ACCEPT  || { status="1"; echo " Setting up Rule: ssh FAILED! "; exit 1; }
# Разрешаем доступ к SSH, не забываем установить fail2ban! (либо использовать -m recent)

$IPT -t filter -A INPUT -p tcp --destination-port 80 -j ACCEPT || { status="1"; echo " Setting up Rule: nginx FAILED! "; exit 1; }
# Простое правило для доступа к HTTP-серверу
$IPT -t filter -A INPUT -p tcp --destination-port 5432 --source 192.168.0.0/255.255.255.0 -j ACCEPT || \
{ status="1"; echo " Setting up Rule: postgres_vpn FAILED! "; exit 1; }
# Разрешаем доступ к PostgreSQL для локальной сети

$IPT -t filter -A INPUT --match state --state RELATED,ESTABLISHED -j ACCEPT ||  \
{ status="1"; echo " Setting up Rule: related FAILED! "; exit 1; }
# Не фильтруем уже установленные соединения (чтобы не отваливались)

$IPT -t filter -A INPUT --match state --state INVALID -j DROP || { status="1"; echo " Setting up Rule: invalid_drop FAILED! "; exit 1; }
# Поломанные пакеты маздай

#$IPT -t filter -A INPUT -m limit --limit 1/second --limit-burst 5 -j LOG --log-prefix "INPUT_DROP: "|| \
{ status="1"; echo " Setting up Rule: Chain: INPUT Drop Logging FAILED! "; exit 1; }
# Так можно писать в логи все пакеты, которые не были пропущены файрволом

$IPT -t filter -P INPUT DROP || { status="1"; echo " Setting up Rule: Chain: INPUT Default Target FAILED! "; exit 1; }
# Политика по умолчанию - непрошедшие пакеты выкидываем

#  Define Rules for Chain: OUTPUT
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: OUTPUT"
fi

$IPT -t filter -P OUTPUT ACCEPT || { status="1"; echo " Setting up Rule: Chain: OUTPUT Default Target FAILED! "; exit 1; }
# Политика по умолчанию - пропускаем все исходящие пакеты

#  Define Rules for Chain: FORWARD
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: FORWARD"
fi

$IPT -t filter -P FORWARD ACCEPT || { status="1"; echo " Setting up Rule: Chain: FORWARD Default Target FAILED! "; exit 1; }
# Политика по умолчанию - пропускаем все форвард-пакеты

if [ "$verbose" = "1" ]; then
echo "Settup Rules in Table NAT:"
fi

#  Define Rules for Chain: OUTPUT
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: OUTPUT"
fi

$IPT -t nat -P OUTPUT ACCEPT || { status="1"; echo " Setting up Rule: Chain: OUTPUT Default Target FAILED! "; exit 1; }

#  Define Rules for Chain: PREROUTING
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: PREROUTING"
fi

$IPT -t nat -P PREROUTING ACCEPT || { status="1"; echo " Setting up Rule: Chain: PREROUTING Default Target FAILED! "; exit 1; }


#  Define Rules for Chain: POSTROUTING
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: POSTROUTING"
fi

$IPT -t nat -P POSTROUTING ACCEPT || { status="1"; echo " Setting up Rule: Chain: POSTROUTING Default Target FAILED! "; exit 1; }

if [ "$verbose" = "1" ]; then
echo "Settup Rules in Table MANGLE:"
fi

#  Define Rules for Chain: INPUT
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: INPUT"
fi

$IPT -t mangle -P INPUT ACCEPT || { status="1"; echo " Setting up Rule: Chain: INPUT Default Target FAILED! "; exit 1; }

#  Define Rules for Chain: OUTPUT
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: OUTPUT"
fi

$IPT -t mangle -P OUTPUT ACCEPT || { status="1"; echo " Setting up Rule: Chain: OUTPUT Default Target FAILED! "; exit 1; }

#  Define Rules for Chain: FORWARD
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: FORWARD"
fi

$IPT -t mangle -P FORWARD ACCEPT || { status="1"; echo " Setting up Rule: Chain: FORWARD Default Target FAILED! "; exit 1; }

#  Define Rules for Chain: PREROUTING
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: PREROUTING"
fi

$IPT -t mangle -P PREROUTING ACCEPT || { status="1"; echo " Setting up Rule: Chain: PREROUTING Default Target FAILED! "; exit 1; }

#  Define Rules for Chain: POSTROUTING
if [ "$verbose" = "1" ]; then
echo "Create Rules for Chain: POSTROUTING"
fi

$IPT -t mangle -P POSTROUTING ACCEPT || { status="1"; echo " Setting up Rule: Chain: POSTROUTING Default Target FAILED! "; exit 1; }

if [ "$verbose" = "1" ]; then
echo -n "Enable IP Forwarding.                "
fi

echo 1 > /proc/sys/net/ipv4/ip_forward
if [ "$verbose" = "1" ]; then
echo "Done."
fi

if [ "$verbose" = "1" ]; then
echo -n "Disable Reverse Path Filtering       "
fi

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
echo 0 > $i
done
if [ "$verbose" = "1" ]; then
echo "Done."
fi

if [ "$verbose" = "1" ]; then
echo -n "Disable log_martians (logging).           "
fi

for i in /proc/sys/net/ipv4/conf/*/log_martians ; do
echo 0 > $i
done
if [ "$verbose" = "1" ]; then
echo "Done."
fi

if [ "$verbose" = "1" ]; then
echo -n "Enable Syn Cookies.          "
fi

echo 1 > /proc/sys/net/ipv4/tcp_syncookies
if [ "$verbose" = "1" ]; then
echo "Done."
fi

echo Done.
}

stopFirewall() {
echo -n "Clearing iptables (created by KMyFirewall)...       "

$IPT -t filter -F || status="1"
$IPT -t filter -X || status="1"
$IPT -t filter -P INPUT ACCEPT || status="1"
$IPT -t filter -P OUTPUT ACCEPT || status="1"
$IPT -t filter -P FORWARD ACCEPT || status="1"
$IPT -t nat -F || status="1"
$IPT -t nat -X || status="1"
$IPT -t nat -P OUTPUT ACCEPT || status="1"
$IPT -t nat -P PREROUTING ACCEPT || status="1"
$IPT -t nat -P POSTROUTING ACCEPT || status="1"
$IPT -t mangle -F || status="1"
$IPT -t mangle -X || status="1"
$IPT -t mangle -P INPUT ACCEPT || status="1"
$IPT -t mangle -P OUTPUT ACCEPT || status="1"
$IPT -t mangle -P OUTPUT ACCEPT || status="1"
$IPT -t mangle -P PREROUTING ACCEPT || status="1"
$IPT -t mangle -P POSTROUTING ACCEPT || status="1"

 echo "Done."

}

IPT="/sbin/iptables"
MOD="/sbin/modprobe"
status="0"
verbose="0"
action="$1"
if [ "$1" = "-v" ]; then
   verbose="1"
fi

if [ "$1" = "--verbose" ]; then
   verbose="1"
fi

if [ "$verbose" = "1" ]; then
   if [ "$2" = "" ]; then
   echo "Usage: sh firewall.sh [-v|--verbose] { start | stop | restart }"
   exit 1
 fi
action="$2"
fi

case $action in
 start)
 stopFirewall
 startFirewall
 ;;
 stop)
 stopFirewall
 ;;
 restart)
 stopFirewall
 startFirewall
 ;;
 *)
 echo "Invalid action!
Usage: sh firewall.sh [-v|--verbose] { start | stop | restart }"
 ;;
 esac

if [ "$status" = "1" ]; then
 exit 1
else
 exit 0
fi

Делаем файл исполняемым:

# chmod +x firewall.sh

После этого выполняем комманду:

# update-rc.d firewall.sh defaults

Которая пропишет скрипт в стартовых скриптах

Запускаем файрвол:

# invoke-rc.d firewall.sh -v start

Смотрим вывод отладочной информации, если все в порядке - пользуемся :)

Посмотреть состояние правил файрвола можно коммандой

# iptables -L

Ссылки

Iptables Tutorial на русском языке

Iptables Tutorial на русском языке

Более новая версия Iptables Tutorial на английском языке

Настраивая у себя iptables наткнулся на это, простое и понятное, руководство

13:46, 11 июля 2007 (MSD)

Личные инструменты