Меню

Скрипт для настройки iptables



Настройка iptables и NAT

Задача: настроить шлюз в интернет для офиса на основе обычного компьютера с установленной Linux с двумя сетевыми картами.

Условимся, что внутренняя сетевая карта называется eth1, внешняя — eth0.

Чуть-чуть ликбеза. Мы настроим (1) forwarding (маршрутизацию) и (2) NAT (netowrk address translation).

(1) Маршрутизация (forwarding) в данном случае означает, что когда пакет из локальной сети в поисках «ya.ru» (или иного сайта или внешнего IP) попадает на наш шлюз, то шлюз должен знать, что такие пакеты надо передать на внешний интерфейс (eth0) — мол, летите, соколы, дальше. Дальше точно так же (ну, пусть не точно также, ну пусть и совсем не так же) от одного узла до другого провайдеры перекидывают наш пакет все дальше от нас и все ближе к цели.

(2) NAT. Как много в этом слове. Пример. Вася открывает сайт ya.ru (IP: 213.180.193.3). Т.к. в локальной сети IP-адреса локальные (не маршрутизируются в интернет, ну никак), то наш шлюз подменяет адрес источника пакета (ноутбук Васи, src=192.168.1.134) на свой собственный IP адрес (src=1.2.3.4), выданный провайдером. Сайт ya.ru будет считать, что IP Васи не 192.168.1.134, а 1.2.3.4. И ответный пакет ya.ru отправит нашему шлюзу. При получении ответа от удаленного сервера наш шлюз вспомнит, какая локальная машина запрашивала 213.180.193.3 и в ответном пакете поменяет dst с 1.2.3.4 на 192.168.1.134.

Такой NAT еще называют SNAT (Source NAT), т.к. изначально меняется адрес источника (src, source). Есть другой NAT — DNAT (destination nat, dst nat). Но морочить себе голову сейчас мы не дадим, не так ли 😉

Если в дальнейшем будет нужна статистика и пр., то настроить Squid будет не так и сложно.

Для простоты обозначений, наш шлюз будем называть сервер. Поехали.

1. Создаем скрипт правил iptables iptables.sh

Например, в директории /root создадим файл iptables.sh, дадим ему права на исполнение:

chmod +x /root/iptables.sh

Теперь поместим в этот файл следующий текст:

# Define vars
IF_EXT=»eth0″
IF_INT=»eth1″
IPT=»/sbin/iptables»

# flush
$IPT —flush
$IPT -t nat —flush
$IPT -t mangle —flush
$IPT -X

# loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

$IPT -N bad_packets
$IPT -P bad_packets ACCEPT

$IPT -A bad_packets -i $IF_EXT -s 10.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 172.16.0.0/12 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 192.168.0.0/12 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 127.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 0.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 169.254.0.0/16 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 192.0.2.0/24 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 204.152.64.0/23 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 224.0.0.0/3 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 240.0.0.0/5 -j DROP

$IPT -A INPUT -j bad_packets
$IPT -A OUTPUT -j bad_packets
$IPT -A FORWARD -j bad_packets

# allow new connections from local net to out
$IPT -A FORWARD -i $IF_INT -o $IF_EXT -m state —state NEW,ESTABLISHED,RELATED -j ACCEPT
# do not allow new connections from internet, but support established connections from local network
$IPT -A FORWARD -i $IF_EXT -o $IF_INT -m state —state ESTABLISHED,RELATED -j ACCEPT

# SNAT — local users to out internet
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE

$IPT -A INPUT -p tcp ! —syn -m state —state NEW -j DROP
$IPT -A INPUT -m state —state ESTABLISHED,RELATED -j ACCEPT

$IPT -A INPUT -i $IF_INT -p tcp —dport 22 -j ACCEPT

# new local connections
$IPT -A OUTPUT -m state —state NEW,ESTABLISHED,RELATED -j ACCEPT

2. Комментарии к скрипту iptables.sh

  1. Все секции снабжены минимальными комментариями, поэтому в них не запутается даже новичок.
  2. Наиболее «туманная» секция — # PROTECT FIREWALL, но во-первых, временно вы можете ее вообще убрать, а во-вторых, если задуматься, там всё просто. Мы защищаем наш сервер от атак, когда из внешней сети пытаются «прикинуться» внутренними адресами. Вот и все.
  3. Чтобы наш сервер в принципе мог выпускать во внешний мир клиентов локальной сети, обязательно надо включить forwarding (почти в самом начале скрипта):

# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

Данный параметр также может быть задан через параметр:

net.ipv4.ip_forward = 1 в файле /etc/sysctl.conf.

Чтобы изменения в файле sysctl.conf вступили в силу, выполните следующую команду:

sysctl -p /etc/sysctl.conf

  • В секции # INPUT chain мы разрешаем клиентам локальной сети подключаться к серверу по ssh. Обратите внимание, несмотря на то, что к самому серверу можно обратиться только по ssh, клиенты локальной сети не будут ограничены в выходе в интернет. Цепочка INPUT не для них!
  • В цепочке # OUTPUT chain мы разрешаем серверу обращаться во внешний мир (скачивать обновления, например). Для упрощения считаем, что мы доверяем нашему серверу и разрешаем ему любые исходящие соединения.
  • Еще раз отмечу — цепочки INPUT и OUTPUT работают только для тех пакетов, которые адресованы локальной машине, в нашем случае это сам сервер.
  • Фактически, пакет из локальной сети в интернет проходит две (упрощенно) цепочки: FORWARD -> POSTROUTING. Более детальное описание этапов прохождения пакетов через iptables смотрите в статье «Порядок прохождения таблиц и цепочек IPTABLES». Поэтому все ограничения клиентов локальной сети (разрешить ли ICQ, WWW, POP3 и т.п.) настраиваются правилами FORWARD (секция #FORWARD chain). Например, для того, чтобы разрешить доступ только к сайтам, пишем:

    $IPT -A FORWARD -i $IF_INT -o $IF_EXT -dport 80 -m state —state NEW,ESTABLISHED,RELATED -j ACCEPT

    Правило по-умолчанию ($IPT -A FORWARD -i $IF_INT -o $IF_EXT -m state —state NEW,ESTABLISHED,RELATED -j ACCEPT) естественно, удаляем либо комментируем символом #.
    Для того, чтобы после перезагрузки правила iptables не стирались, после того, как выполните скрипт iptables.sh и убедитесь, что все работает так, как надо, выполните команду:

    service iptables save

    Эта команда сохранит настройки iptables. Эта команда подойдет для RHEL-основанных дистрибутивов. Для других не знаю. Если нужен универсальный метод — поместите запуск этого скрипта в автозагрузку.

  • Пожалуй, все. Естественно, если вы новичок, НИКОГДА не настраивайте правила iptables находясь не за клавиатурой самого сервера. Ведь если вы случайно запретите себе доступ, то придется ноги-в-руки-и-на-работу 🙂 Если вы уже знаете, что делаете, это к вам не относится.
  • Если есть вопросы, пишите!
  • Источник

    Iptables — скрипты для конфигурирования

    В статье представлено несколько скриптов для конфигурирования iptables и ip6tables: сброс настроек по умолчанию для всех таблиц, цепочек фаервола с удалением пользовательских названий цепочек и базовые конфигурации для iptables протоколов IPv4 и IPv6. Описание процесса настройки iptables, ip6tables и как сохранить конфигурацию фаервола после перезагрузки сервера — читайте тут: Как настроить iptables.

    Очистка всех настроек

    Этот скрипт поможет очистить все настройки iptables, ip6tables и установить политики по умолчанию для всех цепочек firewall. Его можно установить в cron и запускать, например, раз в 20 минут, для того, чтобы в ходе экспериментов с фаерволом не лишиться доступа к удаленному серверу.

    Если запустить скрипт без параметров, то в консоль пользователю будет выводиться информация о конфигурации скрипта (какие firewall будут затронуты и политика по умолчанию). После положительного ответа (нажатия Y) отобразится краткий отчет по проведенным действиям.

    Чтобы скрипт запустился в автоматическом режиме, например из cron, необходимо запускать скрипт с параметром -cron:

    В этом случае, не будет запрашиваться подтверждение на выполнение изменений в iptables, и скрипт выполнится без отображения запускаемых им команд.

    Закомментировав строку iptables_path[1] или iptables_path[2] — можно выбрать, для какого из протоколов, IPv4 или IPv6 будут применяться настройки. Также, присвоив переменной def_val значение DROP, можно полностью закрыть сервер от сети, но ни в коем случае не применяйте параметр DROP для той сети, по которой подключены, если работаете удаленно!

    # Полный путь к iptables
    iptables_path[1]=»/sbin/iptables»
    # Полный путь к ip6tables
    iptables_path[2]=»/sbin/ip6tables»

    # Состояние по умолчанию, устанавливаемое скриптом
    def_val=»ACCEPT»

    # Таблицы iptables
    ipt_table[1]=’filter’
    ipt_table[2]=’nat’
    ipt_table[3]=’mangle’
    ipt_table[4]=’raw’
    ipt_table[5]=’security’

    # Цепочки для каждой таблицы
    chain_filter=( INPUT OUTPUT FORWARD )
    chain_nat=( PREROUTING INPUT OUTPUT POSTROUTING )
    chain_mangle=( PREROUTING INPUT FORWARD OUTPUT POSTROUTING )
    chain_raw=( PREROUTING OUTPUT )
    chain_security=( INPUT OUTPUT FORWARD )

    if [ «$1» != «$cron_flag» ]
    then
    echo «Firewall set default and clear user settings.»
    echo «»
    echo «Setting:»
    echo «Firewall path: $
    echo «Default value for all chains tables: $def_val.»
    echo «»
    read -p «Are you sure to start (y/n): » AMSURE.

    if [ «$AMSURE» != «y» ]
    then
    echo «Exit, no changes.»
    exit
    fi
    fi

    [ «$1» != «$cron_flag» ] && echo «»

    [ «$1» != «$cron_flag» ] && echo «Firewal script $iptables_path:»

    # Запуск настроек iptables
    for c in $(eval echo «\$<$chain[@]>«); do
    $iptables_path -t $table -P $c $def_val
    $iptables_path -t $table -F
    $iptables_path -t $table -X
    chains=»$$c, »
    done

    if [ «$1» != «$cron_flag» ]
    then
    chains=»$
    echo » — Table \»$table\», chains: $chains — all setting cleared.»
    fi
    done

    [ «$1» != «$cron_flag» ] && echo «»
    done

    Конфигурация iptables

    Скрипт iptables_conf_set загружает в iptables базовую конфигурацию, предварительно очистив все правила и пользовательские цепочки для ВСЕХ таблиц iptables, и записывает настройки в файл, указанный в переменной $IPTCONF.

    Правила разрешают доступ из вне на указанном сетевом интерфейсе только к определенным портам и запрещают весь остальной входящий трафик (таблица filter, цепочка INPUT). Также, в качестве примера, приведены настройки для блокирования исходящего трафика в цепочке OUTPUT таблицы filter. Но, поскольку, последним правилом в OUTPUT записано: «-A OUTPUT -j ACCEPT», что разрешает весь исходящий (созданный сервером) трафик, то в не зависимости от правил цепочки, остальные пакеты блокироваться не будут. Если нужно блокировать все, кроме разрешенных, соединения, инициированные сервером, можно установить в последнем правиле цепочки OUTPUT направление DROP, как это сделано в цепочке INPUT.

    Перед запуском скрипта внимательно проверьте все устанавливаемые им правила, чтобы не лишиться доступа к серверу, если конфигурирование происходит удаленно.

    # Полный путь к iptables
    IPT=»/sbin/iptables»

    # Полный путь к iptables-save
    IPTS=»/sbin/iptables-save»

    # Полный путь к файлу, в котором будет сохранена конфигурация iptables
    IPTCONF=»/etc/iptables.conf»

    # Название сетевого интерфейса, к которому будут применены разрешающие правила
    # Название можно найти тут: /etc/network/interfaces
    PUBIF=»eth0″

    # IP-адрес сервера
    SRVIP=`ifconfig $PUBIF | grep ‘inet addr’ | awk <'print $2'>| sed s/.*://`

    # Состояние по умолчанию, устанавливаемое скриптом
    def_val=»ACCEPT»

    # Таблицы iptables
    ipt_table[1]=’filter’
    ipt_table[2]=’nat’
    ipt_table[3]=’mangle’
    ipt_table[4]=’raw’
    ipt_table[5]=’security’

    # Цепочки для каждой таблицы
    chain_filter=( INPUT OUTPUT FORWARD )
    chain_nat=( PREROUTING INPUT OUTPUT POSTROUTING )
    chain_mangle=( PREROUTING INPUT FORWARD OUTPUT POSTROUTING )
    chain_raw=( PREROUTING OUTPUT )
    chain_security=( INPUT OUTPUT FORWARD )

    echo «Starting IPv4 firewall (iptables) configure»

    read -p «Are you sure to start (y/n): » start
    if [ «$start» != «y» ]
    then
    echo «Exit, no changes.»
    exit
    fi

    echo «»
    echo «Step 1: clean old configuration»

    # Сброс настроек iptables
    for c in $(eval echo «\$<$chain[@]>«); do
    $IPT -t $table -P $c $def_val
    $IPT -t $table -F
    $IPT -t $table -X
    chains=»$$c, »
    done

    chains=»$
    echo » — Table \»$table\», chains: $chains — all setting cleared.»
    done

    echo «»
    echo «Step 2: saved main configuration»

    # Полный доступ интерфейса loopback
    $IPT -A INPUT -i lo -j ACCEPT
    $IPT -A OUTPUT -o lo -j ACCEPT

    # Разрешить весь исходящий трафик и инициированный им входящий
    $IPT -A INPUT -i $PUBIF -m conntrack —ctstate RELATED,ESTABLISHED -j ACCEPT
    #$IPT -A OUTPUT -o $PUBIF -m conntrack —ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

    # Разрешить входящий ICMP
    $IPT -A INPUT -i $PUBIF -p icmp -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p icmp -j ACCEPT

    # Разрешить SSH
    $IPT -A INPUT -i $PUBIF -p tcp -m tcp —dport 22 -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p tcp -m tcp —sport 22 -j ACCEPT

    # Разрешить HTTP
    $IPT -A INPUT -i $PUBIF -p tcp -m tcp —dport 80 -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p tcp -m tcp —sport 80 -j ACCEPT

    # Разрешить HTTPS
    $IPT -A INPUT -i $PUBIF -p tcp -m tcp —dport 443 -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p tcp -m tcp —sport 443 -j ACCEPT

    # Открыть порт OpenVPN
    $IPT -A INPUT -i $PUBIF -m tcp -p tcp —dport 1723 -j ACCEPT
    $IPT -A INPUT -i $PUBIF -p gre -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p tcp -m tcp —sport 1723 -j ACCEPT
    $IPT -A OUTPUT -o $PUBIF -p gre -j ACCEPT

    # Nat для VPN-подключения
    $IPT -t nat -A POSTROUTING -j SNAT —to-source $SRVIP

    # Логирование всего, что не попало под правила ACCEPT
    # $IPT -A INPUT -i $PUBIF -j LOG

    # Запретить весь входящий и исходящий трафик на всех сетевых интерфейсах
    # не попавший под правила ACCEPT вверху
    $IPT -A INPUT -j DROP
    $IPT -A OUTPUT -j ACCEPT

    # Записать настройки в конфигурационный файл iptables,.
    # настройки из которого загружаются сразу после перезагрузки
    $IPTS > $IPTCONF

    echo «IPv4 firewall configured, config saved to «$IPTCONF

    Конфигурация ip6tables

    Скрипт ip6tables_conf_set для базовой конфигурации фаервола ip6tables протокола IPv6.

    # Полный путь к ip6tables
    IPT6=»/sbin/ip6tables»

    # Полный путь к ip6tables-save
    IPT6S=»/sbin/ip6tables-save»

    # Полный путь к файлу, в котором будет сохранена конфигурация ip6tables
    IPT6CONF=»/etc/ip6tables.conf»

    # Название сетевого интерфеса, к которому будут применены разрешающие правила
    # Название можно найти тут: /etc/network/interfaces
    PUBIF=»eth0″

    # Состояние по умолчанию, устанавливаемое скриптом
    def_val=»ACCEPT»

    # Таблицы iptables
    ipt_table[1]=’filter’
    ipt_table[2]=’nat’
    ipt_table[3]=’mangle’
    ipt_table[4]=’raw’
    ipt_table[5]=’security’

    # Цепочки для каждой таблицы
    chain_filter=( INPUT OUTPUT FORWARD )
    chain_nat=( PREROUTING INPUT OUTPUT POSTROUTING )
    chain_mangle=( PREROUTING INPUT FORWARD OUTPUT POSTROUTING )
    chain_raw=( PREROUTING OUTPUT )
    chain_security=( INPUT OUTPUT FORWARD )

    echo «Starting IPv6 firewall (ip6tables) configure»

    read -p «Are you sure to start (y/n): » start
    if [ «$start» != «y» ]
    then
    echo «Exit, no changes.»
    exit
    fi

    echo «»
    echo «Step 1: clean old configuration»

    # Сброс настроек ip6tables
    for c in $(eval echo «\$<$chain[@]>«); do
    $IPT6 -t $table -P $c $def_val
    $IPT6 -t $table -F
    $IPT6 -t $table -X
    chains=»$$c, »
    done

    chains=»$
    echo » — Table \»$table\», chains: $chains — all setting cleared.»
    done

    echo «»
    echo «Step 2: saved main configuration»

    # По умолчанию разрешить весь входящий, исходящий и запретить перенаправляемый трафик
    $IPT6 -P INPUT ACCEPT
    $IPT6 -P OUTPUT ACCEPT
    $IPT6 -P FORWARD DROP

    # Полный доступ интерфеса loopback
    $IPT6 -A INPUT -i lo -j ACCEPT
    $IPT6 -A OUTPUT -o lo -j ACCEPT

    # Разрешить весь исходящий трафик и инициированный им входящий
    $IPT6 -A INPUT -i $PUBIF -m state —state ESTABLISHED,RELATED -j ACCEPT
    $IPT6 -A OUTPUT -o $PUBIF -m state —state NEW,ESTABLISHED,RELATED -j ACCEPT

    # Разрешить входящий ICMP
    $IPT6 -A INPUT -i $PUBIF -p ipv6-icmp -j ACCEPT
    $IPT6 -A OUTPUT -o $PUBIF -p ipv6-icmp -j ACCEPT

    # Здесь можно добавить свои правила, например открыть 80 порт по IPv6
    # .

    # Логирование всего, что не попало под правила ACCEPT
    $IPT6 -A INPUT -i $PUBIF -j LOG

    # Запретить весь входящий и исходящий трафик на всех сетевых интерфейсах
    # не попавший под правила ACCEPT вверху
    $IPT6 -A INPUT -j DROP
    $IPT6 -A OUTPUT -j DROP

    # Записать настройки в конфигурационный файл ip6tables,
    # настройки из которого загружаются сразу после перезагрузки
    $IPT6S > $IPT6CONF

    echo «IPv6 firewall configured, config saved to «$IPT6CONF

    Источник

    Читайте также:  Настройка панели уведомлений miui
    Adblock
    detector