Некоторые рассуждения о защите от ddos на примере защиты от SSL denial of service attack
Как многие слышали, недавно был представлен эксплойт, который поможет вам погасить любую машинку с SSL, торчащим наружу.
Я бы сегодня хотел немного порассуждать на тему того, как защищаться от подобных атак (заранее, само собой). Заодно я вам расскажу о том, как рассуждает любой системный администратор, защищаясь от dos/ddos атаки.
Для того, чтобы отразить любую dos/ddos атаку существует обычно 6 способов:
1) увеличить мощности (в таком случае, мощности ботнета может не хватить для успешной атаки. Плохой способ в принципе, но помогает при простых атаках (GET / HTTP/1.1\nHost: bla blabla\n\n, например).
2) увести атаку в сторону (например, совсем недавно, у меня атаковали один из сайтов. Атаковали дергая главную страницу. Здраво рассудив, что потеря главной страницы - не потеря всего сервиса, я nginx'ом спроксировал запросы на другой сервер. Он выстоял кстати, в конечном счете. Но рассчет был на то, что в спокойной обстановке я избавлюсь от атаки через ipfw).
3) сделать атаку невыгодной, значительно повысив нагрузку на клиент (в случае с SSL этот метод может сработать, как раз)
4) отключить проблемную часть сервиса в ущерб функциональности.
5) ограничить количество одинаковых запросов от одного хоста (очень плохо помогает, когда хостов много)
6) в реальном времени блокировать файрволлом атакующих, распознавая их по общим признакам (прекрасный способ, если у вас FreeBSD или iptables+ipset. Поставленный впереди сервера BSD-шлюз поможет вам отразить почти любую атаку (ну кроме UDP-флуда объёмом большим, чем канал)).
Рассмотрим применимость всего этого к указанному в заголовке типу атаки.
Во-первых, немного о самой атаке. Использует она механизм SSL/TLS renegotiation. Было бы некрасиво пытаться его перевести.
Проверить, уязвим ли ваш хост, можно выполнив команду: openssl s_client -connect host:443
После того, как вы получите сертификат - нажмите shift+R, потом Enter. Если ваш хост поддерживает данный механизм - то соединение останется "живым". В противном случае вас выбросит в консоль (потренироваться можно на gmail.com, у них этот механизм отключен).
Теперь по порядку.
1) Увеличение мощности здесь бесполезно. Даже самый маленький ботнет сейчас составляет не менее 1000 хостов. Обмен здесь идет 1 на 1 - 1 атакующий на 1 сервер (если у вас не 48 поточные монстры с 196+ памяти).
2) Увести атаку в сторону. Эффективный способ, если вы не так страшитесь потери SSL. Направляем при помощи rinetd 443 порт в виртуалку (которая упрется в ограничение по процессору и памяти) и пусть по возможности отплевывается и проксирует запросы к нашему вебсерверу. Ну или даже отвести атаку на другую машину физическую. LXC вам в помощь.
3) Сделать атаку невыгодной. Это может помочь при маленьком ботнете или одном атакующем. Например, RSA ключик в 4096 бит требует от сервера примерно в 25 раз больше затрат CPU, чем от клиента. А при DHE-DSS-AES256-SHA сервер потратит в 2 раза меньше процессорного времени, чем клиент. Тогда клиент с Core Quad никогда не повалит ваш i7.
4) Отключить проблемную часть сервиса. Насколько я помню, renegotiation отключен в openssl 0.9.81. Могу быть неправ - если будете использовать этот вариант - проверьте. Nginx, по идее, также не поддерживает данную фичу в текущем релизе (1.х). Но опять же - проверяйте.
5) Ограничить количество одинаковых запросов. В нашем случае - это SSL handshake. Вот тут приведены примеры того, как ограничить или заблокировать через iptables этот механизм.
6) Тут уже сами фантазируйте. Я обычно скармливаю лог вебсервера самописным скриптам, которые идут на шлюз и пишут там правила в ipfw. Реже - в ipset кормлю ip-адреса.