iptables-proxmox.sh
4.8 KB
Поискал по каналу и не нашёл ни одной заметки, где бы я рассказал и показал на практике, как я настраиваю iptables на гипервизорах Proxmox. Я всегда в обязательном порядке это делаю. Не утверждаю, что так, как настраиваю я, правильно и наиболее подходящий вариант. Просто привык делать именно так, проблем с этим не было, поэтому закрепилось. Воспроизвожу из раза в раз эту настройку.
Порядок настройки следующий:
1️⃣ Сохраняю список правил в файл
Настройку делаю на чистом гипервизоре, поэтому даже если ошибусь где-то, то проблемы это не вызовет. Набор правил отлажен, обычно проблем нет, если не ошибся с именами интерфейсов.
2️⃣ Убеждаюсь, что после выполнения скрипта появился файл-экспорт с набором правил
Вешаю загрузку правил iptables на поднятие wan интерфейса.
3️⃣ Перезагружаю сервер и убеждаюсь, что всё нормально поднимается, правила применяются, доступ к серверу у меня есть.
4️⃣ Если нужно добавить или изменить какое-то правило, то правлю файл
Если у вас хост Proxmox выполняет роль шлюза, то не забудьте проверить, что параметр
В наборе правил пример с работающего сервера. На основе него можете сформировать свой набор правил. Я там некоторые правила закомментировал, так как нужны они будут не всем. Оставил их для примера.
Формирую набор правил именно в таком виде, потому что он мне кажется удобным и наглядным. Можно быстро оценить все правила, оставить комментарии, что-то добавить.
#proxmox #iptables
Порядок настройки следующий:
1️⃣ Сохраняю список правил в файл
/etc/iptables.sh. Адаптирую под текущие условия гипервизора: меняю имена сетевых интерфейсов, IP адреса. Делаю его исполняемым. Обычно сразу же проверяю, просто запустив его. # mcedit /etc/iptables.sh# chmod +x /etc/iptables.sh# bash /etc/iptables.sh# iptables -L -v -nНастройку делаю на чистом гипервизоре, поэтому даже если ошибусь где-то, то проблемы это не вызовет. Набор правил отлажен, обычно проблем нет, если не ошибся с именами интерфейсов.
2️⃣ Убеждаюсь, что после выполнения скрипта появился файл-экспорт с набором правил
/etc/iptables.rules. Добавляю применение правил в файл /etc/network/interfaces:iface enp5s0 inet manualpost-up iptables-restore < /etc/iptables.rulesВешаю загрузку правил iptables на поднятие wan интерфейса.
3️⃣ Перезагружаю сервер и убеждаюсь, что всё нормально поднимается, правила применяются, доступ к серверу у меня есть.
4️⃣ Если нужно добавить или изменить какое-то правило, то правлю файл
iptables.sh, а когда закончу, запускаю его. Он обновляет набор правил в iptables.rules, так что после перезагрузки хоста изменённые правила сохранятся.Если у вас хост Proxmox выполняет роль шлюза, то не забудьте проверить, что параметр
net.ipv4.ip_forward=1 активен в /etc/sysctl.conf. Без него NAT для виртуалок не заработает. Точнее не сам нат, а передача пакетов между локальным и wan интерфейсом. Если в качестве шлюза для VM выступает отдельная VM, то как минимум из набора правил исчезает NAT и всё, что касается локалки и проброса портов. А на шлюз уезжает этот же шаблон с правилами и там правится по месту. В наборе правил пример с работающего сервера. На основе него можете сформировать свой набор правил. Я там некоторые правила закомментировал, так как нужны они будут не всем. Оставил их для примера.
Формирую набор правил именно в таком виде, потому что он мне кажется удобным и наглядным. Можно быстро оценить все правила, оставить комментарии, что-то добавить.
#proxmox #iptables
3👍145👎4
На днях случился необычный для меня инцидент. Расскажу, как его преодолел. Сразу скажу, что это будет не инструкция, как надо делать, а то, как поступил я в конкретной ситуации. У меня есть в управлении одиночный сервер, где одна из виртуальных машин выполняет роль Nginx Proxy для других сервисов. Кто-то эту прокси решил ддоснуть. Немного растерялся от ситуации, так как сталкиваешься с ней нечасто и выверенного алгоритма действий нет.
Я не знаю, кем и для чего это делалось. Виртуалка проксировала доступ на неприметный публичный сайт, который давно не обновлялся и работал для галочки. Также проксировались соединения на мониторинг, 1С и некоторые другие внутренние сервисы для доступа к ним извне. На виртуалке внутри не было никакой защиты от ddos, внешняя, соответственно, тоже подключена не была. В этом не было необходимости. Ничего критичного там не стояло.
От мониторинга прилетел алерт на недоступность некоторых ресурсов, и на высокий LA виртуалки. По SSH хоть и небыстро, но подключился к ней. Заодно сразу зашёл на гипервизор. Он нормально переваривал нагрузку. Увидел, что на виртуалке CPU на четырёх ядрах в потолке. И все ядра нагрузил Nginx. Голым Nginx нагрузить практически пустыми соединениями на 100% 4 CPU не так просто. Я думал, что сейчас провайдер просто отрубит сервак и на этом всё закончится. Но нет, он переваривал, так что я стал разбираться на сервере локально.
Глянул лог Nginx и увидел массовые обращения на один конкретный URL публичного сайта с разных IP адресов. Вообще не понял, причём тут этот URL и почему в него долбят. Первое, что сделал, вообще отключил этот сайт. Nginx стал отдавать 502 ошибку, но серверу это слабо помогло.
Потом добавил параметр
в nginx.conf и
в настройки виртуального хоста. Хотел собирать айпишники тех, кто открывает более 50 соединений к сайту, чтобы потом их банить. Но там особо не собиралось, плюс лог ошибок рос с огромной скоростью, трудно было из него что-то выбирать. Виртуалка и так сильно тормозила. IP постоянно менялись, одновременных запросов, которые бы ловились Nginx, не было.
Решил мимо Nginx напрямую с iptables работать. У меня есть в закладках команда, которая сортирует и считает соединения с каждого IP адреса:
Тут уже было хорошо видно адреса, которые открыли много соединений. Немного изменил скрипт, чтобы выводить чистые списки IP адресов, открывших более 50-ти соединений и сохранять их в файл:
Дальше создал список ipset для использования списка IP адресов в правилах iptables. Напрямую большие списки в iptables направлять не надо, он их может не переварить.
Закинул туда список пойманных ранее IP адресов:
И сделал правило в iptables для блокировки из этого списка:
Блокировка заработала, счётчики правила пошли вверх, но помогло это слабо. Адреса постоянно менялись. Собрал всё это в скрипт и запускал по крону раз в минуту, тоже не помогло.
Решил забанить всех, кто обращается к урлу, который ддосят. Забирал IP ардеса, чтобы сильно не грузить сервак, так:
Собрал их в ipset, добавил правило блокировки:
Продолжение в следующей заметке 👇👇👇👇
#ddos #nginx #iptables
Я не знаю, кем и для чего это делалось. Виртуалка проксировала доступ на неприметный публичный сайт, который давно не обновлялся и работал для галочки. Также проксировались соединения на мониторинг, 1С и некоторые другие внутренние сервисы для доступа к ним извне. На виртуалке внутри не было никакой защиты от ddos, внешняя, соответственно, тоже подключена не была. В этом не было необходимости. Ничего критичного там не стояло.
От мониторинга прилетел алерт на недоступность некоторых ресурсов, и на высокий LA виртуалки. По SSH хоть и небыстро, но подключился к ней. Заодно сразу зашёл на гипервизор. Он нормально переваривал нагрузку. Увидел, что на виртуалке CPU на четырёх ядрах в потолке. И все ядра нагрузил Nginx. Голым Nginx нагрузить практически пустыми соединениями на 100% 4 CPU не так просто. Я думал, что сейчас провайдер просто отрубит сервак и на этом всё закончится. Но нет, он переваривал, так что я стал разбираться на сервере локально.
Глянул лог Nginx и увидел массовые обращения на один конкретный URL публичного сайта с разных IP адресов. Вообще не понял, причём тут этот URL и почему в него долбят. Первое, что сделал, вообще отключил этот сайт. Nginx стал отдавать 502 ошибку, но серверу это слабо помогло.
Потом добавил параметр
limit_conn_zone $binary_remote_addr zone=perip:10m;в nginx.conf и
limit_conn perip 50;в настройки виртуального хоста. Хотел собирать айпишники тех, кто открывает более 50 соединений к сайту, чтобы потом их банить. Но там особо не собиралось, плюс лог ошибок рос с огромной скоростью, трудно было из него что-то выбирать. Виртуалка и так сильно тормозила. IP постоянно менялись, одновременных запросов, которые бы ловились Nginx, не было.
Решил мимо Nginx напрямую с iptables работать. У меня есть в закладках команда, которая сортирует и считает соединения с каждого IP адреса:
# netstat -ntu | awk '{print $5}' | grep -vE "(Address|servers|127.0.0.1)" | cut -d: -f1 | sort | uniq -c | sort -n| sed 's/^[ \t]*//'Тут уже было хорошо видно адреса, которые открыли много соединений. Немного изменил скрипт, чтобы выводить чистые списки IP адресов, открывших более 50-ти соединений и сохранять их в файл:
# netstat -ntu | awk '{print $5}' | grep -vE "(Address|servers|127.0.0.1)" | cut -d: -f1 | sort | uniq -c | sort -n| sed 's/^[ \t]*//' | awk '{if ($1 > 50 ) print$2}' > ~/top_connect.txtДальше создал список ipset для использования списка IP адресов в правилах iptables. Напрямую большие списки в iptables направлять не надо, он их может не переварить.
# ipset -N top_connect nethashЗакинул туда список пойманных ранее IP адресов:
# cat ~/top_connect.txt | xargs -n1 ipset -A top_connectИ сделал правило в iptables для блокировки из этого списка:
# iptables -I INPUT 1 -m set --match-set top_connect src -j DROPБлокировка заработала, счётчики правила пошли вверх, но помогло это слабо. Адреса постоянно менялись. Собрал всё это в скрипт и запускал по крону раз в минуту, тоже не помогло.
Решил забанить всех, кто обращается к урлу, который ддосят. Забирал IP ардеса, чтобы сильно не грузить сервак, так:
# tail -1000 /var/log/nginx/access.log | egrep "GET /url-for-ddos/" | awk '{print $1}' | sort -n | uniq -c | sort -n | tail -n100 | awk '{if ($1 > 2 ) print $2}' > ~/top_get.txtСобрал их в ipset, добавил правило блокировки:
# ipset -N top_get nethash
# iptables -I INPUT 1 -m set --match-set top_get src -j DROPПродолжение в следующей заметке 👇👇👇👇
#ddos #nginx #iptables
1👍107👎2
После прошлой истории с ddos захотелось проработать какое-то готовое универсальное решение, чтобы можно было его быстро применить, а не придумывать разные способы. В комментариях люди писали, что надо было установить fail2ban, какой-нибудь WAF или что-то в этом роде. Это всё слабо поможет, если идёт большая нагрузка. Fail2ban сразу мимо, забываем про него. А WAF или какой-то фильтрующий сервер надо настраивать заранее, а не когда у вас единственную машину ддосят.
Я взял наиболее простой и быстрый с точки зрения производительности вариант: ipset + iptables. Если ваш канал и сервер в целом вывозят нагрузку и вас не блокирует провайдер, указанная связка будет наиболее лёгкой и эффективной с точки зрения потребления ресурсов.
Сначала хотел что-то простое набросать, но потом всё расширял и расширял возможности. В итоге родился довольно большой bash скрипт с некоторыми проверками и логированием. Рассказываю, что он делает:
1️⃣ Проверяет установку ipset, создаёт списки.
2️⃣ Проверяет установку rsyslog, чтобы логировать заблокированные подключения. Это нужно на момент отладки и в обычное время, когда нет ддоса. Если начали ддосить, логирование надо отключить.
3️⃣ Создаёт конфигурацию rsyslog для хранения логов в отдельных файлах. Настраивает ротацию через logrotate.
4️⃣ Дальше идут переменные, касающиеся правил iptables: имя и ip адрес WAN интерфейса, белый список IP, с которых разрешено всё, разрешённые TCP и UDP порты, на которые мы принимаем соединения. Всё остальное блокируем.
5️⃣ Дальше идут наборы правил:
- очистка всех правил
- запрет всего, что не разрешено явно
- разрешаем установленные соединения
- разрешаем localhost и icmp
- разрешаем исходящие соединения сервера
- разрешаем все соединения от белого списка
- блокируем неопознанные и нулевые пакеты
- блокируем новые соединения без статуса NEW
- блокируем списки ipset, которые формируются ниже
- добавляем в список тех, кто открывает более 10-ти соединений с сервером в течении секунды, логируем таких товарищей
- разрешаем доступ к открытым портам, в данном примере это порты 80, 443 TCP и 443 UDP
- тех, кто обращается к другим портам, добавляем в список ipset
- сохраняю все правила в файл
Сразу скажу, что я не занимался плотной отладкой этого набора правил в реальной ситуации. Набросал правила на основе своего опыта и протестировал в ручном режиме. Под реальной нагрузкой и спамом запросов не проверял.
Для проверки работы надо установить на сервере iptables, ipset, rsyslog:
Скопировать и заполнить переменные в bash скрипте. Особое внимание уделить переменным WAN, WAN_IP, WLIST, WPORT_TCP, WPORT_UDP. На основе них будут сформированы правила iptables. Отдельного правила для SSH я не делал. Подразумевается, что подключаться куда-либо кроме открытых 80 и 443 портов можно только из списка WLIST. Туда можно добавлять IP адреса или подсети через запятую.
После выполнения скрипта, смотрим правила iptables:
Проверял работу так. Установил веб сервер. Попробовал с другой машины подключиться к серверу через telnet на любой отличный от HTTP порт:
Получил бан с занесением в список BANPORT. Смотреть этот список так:
Далее установил ab и попробовал спам запросов в 50 потоков к веб серверу:
Получил бан с занесением в список BANDDOS. Оба бана были отражены в лог файлах
⚡️На работающем сервере запускать такие скрипты не рекомендую, особенно если нет доступа к консоли. Сначала проверьте и отладьте на тестовой виртуалке. Убедитесь, что не отрубаете себе доступ. В целом, тут небольшой и относительно простой набор правил.
⇨ Забрать скрипт iptables.sh
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#iptables #ipset #ddos
Я взял наиболее простой и быстрый с точки зрения производительности вариант: ipset + iptables. Если ваш канал и сервер в целом вывозят нагрузку и вас не блокирует провайдер, указанная связка будет наиболее лёгкой и эффективной с точки зрения потребления ресурсов.
Сначала хотел что-то простое набросать, но потом всё расширял и расширял возможности. В итоге родился довольно большой bash скрипт с некоторыми проверками и логированием. Рассказываю, что он делает:
- очистка всех правил
- запрет всего, что не разрешено явно
- разрешаем установленные соединения
- разрешаем localhost и icmp
- разрешаем исходящие соединения сервера
- разрешаем все соединения от белого списка
- блокируем неопознанные и нулевые пакеты
- блокируем новые соединения без статуса NEW
- блокируем списки ipset, которые формируются ниже
- добавляем в список тех, кто открывает более 10-ти соединений с сервером в течении секунды, логируем таких товарищей
- разрешаем доступ к открытым портам, в данном примере это порты 80, 443 TCP и 443 UDP
- тех, кто обращается к другим портам, добавляем в список ipset
- сохраняю все правила в файл
Сразу скажу, что я не занимался плотной отладкой этого набора правил в реальной ситуации. Набросал правила на основе своего опыта и протестировал в ручном режиме. Под реальной нагрузкой и спамом запросов не проверял.
Для проверки работы надо установить на сервере iptables, ipset, rsyslog:
# apt install iptables ipset rsyslogСкопировать и заполнить переменные в bash скрипте. Особое внимание уделить переменным WAN, WAN_IP, WLIST, WPORT_TCP, WPORT_UDP. На основе них будут сформированы правила iptables. Отдельного правила для SSH я не делал. Подразумевается, что подключаться куда-либо кроме открытых 80 и 443 портов можно только из списка WLIST. Туда можно добавлять IP адреса или подсети через запятую.
После выполнения скрипта, смотрим правила iptables:
# iptables -L -v -nПроверял работу так. Установил веб сервер. Попробовал с другой машины подключиться к серверу через telnet на любой отличный от HTTP порт:
# telnet 85.143.173.182 23Получил бан с занесением в список BANPORT. Смотреть этот список так:
# ipset -L BANPORTДалее установил ab и попробовал спам запросов в 50 потоков к веб серверу:
# ab -c 50 -n 30000 "http://85.143.173.182/"Получил бан с занесением в список BANDDOS. Оба бана были отражены в лог файлах
ipset_portscan.log и ipset_ddos.log. При этом если ничего из описанного выше не делать, а просто ходить на веб сайт, доступ открыт, всё работает нормально.⚡️На работающем сервере запускать такие скрипты не рекомендую, особенно если нет доступа к консоли. Сначала проверьте и отладьте на тестовой виртуалке. Убедитесь, что не отрубаете себе доступ. В целом, тут небольшой и относительно простой набор правил.
⇨ Забрать скрипт iptables.sh
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#iptables #ipset #ddos
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍183👎2