Советы и приемы iptables [закрыто]

Я уверен, что системные администраторы Linux хорошо знакомы с iptables , пользовательским интерфейсом к netfilter ] структура фильтрации пакетов.

Теперь этот «Вопрос» предназначен для Вики Сообщества для сбора воедино различных битов и кусочков мудрости iptables . Нет ничего слишком обычного или неясного. Публикуйте все, что вы знаете, что поможет другим максимально использовать iptables .

60
задан 10 March 2011 в 16:15
18 ответов

Используя белый список и черный список с iptables

#!/bin/bash

WHITELIST=/whitelist.txt
BLACKLIST=/blacklist.txt

#THIS WILL CLEAR ALL EXISTING RULES!
echo 'Clearing all rules'
iptables -F

#
## Whitelist
#

for x in `grep -v ^# $WHITELIST | awk '{print $1}'`; do
        echo "Permitting $x..."
        $IPTABLES -A INPUT -t filter -s $x -j ACCEPT
done

#
## Blacklist
#

for x in `grep -v ^# $BLACKLIST | awk '{print $1}'`; do
        echo "Denying $x..."
        $IPTABLES -A INPUT -t filter -s $x -j DROP
done

Сценарий к открытым портам

#!/bin/bash
ALLOWEDTCP="80 3128 3784"
ALLOWEDUDP="3128 3784"

#
## Permitted Ports
#

for port in $ALLOWEDTCP; do
       echo "Accepting port TCP $port..."
       $IPTABLES -A INPUT -t filter -p tcp --dport $port -j ACCEPT
done

for port in $ALLOWEDUDP; do
        echo "Accepting port UDP $port..."
        $IPTABLES -A INPUT -t filter -p udp --dport $port -j ACCEPT
done

Блокирование сканирования портов

# Attempt to block portscans
# Anyone who tried to portscan us is locked out for an entire day.
iptables -A INPUT   -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP

# Once the day has passed, remove them from the portscan list
iptables -A INPUT   -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove

# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A INPUT   -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP

Имитировавший/Недопустимые пакеты

# Reject spoofed packets
# These adresses are mostly used for LAN's, so if these would come to a WAN-only server, drop them.
iptables -A INPUT -s 10.0.0.0/8 -j DROP
iptables -A INPUT -s 169.254.0.0/16 -j DROP
iptables -A INPUT -s 172.16.0.0/12 -j DROP
iptables -A INPUT -s 127.0.0.0/8 -j DROP

#Multicast-adresses.
iptables -A INPUT -s 224.0.0.0/4 -j DROP
iptables -A INPUT -d 224.0.0.0/4 -j DROP
iptables -A INPUT -s 240.0.0.0/5 -j DROP
iptables -A INPUT -d 240.0.0.0/5 -j DROP
iptables -A INPUT -s 0.0.0.0/8 -j DROP
iptables -A INPUT -d 0.0.0.0/8 -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
iptables -A INPUT -d 255.255.255.255 -j DROP

# Drop all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP

Смурф блока нападает

# Stop smurf attacks
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
iptables -A INPUT -p icmp -m icmp -j DROP

# Drop excessive RST packets to avoid smurf attacks
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

Блок ICMP (иначе ping)

# Don't allow pings through
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
26
ответ дан 28 November 2019 в 19:32

Другой GUI, который может использоваться для конфигурирования iptables, является Разработчиком Брандмауэра. Это позволяет пользователям создать элементы правила как объекты в базе данных и затем перетащить эти объекты в редактора правил создать желаемую политику брандмауэра. Приложение затем генерирует файл сценария со всеми командами iptables, требуемыми реализовать правила.

В отличие от некоторых других iptables решений GUI, где можно только управлять одной iptables конфигурацией за один раз с Разработчиком Брандмауэра, можно управлять большим количеством iptables конфигураций все из отдельного приложения. Разработчик брандмауэра работает на Linux, Windows и Mac OS X, был вокруг больше 10 лет и имеет тысячи активных пользователей во всем мире.

Полное раскрытие - я - соучредитель NetCitadel, который является компанией, которая разрабатывает Разработчика Брандмауэра.

2
ответ дан 28 November 2019 в 19:32

(из моего файла iptables_tricks.txt, перекомпилированного от большого количества мест :P)

Заставляет iptables ожидать 15 секунд между новыми соединениями от того же IP на порте 22 (SSH):

 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
 iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
4
ответ дан 28 November 2019 в 19:32

использование FireHOL - удобная iptables обертка

Я нашел это намного более интуитивным, чем прямые команды iptables. Специально для людей с прошлым опытом с другими брандмауэрами:

FireHOL является iptables генератором брандмауэра, производящим iptables пакетные брандмауэры фильтрации с сохранением информации, на хостах Linux и маршрутизаторах с любым количеством сетевых интерфейсов, любым количеством маршрутов, любым номером обслуживаемых служб, любым количеством сложности между изменениями сервисов (включая положительные и отрицательные выражения).

4
ответ дан 28 November 2019 в 19:32

Блок нападения ICMP

Добавьте следующие правила, предпочтительно в -t raw -A PREROUTING

-p icmp -m u32 ! --u32 "4&0x3FFF=0"   -j DROP
-p icmp -m length --length 1492:65535 -j DROP

Первое правило блокирует все пакеты ICMP, чьи "флаг фрагментации" не 0. (ICMP никогда не должен фрагментироваться; они должны нести маленькие полезные нагрузки),

Вторые блоки правила нефрагментированные пакеты ICMP увеличенного размера.

6
ответ дан 28 November 2019 в 19:32

Включение NAT

  1. echo 1 > /proc/sys/net/ipv4/ip_forward
  2. /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Шаг 1 устанавливает параметр ядра для обеспечения IP передачи, шаг 2 устанавливает iptables правило, которое включает NAT в интерфейсе eth0.

7
ответ дан 28 November 2019 в 19:32

Блок известные нападения TCP

Добавьте следующие правила, предпочтительно в -t raw -A PREROUTING

-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP

Заблокированные нападения, соответственно:

  • Нападение SYN-FIN
  • Нападение SYN-RST
  • Рождественское нападение
  • nmap сканирование FIN
  • Нападение NULLflags
  • Нападение ALLflags

(не стесняйтесь редактировать названия нападений выше),

16
ответ дан 28 November 2019 в 19:32

Оптимизируйте Производительность netfilter Используя ipset

Если Вы пишете много подобных правил на основе простого IP, порта, или обоих, рассматриваете использование ipset оптимизировать производительность netfilter.

Например:

iptables -s 192.168.1.11 -j ACCEPT
iptables -s 192.168.1.27 -j ACCEPT
iptables -s 192.168.1.44 -j ACCEPT
... hundreds of similar rules ...
iptables -s 192.168.251.177 -j ACCEPT

Это означает, что пакет с исходным адресом 192.168.251.177 должен сначала пересечь сотни правил, прежде чем это сможет добраться, его вердикт ПРИНИМАЮТ.

Конечно, опытные системные администраторы разделят правила подсетью. Но это все еще означает сотни правил.

ipset к спасению!

Во-первых, определите Набор IP ipmap тип:

ipset -N Allowed_Hosts ipmap --network 192.168.0.0/16

Затем заполните его с адресами:

for ip in $LIST_OF_ALLOWED_IP; do ipset -A Allowed_Hosts $ip; done

Наконец, замените сотни правил iptables выше с одним правилом:

iptables -m set --match-set Allowed_Hosts src -j ACCEPT

Когда пакет прибудет, netfilter будет работать, очень быстрый битовый массив ищут источник пакета (src) IP против Allowed_Hosts Набор IP. Все пакеты, прибывающие из 192.168.0.0/16, испытают одно правило. И действительно полагайте мне, что поиск битового массива является по крайней мере двумя порядками величин быстрее, чем работающие сотни iptables проверки правила.

ipset не ограничен IP-адресами. Это может также соответствовать на основе портов, кортежа порта IP, сети/адресов подсети, кортежа MAC IP, и т. д. и т. п. И это может соответствовать тем критериям как источнику или месту назначения или соединению обоих (в случае кортежей).

И наконец, с ipset можно автоматически поместить IP-адреса в черные списки/белые списки. Эти черные списки/белые списки могут также 'стареть', таким образом автоматически удаляя IP-адрес после того, как настраиваемое количество времени передало.

См. ipsetстраница справочника для получения дополнительной информации.

ОЧЕНЬ ВАЖНОЕ ПРИМЕЧАНИЕ:

Некоторые дистрибутивы Linux не могут иметь поддержки 'out-of-the-box' ipset (например, Ubuntu 10.04 имела эту проблему). В этих системах один метод должен установить ipset от исходного кода.

Вместо этого загрузите ipsetисточник с его веб-сайта: http://ipset.netfilter.org/install.html

С другой стороны, если Вы используете xtables-addons, ipset включен в свой источник: http://xtables-addons.sourceforge.net/

25
ответ дан 28 November 2019 в 19:32

Учебные руководства по видео IPTABLES

Эпизод 1 http://www.youtube.com/watch?v=ldB8kDEtTZA&feature=player_embedded

Эпизод 2 http://www.youtube.com/watch?v=aDaEXxRHeXY&feature=related

Заключительный эпизод

http://www.youtube.com/watch?v=JojqHKcSxpo&feature=player_embedded

Будет хорошее начало для любого новичка.

3
ответ дан 28 November 2019 в 19:32

Добавьте комментарии к своим правилам:

-m comment --comment "Comments help to read output of iptables -nvL"
21
ответ дан 28 November 2019 в 19:32

Что-то, что я делаю, в основном из-за моего незнания более элегантного решения, заключается в ручной проверке моих логов Nginx каждые 4 часа и логов почтового сервера каждые 2 минуты на предмет чрезмерного доступа по отдельным IP-адресам. Я запускаю несколько скриптов вместе, которые:

  1. Проверяют access.log и составляют список 10 лучших IP-адресов, организованных по количеству обращений к серверу
  2. Сбрасывают результаты в лог-файл
  3. Пусть другой скрипт посмотрит на этот лог-файл и запретит любой IP-адрес, который ударил по серверу более X раз за последние X часов
  4. Сохраните мои iptables. save

Вот как это выглядит:

autoBanIPs_mail.sh
#!/bin/bash

# This script checks the last 2 minutes of log entries to see if any 
# IP has made over 99 connections

now=$(date +"%m_%d_%Y")

/root/bin/checkBadIPs_mail.sh > /home/ipChecker/ipcheckMAIL_$now.txt
cat /home/ipChecker/ipcheckMAIL_$now.txt | \
    grep " \\(\\([9][9]\\)\\|\\([0-9][0-9][0-9]\\+\\)\\) " | \
    awk '{print $2}' > /home/ipChecker/badMailIPs_$now.sh
sed -i "s/^/\/usr\/local\/sbin\/blockIP /g" /home/ipChecker/badMailIPs_$now.sh
/bin/bash /home/ipChecker/badMailIPs_$now.sh
cat /home/ipChecker/ipcheckMAIL_$now.txt >> /home/ipChecker/ipcheckMAIL_$now.log
rm /home/ipChecker/ipcheckMAIL_$now.txt
rm /home/ipChecker/badMailIPs_$now.sh
checkBadIPs_mail.sh

ОЧЕНЬ важно отметить, что вы НЕ ДОЛЖНЫ установить белый список, иначе вы начнете блокировать множество аутентичных IP-адресов с серверов, с которых вы просто получаете много электронной почты, или, в случае с другими логами, IP-адреса, которые просто сильно ударяют по вашему серверу по уважительным причинам. Мой белый список только что встроен в этот сценарий путем добавления grep труб сразу после | grep ']' |, которые выглядят примерно так "grep -v 127.0 |".
. Вам нужно время, чтобы научить ваш сервер, какие IP-адреса высокого трафика легальны, а какие нет. Для меня это означало, что я должен был провести первую неделю или около того, проверяя мои журналы вручную каждые пару часов, просматривая высокий трафик ip на iplocation.net, а затем добавляя легальные, такие как amazon, box.com или даже мой дом/офис IP диапазоны в этот белый список. Если вы этого не сделаете, то, скорее всего, вас заблокируют с вашего собственного сервера или вы начнете блокировать легальные почтовые/веб-серверы и вызывать прерывания в электронной почте или в трафике.

cat /var/log/mail.log | awk \
    -v d1="$(date --date="-2 min" "+%b %_d %H:%M")" \
    -v d2="$(date "+%b %_d %H:%M")" \
    '$0 > d1 && $0 < d2 || $0 ~ d2' | \
    grep '\[' | grep '\]' | \
    grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v 127.0 | \
    awk '{print $1}' | sort | uniq -c | sort -n | tail -10
BlockIP
#!/bin/bash
sudo iptables -I INPUT -s $1 -j DROP
sudo bash -c "iptables-save > /etc/network/iptables.save"

Again I know this is crude as hell and there probably is a nice clean efficient protocol that does all of this, but I didn't know about it and this thing was going for a year or two now and keep the bad guys at a bay. Единственное, что я бы очень СЕРЬезно порекомендовал, это то, что у вас есть прокси или другой сервер в крыльях, который вы можете использовать для доступа к вашему основному серверу... Причина в том, что если вы делаете веб-разработки один день из ниоткуда и вы пингуете себе 2000 раз за 5 часов для некоторых тестов, то вы можете получить блокировку без возможности вернуться назад, кроме прокси.

Вы можете видеть, что в checkBadIPs.sh я поставил grep -v 127.0 и в моих актуальных файлах у меня есть куча правил игнорирования для моих собственных IP и других доверенных диапазонов IP, но иногда ваш IP меняется, вы забываете обновиться и затем вы заблокированы от вашего собственного сервера.

В любом случае, надеюсь, что это поможет.

UPDATE

Я немного изменил ситуацию, так что теперь вместо проверки каждые пару часов я проверяю журналы каждые 2 минуты, в основном мой ssh auth-журнал и почтовый журнал по мере того, как они стучат :(.

Я настраиваю специальные скрипты для каждого лог-файла, хотя это было бы достаточно просто из ручного скрипта, который я использую сам, когда хочу проверить лог-файлы. Похоже на то:

#!/bin/bash

log=$1 time=$2

cat /var/log/${log} | awk \
    -v d1="$(date --date="-${time} min" "+%b %_d %H:%M")" \
    -v d2="$(date "+%b %_d %H:%M")" \
    '$0 > d1 && $0 < d2 || $0 ~ d2' | \
    grep '\[' | grep '\]' | \
    grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
    sort | uniq -c | sort -n | tail -10

Это требует 2 входа при запуске, лог-файл, который Вы хотите просканировать, и как далеко в прошлое Вы хотите просканировать.

Так что, если бы я хотел проверить mail.log на подсчет ip, я бы запустил его через 75 минут в прошлое:

$ sudo script.sh mail.log 75
0
ответ дан 28 November 2019 в 19:32
#!/bin/bash
# The following iptables/ip6tables configurations have
# been kindly shared with us from ArckWiki. There are
# a few additions apart from what has been defined.
#
#=================Flush current definitions==============
    iptables -F
    ip6tables -F
    iptables -X
    ip6tables -X

#
#=================Chains=================================
#
#----Define chains for opened ports
    iptables -N TCP
    ip6tables -N TCP
    iptables -N UDP
    ip6tables -N UDP

#
#----Setting up the filter table for NAT
#   iptables -N fw-interfaces
#   ip6tables -N fw-interfaces
#   iptables -N fw-open
#   ip6tables -N fw-open

#
#================Default Chain reactions=================
#
#----Default FORWARD reaction
    iptables -P FORWARD DROP
    ip6tables -P FORWARD DROP

#
#----Default OUTPUT reaction
    iptables -P OUTPUT ACCEPT
    ip6tables -P OUTPUT ACCEPT

#
#----Shellshock
    iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
    ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP

#
#----Default INPUT reaction
    iptables -P INPUT DROP
    ip6tables -P INPUT DROP
#
#----Drop spoofing packets
    iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -i wlan0 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -i wlan1 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -s 10.0.0.0/8 -j DROP
    iptables -A INPUT -s 169.254.0.0/16 -j DROP
    iptables -A INPUT -s 172.16.0.0/12 -j DROP
    iptables -A INPUT -s 224.0.0.0/4 -j DROP
    iptables -A INPUT -d 224.0.0.0/4 -j DROP
    iptables -A INPUT -s 240.0.0.0/5 -j DROP
    iptables -A INPUT -d 240.0.0.0/5 -j DROP
    iptables -A INPUT -s 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 0.0.0.0/8 -j DROP
    iptables -A INPUT -d 239.255.255.0/24 -j DROP
    iptables -A INPUT -d 255.255.255.255 -j DROP

#
#================Ping rate limiting globally=============
    iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 30/min --limit-burst 8 -j ACCEPT
    ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 --match limit --limit-burst 8 -j ACCEPT
    iptables -A INPUT -p icmp --icmp-type 8 -j DROP
    ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 -j DROP

#
#----flooding RST packets, smurf attack Rejection
    iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

#
#----Bogus packet DROP
    iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
    ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP

#
#================RELATED,ESTABLISHED reaction============
    iptables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    ip6tables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#
#================unfetered loopback======================
    iptables -A INPUT -i lo -j ACCEPT
    ip6tables -A INPUT -i lo -j ACCEPT

#
#================INVALID catagory of packets=============
    iptables -A INPUT -p 41 -j ACCEPT
    iptables -A INPUT --match conntrack --ctstate INVALID -j DROP
    ip6tables -A INPUT --match conntrack --ctstate INVALID -j DROP

#
#================IPv6 reactions and definitions==========
    ip6tables -A INPUT -s fe80::/10 -p icmpv6 -j ACCEPT
    ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/10 -j ACCEPT
    ip6tables -t raw -A PREROUTING --match rpfilter -j ACCEPT
    ip6tables -t raw -A PREROUTING -j DROP
#
#=======Acceptable INVALIDs and a curteous response======
    iptables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
    ip6tables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP
    iptables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP
    ip6tables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP

#
#================Defining the TCP and UDP chains
#
#########################################################
#            Notes for port open definitions            #
# It is important to note that this should be config-   #
# ured differently if you're providing any routing      #
# activity for any purpose. it is up to you to actively #
# define what suites your needs to get the job done.    #
# In this example, I'm exempting IPv6 from being able   #
# to interact with SSH protocols for two reasons. The   #
# first is because it is generally easier and more com- #
# for internal networks to be deployed with IPv4. The   #
# second reason is, IPv6 can be deployed globally.      #
#########################################################
#
#----SSH configured for eth0
    iptables -A TCP -i eth0 -p tcp --dport ssh -j ACCEPT

#!---Blocking SSH interactions in IPv6
    ip6tables -A TCP -p tcp --dport ssh -j DROP

#!---Leave commented for end service device
#   iptables -A TCP -p tcp --dport 80 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 80 -j ACCEPT
#   iptables -A TCP -p tcp --dport 443 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 443 -j ACCEPT
#
#!---Uncomment for remote service to this device
#   iptables -A TCP -p tcp --dport 22 -j ACCEPT
#   ip6tables -A TCP -p tcp --dport 22 -j ACCEPT
#
#!---Uncomment if you're providing routing services
#   iptables -A UDP -p udp 53 -j ACCEPT
#   ip6tables -A UDP -p udp 53 -j ACCEPT
#
#=================Tricking port scanners=================
#
#----SYN scans
    iptables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
    ip6tables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP
    iptables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP
    ip6tables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP

#
#----UDP scans
    iptables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
    ip6tables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP
    iptables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP
    ip6tables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP

#
#----For SMURF attack protection
    iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
    iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
    iptables -A INPUT -p icmp -m limit --limit 2/second --limit-burst 2 -j ACCEPT
    ip6tables -A INPUT -p icmpv6 -m limit --limit 2/second --limit-burst 2 -j ACCEPT

#
#----Ending all other undefined connections
    iptables -A INPUT -j DROP
    ip6tables -A INPUT -j DROP

#
#=======Defining the IN_SSH chain for bruteforce of SSH==
#
#!---I've elected to keep IPv6 out of this realm for
#!---ease of use
    iptables -N IN_SSH
    iptables -A INPUT -p tcp --dport ssh --match conntrack --ctstate NEW -j IN_SSH
    iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP
    iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP
    iptables -A IN_SSH --match recent --name sshbf --set -j ACCEPT
    iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH

#
#==================Setting up a NAT gateway==============
#
#########################################################
#                                                       #
# I commented this half out because it's not something  #
# that will apply to all setups. Make note of all par-  #
# tinate interfaces and what exactly is going on.       #
#                                                       #
#########################################################
#
#----Setting up the FORWARD chain
#   iptables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#   ip6tables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#
#
#----Defining the fw-interfaces/open chains for FORWARD
#   iptables -A FORWARD -j fw-interfaces
#   ip6tables -A FORWARD -j fw-interfaces
#   iptables -A FORWARD -j fw-open
#   ip6tables -A FORWARD -j fw-open
#   iptables -A FORWARD -j DROP # Should be REJECT. But, fuck them
#   ip6tables -A FORWARD -j DROP
#   iptables -P FORWARD DROP
#   ip6tables -P FORWARD DROP
#
#
#----Setting up the nat table
#   iptables -A fw-interfaces -i ### -j ACCEPT
#   ip6tables -A fw-interfaces -i ### -j ACCEPT
#   iptables -t nat -A POSTROUTING -s w.x.y.z/S -o ppp0 -j MASQUERADE
#   ip6tables -t nat -A POSTROUTING -s fe::/10 -o ppp0 -j MASQUERADE
#----The above lines should be repeated specifically for EACH interface
#
#----Setting up the PREROUTING chain
#
#######################################################
#                             #
# The PREROUTING chain will redirect either port      #
# targets to be redirected. This can also redirect    #
# traffic inbound to your network from the gateway    #
# to this machine. This can be useful if you're using #
# a honeypot or have any service within your network  #
# that you want to be pointed to a specific device.   #
#                             #
#######################################################
#
#----SSH honeypot server
#   iptables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
#   ip6tables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT
#----With intuition, you can configure the above to also direct specific
#----requests to other devices providing those services. The bellow will
#----be for a squid server
#   iptables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
#   ip6tables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT
#   iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
#   ip6tables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP
#
#===============Declare configurations=================
    iptables -nvL
    ip6tables -nvL
-2
ответ дан 28 November 2019 в 19:32

регистрировать исходящее соединение с uid

iptables -A OUTPUT -m state --state NEW -m tcp -p tcp -m limit --limit 5/m -j LOG --log-uid --log-prefix="outgoing connection: "

порт / переадресация соединения:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.1.7:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT
1
ответ дан 28 November 2019 в 19:32

Сопоставьте несколько имен интерфейсов с помощью подстановочного знака

Пример: у вас есть eth0 и eth1 и вы хотите разрешить любой трафик между ними?

iptables -A FORWARD -i eth+ -o eth+ -j ACCEPT

Я использовал это в прошлом для сопоставления интерфейсов veth , динамически создаваемых и именованных LXC. Поэтому я могу сопоставить все сразу с помощью veth + .

Я также намеренно назвал некоторые интерфейсы _ , чтобы сопоставить с _ + . . 1136057]

1
ответ дан 28 November 2019 в 19:32

Снова о наборах IP

Уже есть ответ, в котором упоминаются наборы IP. Тем не менее, он довольно одномерен, поскольку фокусируется на выигрыше в производительности по сравнению с классическими правилами и на том факте, что наборы IP смягчают проблему с большим количеством индивидуальных IP-адресов, которые нельзя легко выразить как подсеть в нотации CIDR.

Обозначения, используемые ниже

Для ipset я буду использовать обозначения, прочитанные ipset restore и записанные ipset save .

Соответственно для iptables Правила ip6tables ) Я буду использовать обозначения, прочитанные iptables-restore и написанные iptables-save . Это сокращает нотацию и позволяет мне выделить потенциальные правила только для IPv4 (с префиксом -4 ) или только для IPv6 (с префиксом -6 ).

В некоторых примерах мы перенаправим поток пакетов в другую цепочку. Предполагается, что в этой точке существует цепочка, поэтому строки для создания цепочек не создаются (также не упоминается имя таблицы или команды COMMIT в конце).

Расширенные наборы IP

Наборы IP могут намного больше, чем было упомянуто в другом ответе , и вам обязательно следует прочитать документацию по набору IP ( ipset (8) ) вместе с iptables -extensions (8) в дополнение к этой краткой записи здесь.

Например, я в основном сосредоточусь на трех типах наборов: hash: ip , hash: net и list: set , но их больше, и все они имеют допустимые варианты использования.

Вы можете, например, также сопоставить номера портов , а не только IP-адреса .

Сохранение и восстановление наборов IP, как с iptables-save и iptables-restore

. Вы можете создавать объявления наборов IP в большом количестве и импортировать их, передавая их по конвейеру в ipset restore . Если вы хотите сделать вашу команду более устойчивой к уже существующим записям, используйте ipset -exist restore .

Если ваши правила находятся в файле с именем default.set , вы должны использовать :

ipset -exist restore < default.set

Такой файл может содержать записи для создания наборов и для добавления в них записей. Но, как правило, похоже, что для большинства команд из командной строки в файлах есть соответствующая версия. Пример (создание набора DNS-серверов):

create dns4 hash:ip family inet
create dns6 hash:ip family inet6
# Google DNS servers
add dns4 8.8.8.8
add dns4 8.8.4.4
add dns6 2001:4860:4860::8888
add dns6 2001:4860:4860::8844

Здесь один набор создается для IPv4 ( dns4 ), а второй - для IPv6 ( dns6 ).

Тайм-ауты для наборов IP

Таймауты в наборах IP могут быть заданы по умолчанию для набора, а также для каждой записи. Это очень полезно для сценариев, в которых вы хотите временно заблокировать кого-либо (например, для сканирования портов или попытки перебора вашего SSH-сервера).

Это работает следующим образом (по умолчанию при создании наборов IP-адресов):

create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800

Мы вернемся к этим конкретным наборам ниже и объясним, почему они настроены именно так.

Если вы хотите установить время ожидания для определенного IP-адреса, вы можете просто сказать:

add ssh_dynblock4 1.2.3.4 timeout 7200

Чтобы заблокировать IP 1.2.3.4 на два часа вместо (установленных) получасовых значений по умолчанию.

Если вы посмотрите на это с помощью ipset save ssh_dynblock4 через короткое время, вы увидите что-то в соответствии со строками:

create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800
add ssh_dynblock4 1.2.3.4 timeout 6954

Предостережения по таймауту

  • тайм-ауты являются особенностью любого заданного набора. Если набор не был создан с поддержкой тайм-аута, вы получите сообщение об ошибке (например, Получена ошибка ядра: Неизвестная ошибка -1 ).
  • таймауты указаны в секундах. Используйте арифметические выражения Bash, например, для перехода от минут к секундам. Например: sudo ipset add ssh_dynblock4 1.2.3.4 timeout $ ((120 * 60))

Проверка, существует ли запись в данном наборе IP.

Внутри ваших сценариев может быть полезно увидеть, есть ли запись уже существует. Этого можно добиться с помощью ipset test , который возвращает ноль, если запись существует, и ненулевое значение в противном случае. Таким образом, в сценарии могут быть применены обычные проверки:

if ipset test dns4 8.8.8.8; then
  echo "Google DNS is in the set"
fi

Однако во многих случаях вы предпочтете использовать переключатель -exist на ipset , чтобы не указывать его жаловаться на существующие записи.

Заполнение наборов IP из iptables rules

Это, на мой взгляд, одна из главных особенностей наборов IP. Вы можете не только сопоставить записи набора IP-адресов, но и добавить новые записи к существующему набору IP.

Например, в этот ответ на этот вопрос у вас:

-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT

.. • с намерением ограничить скорость попыток подключения к SSH (TCP-порт 22). Используемый модуль , недавний отслеживает недавние попытки подключения. Однако вместо модуля состояния я предпочитаю модуль conntrack .

# Say on your input chain of the filter table you have
   -A INPUT -i eth+ -p tcp --dport ssh -j SSH
# Then inside the SSH chain you can
# 1. create an entry in the recent list on new connections
   -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
# 2. check whether 3 connection attempts were made within 2 minutes
#    and if so add or update an entry in the ssh_dynblock4 IP set
-4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist
-6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist
# 3. last but not least reject the packets if the source IP is in our
#    IP set
-4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT
-6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT

В этом случае я перенаправляю поток в цепочку SSH , так что я не нужно повторяться с -p tcp --dport ssh для каждого отдельного правила.

Повторяю:

  • -m set делает iptables осведомленным что мы используем переключатели из модуля set (который обрабатывает наборы IP)
  • - match-set ssh_dynblock4 src сообщает iptables , чтобы он соответствовал источнику ( src ) адрес для именованного набора ( ssh_dynblock4 )
    • это соответствует sudo ipset test ssh_dynblock4 $ IP (где $ IP содержит исходный IP-адрес для пакета)
  • -j SET --add-set ssh_dynblock4 src --exist добавляет или обновляет адрес источника ( src ) из пакета в набор IP ssh_dynblock4 . Если запись существует ( - существует ), она будет просто обновлена.
    • это соответствует sudo ipset -exist add ssh_dynblock4 $ IP (где $ IP содержит исходный IP-адрес для пакета)

Если вы хотите сопоставить цель / адрес назначения вместо dst вместо src . Дополнительные параметры см. В руководстве.

Наборы наборов

Наборы IP могут содержать другие наборы. Теперь, если вы читали статью до этого места, вы задавались вопросом, можно ли комбинировать наборы. И конечно это так. Для указанных выше наборов IP мы можем создать два объединенных набора ssh_dynblock и ssh_loggedon соответственно, чтобы содержать наборы только для IPv4 и только для IPv6:

create ssh_loggedon4 hash:ip  family inet  timeout 5400
create ssh_loggedon6 hash:ip  family inet6 timeout 5400
create ssh_dynblock4 hash:ip  family inet  timeout 1800
create ssh_dynblock6 hash:ip  family inet6 timeout 1800
# Sets of sets
create ssh_loggedon  list:set
create ssh_dynblock  list:set
# Populate the sets of sets
add ssh_loggedon ssh_loggedon4
add ssh_loggedon ssh_loggedon6
add ssh_dynblock ssh_dynblock4
add ssh_dynblock ssh_dynblock6

И следующий вопрос, который должен появиться у вас в голове вопрос, позволяет ли это нам сопоставить и управлять наборами IP без привязки к версии IP.

И ответ на этот вопрос звучит однозначно: ДА! (увы, это не было явно задокументировано в прошлый раз, когда я проверял)

Следовательно, правила из предыдущего раздела можно переписать следующим образом:

-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT

, что намного короче. И да, это испытано и протестировано и работает как шарм.

Собираем все вместе: защита от перебора SSH

На моих серверах у меня есть скрипт, запускаемый как cron задание, которое требует набор имен хостов и разрешает их в IP-адреса,затем передать его в набор IP для «доверенных хостов». Идея состоит в том, что доверенные хосты получают больше попыток входа на сервер и не обязательно блокируются так долго, как кто-либо еще.

И наоборот, у меня целые страны заблокированы от подключения к моему SSH-серверу, с (потенциальным) исключение доверенных хостов (то есть порядок правил имеет значение).

Однако это оставлено в качестве упражнения для читателя. Здесь я хотел бы добавить изящное решение, которое будет использовать наборы, содержащиеся в наборе ssh_loggedon , чтобы разрешить последующие попытки подключения и не подвергаться такой же проверке, как другие пакеты.

Важно помнить, что время ожидания по умолчанию составляет 90 минут для ssh_loggedon и 30 минут для ssh_dynblock , глядя на следующие правила iptables :

-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m set --match-set ssh_loggedon src -j ACCEPT
-A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT

К настоящему времени вы должны спросить себя, как подключаемый IP-адрес попадает в поднаборы ssh_loggedon . Так что читайте дальше ...

Бонус: добавление IP-адреса, с которым вы входите в систему во время входа в систему по SSH

Если вы экспериментировали с sshrc и друзьями, вы узнали о его недостатках. Но на помощь приходит PAM. Модуль с именем pam_exec.so позволяет нам вызывать сценарий во время входа в систему SSH в точке, где мы знаем, что пользователь допущен.

В /etc/pam.d/sshd под записями pam_env и pam_selinux добавьте следующую строку:

session    optional     pam_exec.so stdout /path/to/your/script

и убедитесь, что ваша версия сценария ( / path / to / your / script выше) существует и является исполняемым.

PAM использует переменные среды для передачи информации о том, что происходит, поэтому вы можете использовать простой скрипт, подобный этому:

#!/bin/bash
# When called via pam_exec.so ...
SETNAME=ssh_loggedon
if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then
    [[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4"
    ipset -exist add $SETNAME "$PAM_RHOST"
fi

К сожалению, утилита ipset не кажется иметь встроенный ум netfilter. Таким образом, при добавлении нашей записи нам нужно различать IPv4 и IPv6. В противном случае ipset будет считать, что мы хотим добавить еще один набор в набор наборов вместо IP. И, конечно, маловероятно, что будет набор, названный в честь IP:)

Поэтому мы проверяем : в IP-адресе и добавляем 6 к имени набора в таком case и 4 в противном случае.

Конец.

3
ответ дан 28 November 2019 в 19:32

Ограничение всех отдельных IP-адресов квотой исходящей полосы пропускания с помощью наборов IP-адресов

Вы можете настроить свой сервер так, чтобы каждый отдельный IP-адрес использовал 15 ГБ полосы пропускания в месяц, в надежде отразить или уклонитесь от атаки на использование полосы пропускания, возможно, из-за вашей квоты на полосу пропускания у вашего интернет-провайдера. Это можно сделать следующим образом:

Сначала создайте наборы IP для IPv4 и IPv6:

ipset create IP_QUOTA_SET_OUT hash:ip timeout 345600 counters
ipset create IP_QUOTA_SET_OUT_INET6 hash:ip timeout 345600 counters family inet6

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

iptables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT dst -j SET --add-set IP_QUOTA_SET_OUT dst --timeout 345600
iptables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT dst --bytes-gt 16106127360 -j DROP

ip6tables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT_INET6 src -j SET --add-set IP_QUOTA_SET_OUT_INET6 src --timeout 345600
ip6tables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT_INET6 src --bytes-gt 16106127360 -j DROP

Это предотвратит такие атаки, как пользователь, запрашивающий большой файл с вашего веб-сервера в течение длительного периода времени, или с любой другой службы, если на то пошло. То же самое можно сделать для цепочки INPUT.

1
ответ дан 28 November 2019 в 19:32

Блокировать необычные значения MSS

iptables -t mangle -A PREROUTING -p tcp \
-m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

Цель SYNPROXY для защиты от DDos

Цель этой цели - проверить, устанавливает ли хост, отправивший пакет SYN, соединение или ничего не делает после инициации соединения SYN. Если он ничего не делает, он отбрасывает пакет с минимальными усилиями.

Установите синхронизирующие пакеты в таблицу отслеживания соединений в исходной таблице

iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 --syn -j CT --notrack

Включите synproxy для http-сервера:

iptables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate INVALID,UNTRACKED \
-j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

Ресурс: Цель SYNPROXY из блога RHEL

1
ответ дан 28 November 2019 в 19:32

Я согласен с комментариями о флагах ipsets и tcp, но по-прежнему многого не хватает:

Используйте xtables-addons geoip match вместо ipsets для списков стран. Регулярно обновляйте данные geoip (не реже одного раза в месяц). Данные более динамичны, чем список ipset, включающий и забыл.

Рассмотрите возможность отслеживания состояния соединения с помощью флагов tcp. Например, tcp RST или ACK имеет смысл только для установленного соединения. SYN имеет смысл только для новых и связанных соединений. SYN для установленного соединения означает, что ваш SYN + ACK был утерян или попытка взлома, и его следует сбросить, поскольку обе стороны соединения не согласны с состоянием.

Хотя нет, SYN + RST и FIN + RST являются недопустимые комбинации, SYN + FIN теперь действителен при быстром открытии TCP (параметр TCP 34), особенно для DNS. Пакеты SYN, даже с быстрым открытием, не должны фрагментироваться. Я не считаю правила с флагами PSH и URG полезными. Не путайте состояние отслеживания соединения с состоянием TCP: RST-ответ на SYN-пакет устанавливается для целей отслеживания.

SYNPROXY предназначен для пересылаемых пакетов и ничего не добавляет для локально доставленных пакетов, кроме поддержки syncookie.

Пакеты ошибок ICMP будут всегда быть в связанном состоянии и иметь длину 48: 576, если они действительны. Длина 84: 1280 для IPv6. Все остальные следует игнорировать. Поскольку их максимальный размер также является минимальным MTU, их никогда не следует фрагментировать. Запросы ICMP (эхо-запросы, отметки времени и т. Д.) Всегда будут новыми, а ответы установлены. Отбрасывать пакеты ICMP в других состояниях.

Подобно примеру SSH с недавним списком и приемом только последующих SYN-пакетов, то же самое следует делать для SMTP и аналогично «серому списку» только для данных IP-адреса.

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

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

0
ответ дан 28 November 2019 в 19:32

Теги

Похожие вопросы