Iptables файрвол

Тема в разделе "Справочник по Ддос-атакам", создана пользователем Devider, 17 сен 2013.

  1. Iptables - это штатный файрвол Linux-систем. Если вы используете для веб-сервера операционные системы Debian, CentOS, OpenSUSE, Ubuntu, то вам предстоит работать с Iptables для предотвращения ддос-атак.

    Небольшой мануал по настройке Iptables

    Код:
    ########BEGIN OF FILE############
    #!/sbin/runscript
    # Copyright 1999-2005 Gentoo Foundation
    # Distributed under the terms of the GNU General Public License v2
    # $Header: /var/cvsroot/gentoo-x86/net-firewall/iptables/files/iptables-1.3.2.init,v 1.4 2006/11/11 08:25:00 vapier Exp $
     
    opts="save reload panic"
     
    #######################################################################################################
    # Настройки IPTABLES ----- Iptables Settings
    # здесь определяются переменные используемые в процедурах старта, перезапуска, останова и т.д.
    #######################################################################################################
     
    IPTABLES_NAME="iptables"
    IPTABLES="/sbin/iptables"
    SAVE_RESTORE_OPTIONS="/etc/firewall.rules"
    IPTABLES_SAVE="/sbin/iptables-save"
    IPTABLES_RESTORE="/sbin/iptables-restore"
    IPTABLES_PROC="/proc/net/ip_tables_names"
    FIREWALL="/etc/firewall.rules"
    POLICY="DROP"
     
    #######################################################################################################
    # Настройки интерфейсов ----- Interfaces Settings
    #######################################################################################################
     
    WAN1_IF="eth0" # внешний интерфейс
    WAN1_IP="10.1.0.5" # адрес на внешнем интерфейсе
    WAN1_GW="10.1.0.1" # шлюз провайдера
     
    LAN="192.168.1.0/24" # внутренняя сеть
    LAN1_IF="eth1" # внутренний интерфейс
    LAN1_IP="192.168.1.1" # адрес на внутреннем интерфейсе
     
    LO_IF="lo" # loopback-интерфейс
    LO_IP="127.0.0.1" # loopback-адрес
    LOOPBACK="127.0.0.0/8" # loopback-петля
     
    DNS="196.196.80.235" # DNS-провайдера
     
    echo 1 > /proc/sys/net/ipv4/ip_forward #ядро должно знать что оно может продвигать пакеты
     
    depend() {
    before net
    use logger
    }
     
    # Установка политики по умолчанию (переменная $POLICY установлена в DROP, т.е. пакеты будут дропаться)
    rules() {
    ebegin "Setting default policy to $POLICY"
    $IPTABLES -P INPUT $POLICY
    $IPTABLES -P FORWARD $POLICY
    $IPTABLES -P OUTPUT $POLICY
     
    #########################################################################
    # Общие Правила - COMMON RULES
    # Здесь мы создаем различные цепочки, которые висят в памяти ядра, далее в таблицах при определенных
    # условиях мы будем направлять пакеты в эти цепочки.
    #########################################################################
    ebegin "Сreating user-defined chains"
    # Разрешаем прохождение statefull-пакетов. Эта цепочка обязательная она разрешает прохождение пакетов в
    # уже установленных соединениях(ESTABLISHED), и на установление новых соединений от уже установленных
    # (RELATED)
    einfo "Creating states chain"
    $IPTABLES -N allowed
    $IPTABLES -F allowed
    # "allowed" это просто имя, можно использовать что нибудь и другое:)
    # Разрешаем прохождение statefull трафика. Далее идет собственно сам список правил
    $IPTABLES -A allowed -m state --state ESTABLISHED,RELATED -j ACCEPT
    # Журналируем все обращение к этому серверу от WAN-сетей :) Мы не ждем гостей !
    $IPTABLES -A allowed -i $WAN1_IF -m limit --limit 1/second -j ULOG --ulog-prefix "Bad packet from $WAN1_IF"
    $IPTABLES -A allowed -j $POLICY
     
    # Цепочка общего разрешения использовать аккуратно!
    # Эту цепочку я использую когда необходимо разрешить прохождение пакетов, с определенных портов или адресов
    einfo "Creating common accepting chain"
    $IPTABLES -N com-allow
    $IPTABLES -F com-allow
    $IPTABLES -A com-allow -p tcp -j ACCEPT
    $IPTABLES -A com-allow -p udp -j ACCEPT
     
    #----------------------------------------------------------------------------------------------------------
    # Правила для входящего трафика
    #----------------------------------------------------------------------------------------------------------
    # 1. Создаем цепочку для входящих ICMP.
    # 2. Создаем цепочку для входящего SSH трафика.
     
    # 1. Разрешаем ICMP
    einfo "Creating incoming icmp traffic chain"
    $IPTABLES -N icmp_in
    $IPTABLES -F icmp_in
    # здесь можно увидеть применения модуля "state" т.е. состояние. пропускаются пакеты со статусом NEW,
    # остальные нам не нужны
    $IPTABLES -A icmp_in -m state --state NEW -p icmp --icmp-type echo-request -j ACCEPT
    $IPTABLES -A icmp_in -m state --state NEW -p icmp --icmp-type time-exceeded -j ACCEPT
    $IPTABLES -A icmp_in -m state --state NEW -p icmp --icmp-type destination-unreachable -j ACCEPT
    # Журналируем ICMP-пакеты, нам не нужны эти пакеты.
    $IPTABLES -A icmp_in -p icmp -j ULOG --ulog-prefix "Bad ICMP"
     
    # 2. Входящий SSH трафик
    einfo "Creating incoming ssh traffic chain"
    $IPTABLES -N ssh-in
    $IPTABLES -F ssh-in
    $IPTABLES -A ssh-in -p tcp --dport 22 -j ACCEPT
    # Защита о флуда по SSH
    $IPTABLES -A ssh-in -m limit --limit 1/second -p tcp --tcp-flags ALL RST --dport ssh -j ACCEPT
    $IPTABLES -A ssh-in -m limit --limit 1/second -p tcp --tcp-flags ALL FIN --dport ssh -j ACCEPT
    $IPTABLES -A ssh-in -m limit --limit 1/second -p tcp --tcp-flags ALL SYN --dport ssh -j ACCEPT
    $IPTABLES -A ssh-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT
     
    #----------------------------------------------------------------------------------------------------------
    # Правила для исходящего трафика
    #----------------------------------------------------------------------------------------------------------
    # 1. Разрешаем исходящий ICMP трафик (функции диагностики)
     
    # 1. Необходимо чтобы мы пинговали всех.
    einfo "Creating outgoing icmp traffic chain"
    $IPTABLES -N icmp_out
    $IPTABLES -F icmp_out
    # Разрешаем icmp-reply во все сети в ответ на icmp-request'ы с сетей
    $IPTABLES -A icmp_out -p icmp --icmp-type 8 -j ACCEPT
    $IPTABLES -A icmp_out -m state --state NEW -p icmp --icmp-type time-exceeded -j ACCEPT
    $IPTABLES -A icmp_out -m state --state NEW -p icmp --icmp-type destination-unreachable -j ACCEPT
     
    # Проверка флагов. Обнаружение сканеров потров. Взято из руководства по Iptables 1.1.19
    einfo "Creating portscan detection chain"
    $IPTABLES -N check_tcp
    $IPTABLES -F check_tcp
    # Отбрасываем невалидные пакты
    $IPTABLES -A allowed -m state --state INVALID -m limit --limit 3/minute -j ULOG --ulog-prefix "INVALID"
    $IPTABLES -A allowed -m state --state INVALID -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
    $IPTABLES -A check_tcp -p tcp ! --syn -m state --state NEW -j ULOG --ulog-prefix "NEW not --syn"
    $IPTABLES -A check_tcp -p tcp ! --syn -m state --state NEW -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j ULOG --ulog-prefix "NMAP-XMAS"
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL ALL -m limit --limit 5/minute -j ULOG --ulog-prefix "XMAS"
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL ALL -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m limit --limit 5/minute -j ULOG --ulog-prefix "XMAS-PSH"
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL NONE -m limit --limit 5/minute -j ULOG --ulog-prefix "NULL_SCAN"
    $IPTABLES -A check_tcp -p tcp --tcp-flags ALL NONE -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 5/minute -j ULOG --ulog-prefix "SYN/RST"
    $IPTABLES -A check_tcp -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
    $IPTABLES -A check_tcp -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/minute -j ULOG --ulog-prefix "SYN/FIN"
    $IPTABLES -A check_tcp -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
     
    #----------------------------------------------------------------------------------------------------------
    # Цепочка t mangle PREROUTING (необходима для изменения битов TOS, QOS)
    #----------------------------------------------------------------------------------------------------------
     
    # Пример использования таблицы mangle, маркируем esp-трафик для дальнейших манипуляций в ядре
    # Можно неиспользовать в простых роутерах такая функция применяется редко
    $IPTABLES -t mangle -A PREROUTING -p esp -j MARK --set-mark 1
     
    #----------------------------------------------------------------------------------------------------------
    # Цепочка t nat PREROUTING (необходима для изменения поля dst в заголовке пакета, можно использовать
    # для проброса порта на сервер во внутренней сети )
    #----------------------------------------------------------------------------------------------------------
     
    # перебрасываем все запросы на 80 порт, приходящие на внешний интерфейс на внутренний веб-сервер
    $IPTABLES -t nat PREROUTING -i $WAN1_IF -p tcp --dport 80 -j DNAT --to-destination 192.168.1.20
     
    #----------------------------------------------------------------------------------------------------------
    # Цепочка INPUT
    # Здесь создаем правила для входящего трафика, конкретно для SSH, DNS, ICMP и служебных обращений на петле
    # также включена проверка на плохие пакеты и в конце правила для остального трафика (см. цепочку allowed).
    #----------------------------------------------------------------------------------------------------------
    einfo "Applying chains to INPUT"
     
    # Проверяем пакеты.
    $IPTABLES -A INPUT -p tcp -j check_tcp
    # Разрешаем входящие по SSH
    $IPTABLES -A INPUT -p tcp --dport 22 -j ssh-in
    # Разрешаем входящие соединения к прокси-серверу SQUID
    $IPTABLES -A INPUT -s $LAN -p tcp --dport 3128 -j com-allow
    # Разрешаем входящие по DNS
    $IPTABLES -A INPUT -s $LAN -p udp --dport domain -j com-allow
    # Разрешаем входящие по icmp
    $IPTABLES -A INPUT -p icmp -j icmp_in
    # Разрешаем входящие на петлю, при его включении заметно улучшение отклика при ssh-авторизации
    $IPTABLES -A INPUT -i $LO_IF -d $LOOPBACK -j ACCEPT
    # Ну, и разрешаем statefull-пекеты.
    $IPTABLES -A INPUT -j allowed
     
    #----------------------------------------------------------------------------------------------------------
    # Цепочка FORWARD
    # Здесь создаются правила для транзитного трафика, для случая если необходимо пользоваться какими либо
    # внешними сервисами (почта, веб, аська). В конце правило для остального трафика (цепочка allowed).
    #----------------------------------------------------------------------------------------------------------
    einfo "Applying chains to FORWARD"
     
    # Отбрасываем плохие пакеты
    $IPTABLES -A FORWARD -j check_tcp
    # Разрешаем SSH
    $IPTABLES -A FORWARD -s $LAN -p tcp --dport 22 -j com-allow
    # Разрешаем прохождение icmp-пакетов
    $IPTABLES -A FORWARD -p icmp -j icmp_in
    # Разрешаем прохождение асечных пакетов
    $IPTABLES -A FORWARD -i $LAN1_IF -s $LAN -p tcp --dport 5190 -j com-allow
    # Разрешаем веб-трафик, если у нас не стоит прокси сервер, можно раскоментить эту строку
    # Здесь же показано применения модуля "multiport"
    # $IPTABLES -A FORWARD -i $LAN1_IF -s $LAN -p tcp -m multiport --dport 80,443,1080,3128,8080 -j com-allow
    # Разрешаем прохождение почтовых пакетиков от POP и SMTP
    $IPTABLES -A FORWARD -i $LAN1_IF -s $LAN -p tcp -m multiport --dport 25,110 -j com-allow
     
    # Несовсем понятно практическая функция этого правила:)
    # $IPTABLES -A FORWARD -o $LO_IF -d $LOOPBACK -j ACCEPT
     
    # Разрешаем входящие пакеты, являющиеся частью установленного соединения
    $IPTABLES -A FORWARD -j allowed
     
    #----------------------------------------------------------------------------------------------------------
    # Цепочка OUTPUT
    # Здесь создаются правила для исходящего трафика, конкретно для SSH, ICMP, DNS, WWW а также разрешены
    # исходящие соединения с внутреннего интерфейса. В конце правила для остального трафика (цепочка allowed).
    #----------------------------------------------------------------------------------------------------------
    einfo "Applying chains to OUTPUT"
     
    $IPTABLES -A OUTPUT -j check_tcp
    $IPTABLES -A OUTPUT -o $LAN1_IF -j ACCEPT
    $IPTABLES -A OUTPUT -p icmp -j icmp_out
    $IPTABLES -A OUTPUT -o $LO_IF -j ACCEPT
    $IPTABLES -A OUTPUT -p tcp --dport 22 -j com-allow
    $IPTABLES -A OUTPUT -p udp --dport domain -j com-allow
    $IPTABLES -A OUTPUT -p tcp -m multiport --dport http,https -j com-allow
    $IPTABLES -A OUTPUT -j allowed
     
    #------------------------------------------------------------------------------------------------------------------------
    # Цепочка t NAT POSTROUTING
    # Изменяем поле адрес источника, а пакете,
    #------------------------------------------------------------------------------------------------------------------------
    ebegin "Applying NAT chains"
     
    $IPTABLES -t nat -A POSTROUTING -s $LAN -o $WAN1_IF -p tcp --dport 22 -j SNAT --to-source $WAN_IP
    #$IPTABLES -t nat -A POSTROUTING -s $LAN -o $WAN1_IF -p tcp -m multiport --dport 80,443,1080,3128,8080 -j SNAT --to-source $WAN_IP
    $IPTABLES -t nat -A POSTROUTING -s $LAN -o $WAN1_IF -p tcp -m multiport --dport 25,110 -j SNAT --to-source $WAN_IP
    $IPTABLES -t nat -A POSTROUTING -s $LAN -o $WAN1_IF -p tcp --dport 5190 -j SNAT --to-source $WAN_IP
    $IPTABLES -t nat -A POSTROUTING -s $LAN -o $WAN1_IF -p icmp -j SNAT --to-source $WAN_IP
     
    }
    # Все правила для пакетов заканчиваются, если пакет не подошел ни к одному условию, его ждет судьба по
    # умолчанию, а нашем случае DROP.
    #########################################################################################################################
    #########################################################################################################################
    # здесь начинаются процедуры останова старта перезапуска и т.д.
    # при установке они уже находятся в скрипте, только в начале необходимо указать переменные
    # этот раздел скрипта можно пропустить
     
    set_table_policy() {
    local chains table=$1 policy=$2
    case ${table} in
    nat) chains="PREROUTING POSTROUTING OUTPUT";;
    mangle) chains="PREROUTING INPUT FORWARD OUTPUT POSTROUTING";;
    filter) chains="INPUT FORWARD OUTPUT";;
    *) chains="";;
    esac
    local chain
    for chain in ${chains} ; do
    ${IPTABLES} -t ${table} -P ${chain} ${policy}
    done
    }
     
    checkkernel() {
    if [[ ! -e ${IPTABLES_PROC} ]] ; then
    eerror "Your kernel lacks ${IPTABLES_NAME} support, please load"
    eerror "appropriate modules and try again."
    return 1
    fi
    return 0
    }
    checkconfig() {
    if [[ ! -f ${IPTABLES_SAVE} ]] ; then
    eerror "Not starting ${IPTABLES_NAME}. First create some rules then run:"
    eerror "/etc/init.d/${IPTABLES_NAME} save"
    return 1
    fi
    return 0
    }
     
    start() {
    ebegin "Starting firewall"
    if [ -e "${FIREWALL}" ]; then
    restore
    else
    einfo "${FIREWALL} does not exists. Using default rules."
    rules
    fi
    eend $?
    }
     
    stop() {
    if [[ ${SAVE_ON_STOP} == "yes" ]] ; then
    save || return 1
    fi
    checkkernel || return 1
    ebegin "Stopping firewall"
    for a in $(<${IPTABLES_PROC}) ; do
    set_table_policy $a ACCEPT
    ${IPTABLES} -F -t $a
    ${IPTABLES} -X -t $a
    done
    eend $?
    }
     
    reload() {
    checkkernel || return 1
    ebegin "Flushing firewall"
    for a in $(<${IPTABLES_PROC}) ; do
    ${IPTABLES} -F -t $a
    ${IPTABLES} -X -t $a
    done
    eend $?
     
    start
    }
     
    save() {
    ebegin "Saving ${IPTABLES_NAME} state"
    touch "${IPTABLES_SAVE}"
    chmod 0600 "${IPTABLES_SAVE}"
    ${IPTABLES}-restore ${SAVE_RESTORE_OPTIONS} > "${IPTABLES_SAVE}"
    eend $?
    }
     
    panic() {
    checkkernel || return 1
    [[ -e ${svcdir}/started/${IPTABLES_NAME} ]] && svc_stop
     
    ebegin "Dropping all packets"
    for a in $(<${IPTABLES_PROC}) ; do
    ${IPTABLES} -F -t $a
    ${IPTABLES} -X -t $a
     
    set_table_policy $a DROP
    done
    eend $?
    }
    ########END OF FILE############### 
    Также думаю полезно будет ознакомиться со статьей Яремчука: http://www.xakep.ru/post/58089/
     
    17 сен 2013

Поделиться этой страницей