На самом деле это вопрос из двух частей. Имейте в виду, что я разработчик, а не системный администратор, но будучи единственным сотрудником в компании, я ношу ВСЕ шляпы.
Я развернул свой сервер с двумя брандмауэрами, работающими на CARP для балансировки нагрузки / избыточности, плюс около 40 компьютеров для базы данных и других потребностей серверных приложений. В качестве стартапа я хочу сэкономить немного денег, уменьшив ущерб от DDoS-атаки, не платя своему интернет-провайдеру за выделенный бизнес-Интернет поверх защиты от DDoS. Я ЗНАЮ, что ВЫ ПОЛНОСТЬЮ НЕ МОЖЕТЕ защитить от DDoS. Я просто хочу уменьшить убытки до тех пор, пока мое приложение не начнет зарабатывать деньги, и тогда я могу позволить интернет-провайдеру разобраться с головной болью.
В этом духе мне было интересно, реализовал ли кто-нибудь когда-нибудь решение, где скрипт (возможно, через cron) изменяет правила PF в зависимости от текущего использования. Например, если существует слишком много полуоткрытых соединений с миллионов IP-адресов, я хотел бы сказать PF перейти в режим SYN-Cookies, а затем, когда атака закончится (или прошло некоторое время), вернуться в нормальное состояние.
Я не могу использовать Cloudfare, потому что я использую серверную часть для приложения и 99% контента не статичны. Я мог бы сделать облачные вычисления для веб-сайта приложения, но это все.
Повторяю, деньги - ЭТО ВОПРОС. В настоящее время я использую FIOS Business, и Verizon не будет обеспечивать защиту от DDoS-атак на линии такого типа.
И последнее: испытывал ли кто-нибудь серьезные проблемы после включения SYN-COOKIES / SYN-PROXYING. Расскажи мне настоящую историю. Пожалуйста.
PS Я не хочу начинать дискуссию о SYN-PROXYING vs SYN-COOKIES!
Поскольку никто не ответил на мой вопрос, это конфигурация pf, с которой я столкнулся. В частности, посмотрите на строку для установки файлов cookie после заполнения таблицы 15% открытых TCP-соединений. SYN-файлы cookie дают большую отдачу, когда дело доходит до предотвращения слишком большого количества полуоткрытых соединений. Однако это не окончательно. Еще одна вещь, которую вы можете сделать в своей собственной среде, - это ограничить количество icmp на внешнем интерфейсе, скажем, 1000 в секунду. Это то, с чем мне еще предстоит поиграть. Просто не ограничивайте его внутри своей сети, так как это может иметь разрушительные последствия.
таблица bogons и таблица USA часто обновляются. Каждые 4 и 24 часа соответственно. ЭТО ОБЯЗАТЕЛЬНО, так как многие IP-адреса, особенно ipv6, сегодня не используются. Так зачем вообще с ними обращаться. Кроме того, никому за пределами США не требуется доступ через SSH.
Существует также пара таблиц попыток перебора, которые мои приложения обновляют извне, а ssh обновляется в pf. На всякий случай, если кто-то пытается попытаться установить слишком много соединений одновременно, он явно пытается что-то теневое.
Это не была моя окончательная конфигурация, так как я выполнял балансировку нагрузки для своих веб-серверов и других вещей, но не хотел публиковать слишком много ненужной информации.
последнее замечание, всегда пытайтесь запустить carp для переключения / резервирования / балансировки нагрузки !!
# Macros
udp_services = "{ domain, ntp }"
tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s }"
carpdevs = "carp0"
ext_if = "em0"
int_if = "{ em1, em2, em3, em4, em5 }"
localnet = "{ em1:network, em2:network, em3:network, em4:network, em5:network}"
table <USA_IP_ADDRESSES> persist file "/etc/usa_all_ip.zone"
table <dhcpd_leased_ips> persist
table <dhcpd_abandoned_ips> persist
table <dhcpd_changed_ips> persist
table <bruteforce> persist
table <bogons> persist file "/etc/bogons" # see cron jobs for when this file gets updated (daily) and from where
table <lan> const { 192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24, 192.168.4.0/24, 192.168.5.0 }
table <webservers> persist { 192.168.4.10, 192.168.4.20 }
table <websiteoverload> persist
table <appoverload> persist
table <mysmateservers> persist
# Global settings
set debug warning
set limit { states 10000000, table-entries 1000000}
set optimization aggressive
set syncookies adaptive (start 15%, end 8%)
set timeout tcp.established 1800
set skip on lo
set loginterface em0
# Default everything coming in + antispoof
antispoof for $ext_if inet
antispoof for $int_if inet
antispoof for carp0 inet
block drop all
block drop in quick on $ext_if from { <bogons>, <bruteforce> }
# Allow traffic from all our CARP devices
pass on $carpdevs proto carp
# Allow connections between all of our intrefaces
pass from { self, $localnet }
#block drop in on $ext_if from carp0:network
# block all outgoing traffic through em0 coming from em2-em5 and don't bother testing other rules
block return out on egress proto { tcp, udp} from 192.168.0.0/16
# pass out clock synchronization
pass out on egress proto udp from 192.168.0.0/16 to port ntp
# pass out dns look up
pass out on egress proto { udp, tcp } from 192.168.0.0/16 to port domain
pass out on egress from 192.168.1.0/24
pass out on egress from 192.168.5.0/24
pass out log on egress from 192.168.2.0/24
match out on $ext_if inet from 192.168.0.0/16 nat-to (carp0) # NAT, match IPv4 only
# ICMP related rules -- See The PF Book Chapter 3
icmp_types = "{ echoreq, unreach }"
icmp6_types = "{ echoreq unreach timex paramprob }"
pass inet proto icmp icmp-type $icmp_types #max-pkt-rate 100/1
pass inet6 proto icmp6 icmp6-type $icmp6_types # max-pkt-rate 100/1
# Allow default port range for traceroute(8) 64*3 - Reference: The PF Book Chapter 3
pass out on egress inet proto udp to port 33433:33626 # For IPv4
pass out on egress inet6 proto udp to port 33433:33626 # For IPv6
# Allow incoming SSH connections from US IP addresses only
pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port ssh modulate state \
(max-src-conn 50, max-src-conn-rate 10/1, overload <bruteforce> flush global)
# Allow incoming traffic on http,https and forward it to our web_server computer
pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port https rdr-to 192.168.5.5 keep state \
(max-src-conn-rate 100/1, overload <websiteoverload>)
pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port 58777 rdr-to <mysmateservers> least-states modulate state \
(max-src-conn-rate 1000/1, overload <appoverload>)
# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010
# Port build user does not need network
block return out proto {tcp udp} user _pbuild