воскресенье, 2 июня 2013 г.

Iptables или мои настройки NAT+Firewall

Все команды выполнялись от прав пользователя root.
1. Создаю скрипт в файле -
'nano /etc/init.d/rc.firewall' следующего содержания:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.firewall+
# Required-Start:  
# Required-Stop:
# Default-Start:     2
# Default-Stop:         0 6   
# Short-Description: Run /etc/init.d/rc.firewall if it exist
### END INIT INFO
######################################################################################
# Configured by Dethroner, 2009
######################################################################################
# Внешний интерфейс
 EXTIF=eth0
# Внутренний интерфейс
 INTIF=eth1
# Loop-устройство/localhost
 LPDIF=lo
 LPDIP=127.0.0.1
 LPDMSK=255.0.0.0
 LPDNET="$LPDIP/$LPDMSK"
# Переменные текстовых инструментов
 IPT='/sbin/iptables'
 IFC='/sbin/ifconfig'
 G='/bin/grep'
 SED='/bin/sed'
 UNPRIPORTS="1024:65535"
# Перечень ip адресов закрытых для FORWARD
 FILENAME_DENY="/etc/deny_inet_hosts"

start_fw()
{
    echo ""  
    echo "IpTables configured by Dethroner"
    # Deny вместо accept: предотвращает открытие "дыр"
    # в то время, как мы закрываем порты и все такое
     $IPT     -P INPUT       DROP
     $IPT     -P OUTPUT      DROP
     $IPT   -P FORWARD     DROP
    # Сброс всех существующих цепочек и стирание персональных цепочек
     CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
     for i in $CHAINS
     do
      $IPT -t $i -F
      $IPT -t $i -X
     done
     echo 1 > /proc/sys/net/ipv4/tcp_syncookies
     echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
    # Проверка адреса источника
     for f in /proc/sys/net/ipv4/conf/*/rp_filter;
     do
      echo 1 > $f
     done
    # Запрет маршрутизации IP от источника и редиректов ICMP
     for f in /proc/sys/net/ipv4/conf/*/accept_source_route;
     do
      echo 0 > $f
     done
     for f in /proc/sys/net/ipv4/conf/*/accept_redirects;
     do
      echo 0 > $f
     done
    # Включить перенаправление пакетов через ядро.
    echo 1 > /proc/sys/net/ipv4/ip_forward

    # Установка переменных среды для внешнего интерфейса
     EXTIP="192.168.1.2"
     EXTBC="192.168.1.255"
     EXTMSK="255.255.255.0"
     EXTNET="$EXTIP/$EXTMSK"
      echo ""
     echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"
  
    # Установка переменных среды для внутреннего интерфейса
     INTIP="192.168.0.1"
     INTBC="192.168.0.255"
     INTMSK="255.255.255.0"
     INTNET="192.168.0.0/24"
     echo ""
     echo "INTIP=$INTIP INTBC=$INTBC INTMSK=$INTMSK INTNET=$INTNET"
  
    # Сейчас мы собираемся создать несколько собственных цепочек, результатом работы
    # которых будет логгинг отброшенных пакетов. Это поможет нам избежать необходимости
    # вводить команду log перед каждым отбрасыванием пакета, что мы хотим запротоколировать.
    # Первыми идут лог отброшенных пакетов и собственно отброс, затем лог пакетов с отказами
    # и собственно отказы.
    # Отключаем сообщения о том, что цепочки уже существуют (чтобы перезапуск был без мусора)
     $IPT -N DROP   2> /dev/null
     #$IPT -A DROP   -j LOG --log-level DEBUG --log-prefix "DROP:"
     #$IPT -A DROP   -j DROP
     $IPT -N REJECT 2> /dev/null
     #$IPT -A REJECT -j LOG --log-level DEBUG --log-prefix "REJECT:"
     #$IPT -A REJECT -j REJECT
     #$IPT -A INPUT -j LOG --log-level DEBUG --log-prefix "INPUT:"
     #$IPT -A OUTPUT -j LOG --log-level DEBUG --log-prefix "OUTPUT:"
     #$IPT -A FORWARD -j LOG --log-level DEBUG --log-prefix "FORWARD:"
     #$IPT -A DROP -j LOG --log-level DEBUG --log-prefix "DROP:"
    
  
    # Весь траффик от устройства loopback принимается
    # если IP совпадает с любым из наших интерфейсов.
     $IPT -A INPUT    -i $LPDIF -s   $LPDIP  -j ACCEPT
     $IPT -A INPUT    -i $LPDIF -s   $EXTIP  -j ACCEPT
     $IPT -A INPUT    -i $LPDIF -s   $INTIP  -j ACCEPT
  
    # Широковещательные пакеты
     $IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j ACCEPT
     $IPT -A INPUT   -i $INTIF -d   $INTBC  -j ACCEPT
     $IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j ACCEPT
     $IPT -A OUTPUT  -o $INTIF -d   $INTBC  -j ACCEPT
     $IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j ACCEPT
     $IPT -A FORWARD -o $INTIF -d   $INTBC  -j ACCEPT
  
    # Блокируем доступ к внутренней сети из WAN
    # Это также призвано не дать нечестивым крякерам использовать нашу сетку
    # в качестве отправной точки для атак на других людей
    # Перевод с языка iptables:
    # "если пришедшие на наружный интерфейс пакеты были отправлены не с выданного
    # nefarious адреса, выкинуть их как горячую картошку"
     $IPT -A INPUT  -i $EXTIF -d ! $EXTIP  -j DROP
  
    # А сейчас мы блокируем внутренние адреса, кроме двух, присвоенных нашим двум
    # внутренним интерфейсам.....только помните, что если вы воткнете свой лэптоп или
    # какой другой pc в напрямую в одну из этих сетевых карт, то нужно удостовериться,
    # что они имеют именно эти IP-адреса или добавить соответствующий адрес отдельно.
  
    # Первый интерфейс/первая внутренняя сеть
    # $IPT -A INPUT   -i $INTIF -s ! $INTNET -j DROP
    # $IPT -A OUTPUT  -o $INTIF -d ! $INTNET -j DROP
    # $IPT -A FORWARD -i $INTIF -s ! $INTNET -j DROP
    # $IPT -A FORWARD -o $INTIF -d ! $INTNET -j DROP
  
    # Дополнительная Egress-проверка
    # $IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROP
  
    # Блокируем исходящиие пакеты ICMP (за исключением PING)
    # $IPT -A INPUT -p icmp --icmp-type ! 8 -j DROP
    # $IPT -A OUTPUT -p icmp --icmp-type ! 8 -j DROP
    # $IPT -A FORWARD -p icmp --icmp-type ! 8 -j DROP
     $IPT -A INPUT -p icmp -j ACCEPT
     $IPT -A OUTPUT -p icmp -j ACCEPT
     $IPT -A FORWARD -p icmp -j ACCEPT
      

         $IPT -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300

    # печально известные порты:
    # 0 - tcpmux; у SGI есть уязвимость, через которую можно атаковать
    # 13 - daytime
    # 98 - Linuxconf
    # 111 - sunrpc (portmap)
    # SNMP: 161,2
    # Флотилия Squid: 3128, 8000, 8008, 8080 (пока закроем)
    # 1214 - Morpheus или KaZaA
    # 2049 - NFS
    # 3049 - очень заразный троян для Linux, часто путаемый с NFS
    # Часто атакуемые: 1999, 4329, 6346
    # Частые трояны 12345 65535
     COMBLOCK="0:1 13 98 111 161:162 1214 1999 2049 3049 4329 6346 8000 8008 12345 65535"
    # Порты TCP:
    # 98 - Linuxconf
    # 512-515 - rexec, rlogin, rsh, printer(lpd)
    #   [очень серьезеные уязвимости; продолжаются ежедневные атаки]
    # 1080 - прокси-серверы Socks
    # 6000 - X (ЗАМЕЧАНИЕ. X через SSH - безопасен, и работает на порту TCP 22)
    # Блокировка 6112 (CDE у Sun и HP)
     TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"
    # Порты UDP:
    # 161:162 - SNMP
    # 520=RIP, 9000 - Sangoma
    # 517:518 - talk и ntalk (самые надоедливые)
     UDPBLOCK="$COMBLOCK 520 123 517:518 1427 9000"
    echo -n "FW: Blocking attacks to TCP port"
    for i in $TCPBLOCK;
    do
     echo -n "$i "
      $IPT -A INPUT   -p tcp --dport $i  -j DROP
      $IPT -A OUTPUT  -p tcp --dport $i  -j DROP
      $IPT -A FORWARD -p tcp --dport $i  -j DROP
    done
    echo ""
    echo -n "FW: Blocking attacks to UDP port "
    for i in $UDPBLOCK;
    do
     echo -n "$i "
      $IPT -A INPUT   -p udp --dport $i  -j DROP
      $IPT -A OUTPUT  -p udp --dport $i  -j DROP
      $IPT -A FORWARD -p udp --dport $i  -j DROP
    done
    echo ""
  
    # Открываем отлеживание соединений по ftp
     MODULES="ip_nat_ftp ip_conntrack_ftp"
     for i in $MODULES;
     do
      echo "Inserting module $i"
      modprobe $i
     done
      
    # Защищаем некоторые распространенные клиенты для чата.
    # Уберите из списка допустимых для пущей безопасности.
    # IRC='ircd'
     MSN=1863
     ICQ=5190
     SSH2=122
     TCP81=81
     #RDM=489
     NFS='sunrpc'
    # Нам нужно синхронизировать данные!!
     PORTAGE='rsync'
     OpenPGP_HTTP_Keyserver=11371
    # Все порты сервисов читаются из /etc/services
    # TCPSERV="domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $MSN $ICQ  $OpenPGP_HTTP_Keyserver" UDPSERV="domain time"
      TCPSERV="domain $SSH2 $TCP81 http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time www webmin $PORTAGE $MSN $ICQ $OpenPGP_HTTP_Keyserver 4899" UDPSERV="domain time netbios-ns netbios-dgm netbios-ssn microsoft-ds"
    echo -n "FW: Allowing inside systems to use service:"
    for i in $TCPSERV;
    do
     echo -n "$i "
        $IPT -A INPUT  -i $INTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT
      $IPT -A INPUT  -i $EXTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT
      $IPT -A OUTPUT -o $INTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT
      $IPT -A OUTPUT -o $EXTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT
      $IPT -A FORWARD -i $INTIF -p tcp -s $INTNET --dport $i --syn -m state --state NEW -j ACCEPT
    done
    echo ""
    echo -n "FW: Allowing inside systems to use service:"
    for i in $UDPSERV;
    do
     echo -n "$i "
        $IPT -A INPUT  -i $INTIF -p udp --dport $i -m state --state NEW -j ACCEPT
      $IPT -A OUTPUT -o $INTIF -p udp --dport $i -m state --state NEW -j ACCEPT
      #$IPT -A OUTPUT -o $EXTIF -p udp --dport $i -m state --state NEW -j ACCEPT
      $IPT -A FORWARD -i $INTIF -p udp -s $INTNET --dport $i -m state --state NEW -j ACCEPT
    done

    # Запрещаем форвардинг для юзеров с отключенным инетом
    echo "Blocked IP forwarding"
  
    # первой внутренней сети
    for ip in $(cat $FILENAME_DENY); do
    $IPT -I FORWARD -s $ip -j DROP
    done

    # DNS rndc сервер на Lo разрешаем. (обход connection refused)
        $IPT -A OUTPUT -p tcp -m tcp -o $LPDIF --dport 953 --sport $UNPRIPORTS -j ACCEPT
  
    # разрешаем доступ DNS-серверу наружу
    $IPT -A OUTPUT -o $EXTIF -p tcp --dport domain -j ACCEPT
    $IPT -A OUTPUT -o $EXTIF -p udp --dport domain -j ACCEPT
      
    # NAT
    $IPT -t nat -A PREROUTING -j ACCEPT
    $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j MASQUERADE
    $IPT -t nat -A POSTROUTING -j ACCEPT
    $IPT -t nat -A OUTPUT -j ACCEPT
    $IPT -A INPUT -p tcp --dport auth --syn -m state --state NEW -j ACCEPT
    $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPT -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
  
    # Заблокировать и запротоколировать все, что мы могли забыть.
    #$IPT -A INPUT -j DROP

    #Для тэстирования NetAMS раскомментировать
    #$IPT -P FORWARD DROP
    #$IPT -P FORWARD QUEUE
    #$IPT -A FORWARD -p all -j QUEUE
    $IPT -A INPUT -j DROP
    $IPT -A OUTPUT -j REJECT
    $IPT -A FORWARD -j DROP
  
    # Squid transparent
     $IPT -t nat -A PREROUTING -i $INTIF -s $INTNET -p tcp -d 0.0.0.0/0 --dport 80 -j REDIRECT --to-port 3128


}
flush_fw()
{
    $IPT -P INPUT ACCEPT
    $IPT -P FORWARD ACCEPT
    $IPT -P OUTPUT ACCEPT
    $IPT -t nat -P PREROUTING ACCEPT
    $IPT -t nat -P POSTROUTING ACCEPT
    $IPT -t nat -P OUTPUT ACCEPT
    $IPT -t mangle -P PREROUTING ACCEPT
    $IPT -t mangle -P OUTPUT ACCEPT
  
    $IPT -F
    $IPT -t nat -F
    $IPT -t mangle -F

    $IPT -X
    $IPT -t nat -X
    $IPT -t mangle -X
}

case "$1" in
start)    echo -n "Starting firewall: iptables"
    start_fw
    echo ""
        echo -n "Starting firewall Ok!"
    echo ""  
    ;;
stop)    echo -n "Stopping firewall: iptables"
    flush_fw
    echo ""
        echo -n "Stopping firewall Ok!"
    echo ""
        ;;
save)    echo -n "Saving firewall: iptables"
    iptables-save > /etc/rules-save
    echo ""  
    echo -n "Status save Ok!."
    echo ""
    ;;
restart) echo -n "Restarting firewall: iptables"
    flush_fw
    start_fw
    echo ""
    echo -n "Status restart Ok!"
    echo ""
        ;;
reload|force-reload) echo -n "Reloading configuration files for firewall: iptables"
        echo "."
        ;;
*)    echo "Usage: /etc/init.d/rc.firewall start|stop|restart|reload|force-reload|save"
        exit 1
        ;;
esac
exit 0


2.
Делаю скрипт исполняемым - 'chmod +x /etc/init.d/rc.firewall'
3. Добавляю в автозагрузку ссылку - 'ln -s /etc/init.d/rc.firewall /etc/rc2.d/S99rc.firewall'
4. Создаю файл в котором будет перечень адресов которым запрещен доступ в Internet (файл задействован в конфиге)  - 'nano /etc/deny_inet_host' следующего содержания:
192.168.0.250
192.168.0.251
192.168.0.252
192.168.0.253
192.168.0.254 


PS. В скрипте задействованы многие правила отдельно публикуемые в предыдущих статьях.