Дано:
• Крупная корпоративная сеть на базе разнообразных железок Cisco с развернутым MPLS/VPN.
• PI блок адресов /22, в котором есть незанятая сеть /24, BGP пиринг с провайдерами.
• Несколько доступных из интернета ресурсов, падение которых несет либо репутационные, либо прямые финансовые потери. Соответственно, есть риск атаки на них, а каналы в интернет хоть и широкие, но вовсе не резиновые. В нормальной ситуации трафик от/до этих ресурсов копеечный, несколько мегабит.
• Некий очень ленивый сетевик, который не хочет, чтобы его будили посреди ночи из-за каких-то там атак.
Требуется подготовить сеть к тому, чтобы при атаке трафик мгновенно перемаршрутизировало через одну из компаний, предоставляющих защиту от DDoS.
Disclaimer. Все дальнейшее содержит массу искажений по разнообразным деталям, но сама архитектура осталась неизменной. Я буду много касаться вопроса настройки маршрутизации, и совсем не буду рассматривать защиту management plane сетевого оборудования от приставаний со стороны угнанного кем-то дырявого вебсервера.
Для начала, необходимо ответить на следующий вопрос: каким образом защищаться?
• Любые механизмы, реализуемые внутри сети, могут помочь от исчерпания ресурсов сервера, но каналы в интернет они не спасут. 10гб/с UDP флуд – и мы отрезаны от внешних сетей.
• BGP blackholing и иже с ним? Ну да, каналы спасены, вот только цель атаки выполнена – интернет-ресурсы лежат. Не годится.
• Заказать услугу защиты от DDoS у провайдера? Не вопрос. Но: качество фильтрации у них обычно не самое лучшее, да и будут проблемы с BGP multihoming’ом. Любой трафик, ходящий через канал провайдера с включенным antiDDOS’ом, должен быть симметричен. Сейчас у нас примерно равномерная загрузка всех интернет-каналов, а придется либо бросить вообще всё на один канал (нагрузка станет высокой даже без всяких атак, придется увеличивать его емкость), либо оставить на нем только защищаемые ресурсы (нагрузка станет почти нулевая). Некрасиво. Мне очень хочется, чтобы защита от DDoS никак не влияла на работу других ресурсов и периметров.
• Использование услуг сторонней организации. Они отслеживают нагрузку на сервера, в случае обнаружения атаки щелкают пальцами, и трафик от/до наших серверов начинает ходить через них. Под «щелчком» может пониматься либо изменение DNS записи (очень медленно, да и вообще убого), либо анонс через них защищаемой сети (быстро и безотказно, но требует предварительной подготовки).
Мы остановились на последнем варианте.
В ходе совещания с представителями организации, предоставляющей защиту от DDoS атак (все ее знают, не хочется их пиарить, потому назовем их «Защитниками») выяснилось, что у нас с ними нет общих точек присутствия, потому придется поднимать BGP пиринг через GRE туннели по интернету, и через них принимать/отдавать трафик защищаемых ресурсов. На этом этапе я сначала немного обалдел: «Так мы же и защищаем интернет-каналы. Если их завалили, то мы, получается, остаемся и без защиты?». Оказалось, своя логика в такой архитектуре есть. Атака не выйдет на максимальную мощность мгновенно, минут 5-10 от начала атаки до блэкаута у нас будет, да и в любом случае ничто не мешает Защитникам создать анонс на сеть и без нашего участия.
Сеть, которую мы им анонсируем, не может быть меньше, чем /24, иначе магистральщики легко могут ее прибить.
Ах да, чуть не забыл. Мы предоставляем Защитникам сервер, расположенной внутри нашей сети. Они ставят на него свои анализаторы, а мы средствами SPANа сливаем на один из его интерфейсов копию всего трафика защищаемых сервисов. То есть они будут отвечать за обнаружение атак.
Итак, переходим к самой интересной части, а именно: надо все настроить так, чтобы переключение осуществлялось лишь силами Защитников, после устного «ok» со стороны сотрудника службы безопасности, и совсем без участия сетевиков. А еще это переключение не должно задеть другие внешние и внутренние ресурсы.
Вот принципиальная топология сети. На стыке между всеми периметрами размещен файрвол Cisco ASA (занимается NATом и фильтрацией трафика по ACL), имеются пограничные маршрутизаторы, между ними и файрволом L2 свитч.
Первый вопрос: откуда тянуть GRE туннели до Защитников? Казалось бы, самый логичный ответ – «через пограничные BGP маршрутизаторы». Но мне этот вариант не нравится. Ведь в туннели нужно будет пускать только защищаемый трафик, все остальные пакеты должны будут лететь по старинке. Надо сделать так, чтобы для разных отправителей пакетов действовали разные правила маршрутизации. MPLS, разумеется, не тянется до пограничных маршрутизаторов, потому остается только вариант с Policy-based routing. Я к нему отношусь примерно так же, как мои бывшие преподаватели по разного рода программированиям относились к оператору «GOTO», то есть в моей сети никакого PBR не будет.
ASA тоже не отличается избирательностью по отношению к отправителям пакетов, потому получается, что маршруты должны меняться где-то внутри сети. Следовательно, нужно будет создать отдельный VRF. И понадобится какая-то отдельная железка, один из интерфейсов которой мы высадим аккурат между файрволом и пограничными маршрутизаторами (не высовывать же ядро сети наружу?). От нее не потребуется какого-либо инспектирования трафика выше L4 (Защитники этим займутся), да и на L4 ничего кроме аксесс-листов не нужно. Какое устройство поддерживает BGP, GRE и сможет прокачать через себя ровно столько трафика, сколько ему дать, и при этом стоит недорого? Правильно, идем на склад и берем лишний свитч Cisco Catalyst 3750 на 24 медных гигабитных порта и 4 SFPшных аплинка.
Размещаем его в сети, и планируем, как пойдет трафик в нормальной ситуации (зеленый цвет) и под атакой (красный).
У внимательного читателя сразу возникнет вопрос: а кто будет NATить пакеты до серверов и обратно? Ведь 3750-й каталист не поддерживает эту фичу… Ответ: «никто». Разве кто-то говорит, что NAT обязательно требуется? Что-то мешает сразу назначить внешний адрес интерфейсу сервера? Ведь в таком подходе есть одно радикальное преимущество: при мощном SYN флуде нашей ASA может сильно поплохеть, а, сняв с нее задачу NATа, мы здорово экономим ее ресурсы. Ну и вдобавок, после переключения в режим защиты трафик до атакуемых серверов вообще не проходит через ASA – а ведь существенную долю в нем может составлять мусор.
Кстати о ресурсах. Отключаем к чертовой бабушке поднятый на пограничных маршрутизаторах Netflow. Да, сейчас у них ЦПУ в пике загружен от силы до 10%, но они легко могут скопытиться от банальных 100мб/с SYN пакетов, надо беречь их силы.
Как же все-таки будет осуществляться переключение? У нас есть, допустим, PI AS 11111 с сетью 198.51.100.0/22. В ней, как уже говорилось выше, свободна одна сеть /24, пусть это будет 198.51.103.0/24. В час «Ч» Защитники выпускают наружу принимаемый от нас анонс на 198.51.103.0/24, а нам выдают маршрут на 0.0.0.0/0 через один из GRE туннелей. Или через несколько – тогда MED скажет, каким пользоваться.
Поехали настраивать.
Сначала sw-ddos:
Sw-ddos(config)# !Делаем интерфейс до Core: interface GigabitEthernet1/0/25 no switchport ip address 169.254.0.2 255.255.255.252 !готовим входящий ACL для интерфейса, по которому должен ходить только GRE трафик: ip access-list extended fromoutside_phy permit gre host 100.0.0.1 host 198.51.101.10 permit gre host 100.1.0.1 host 198.51.101.10 permit gre host 100.2.0.1 host 198.51.101.10 permit gre host 100.3.0.1 host 198.51.101.10 !Сам интерфейс: Interface GigabitEthernet1/0/24 no switchport ip address 198.51.101.10 255.255.255.0 ip access-group fromoutside_phy in !Входящий ACL для туннелей: ip access-list extended fromoutside permit tcp host 10.10.0.1 host 10.10.0.2 eq bgp permit tcp host 10.10.0.1 eq bgp host 10.10.0.2 permit tcp host 10.10.0.5 host 10.10.0.6 eq bgp permit tcp host 10.10.0.5 eq bgp host 10.10.0.6 permit tcp host 10.10.0.9 host 10.10.0.10 eq bgp permit tcp host 10.10.0.9 eq bgp host 10.10.0.10 permit tcp host 10.10.0.13 host 10.10.0.14 eq bgp permit tcp host 10.10.0.13 eq bgp host 10.10.0.14 permit tcp any host 198.51.103.5 eq www !Сами туннели: interface Tunnel1 ip address 10.10.0.2 255.255.255.252 ip access-group fromoutside in tunnel source GigabitEthernet1/0/24 tunnel destination 100.0.0.1 interface Tunnel2 ip address 10.10.0.6 255.255.255.252 ip access-group fromoutside in tunnel source GigabitEthernet1/0/24 tunnel destination 100.1.0.1 interface Tunnel3 ip address 10.10.0.10 255.255.255.252 ip access-group fromoutside in tunnel source GigabitEthernet1/0/24 tunnel destination 100.2.0.1 interface Tunnel4 ip address 10.10.0.14 255.255.255.252 ip access-group fromoutside in tunnel source GigabitEthernet1/0/24 tunnel destination 100.3.0.1 !Чуть не забыл маршруты до GRE ендпоинтов со стороны Защитников – пусть будет статика, указывающая на пограничный маршрутизатор: ip route 100.0.0.1 255.255.255.255 198.51.101.1 ip route 100.1.0.1 255.255.255.255 198.51.101.1 ip route 100.2.0.1 255.255.255.255 198.51.101.1 ip route 100.3.0.1 255.255.255.255 198.51.101.1 !Ну и лупбек – чтобы достучаться до этого свитча: interface Loopback0 ip address 192.168.0.15 255.255.255.255 !Роут-мапы для BGP, фильтрующие обмен префиксами с Защитниками: ip prefix-list from_Def seq 5 permit 0.0.0.0/0 ip prefix-list to_Def seq 5 permit 198.51.103.0/24 !(ибо мы хотим принимать от них только дефолтный маршрут, а отдавать – только целевую /24 сеть) route-map from_Def permit 10 match ip address prefix-list from_Def route-map to_Def permit 10 match ip address prefix-list to_Def !А вот дальше уже роут-мапы для внутреннего пиринга с ядром сети route-map from_Inside deny 10 match ip address prefix-list from_Def !режем на корню дефолтный маршрут route-map from_Inside permit 20 !остальное разрешаем !Сам BGP (в той же AS, что и пограничные маршрутизаторы): router bgp 11111 no auto-summary bgp log-neighbor-changes !Защитники могут MEDом указывать нам, через какой туннель идти, потому: bgp deterministic-med bgp bestpath med missing-as-worst !анонсируем лупбек network 192.168.0.15 mask 255.255.255.255 !Создаем summary на защищаемую сеть – у нас ведь будет несколько сетей из доступного блока /24 aggregate-address 198.51.103.0 255.255.255.0 summary-only !Сам пиринг: neighbor DEF peer-group neighbor DEF remote-as 2222 neighbor DEF timers 20 60 neighbor DEF soft-reconfiguration inbound neighbor DEF route-map from_DEF in neighbor DEF route-map to_DEF out neighbor INSIDE peer-group neighbor INSIDE remote-as 65000 neighbor INSIDE soft-reconfiguration inbound neighbor INSIDE route-map from_Inside in neighbor 10.10.0.1 peer-group DEF neighbor 10.10.0.5 peer-group DEF neighbor 10.10.0.9 peer-group DEF neighbor 10.10.0.13 peer-group DEF neighbor 169.254.0.1 peer-group INSIDE
С sw-ddos закончили. Переходим к ядру.
Core(config)# !Делаем VRF ip vrf DDOS rd 10:10 route-target both 10:10 !Создаем статические маршруты из VRF в сторону ASA как для доступа к внутренним ресурсам, так и для маршрутизации в интернет в обычной ситуации. ip route vrf DDOS 0.0.0.0 0.0.0.0 172.31.0.1 250 ip route vrf DDOS 10.0.0.0 255.0.0.0 172.31.0.1 ip route vrf DDOS 172.16.0.0 255.240.0.0 172.31.0.1 ip route vrf DDOS 192.168.0.0 255.255.0.0 172.31.0.1 !Да, маршрут на 0.0.0.0/0 имеет метрику 250 – нужно, чтобы внезапно пришедший от sw-ddos BGP маршрут на тот же префикс мог перекрыть статику. !Нужны route-map’ы для BGP. Мы можем принять от sw-ddos только дефолтный маршрут, или маршрут на лупбек. Для принятого маршрута ставим большой Local Preference, ведь мы будем создавать анонс на 0.0.0.0/0 локально, и надо, чтобы маршрут от Защитников, как только он прилетит, был сильнее: ip prefix-list from-def seq 5 permit 0.0.0.0/0 ip prefix-list from-def seq 10 permit 192.168.0.15/32 route-map from-def permit 5 match ip address prefix-list from-def set local-preference 200 !А еще мы выдадим тому свитчу полный комплект маршрутов на приватные сети. В принципе, только для management целей. ip prefix-list private-nets seq 5 permit 10.0.0.0/8 ip prefix-list private-nets seq 10 permit 192.168.0.0/16 ip prefix-list private-nets seq 15 permit 172.16.0.0/12 route-map to_bgp_ddos permit 5 match ip address prefix-list private-nets !Теперь BGP. Он исключительно внутренний, потому AS приватная. Пиринг со свитчем мы поднимаем исключительно внутри VRF. router bgp 65000 address-family ipv4 vrf DDOS redistribute static route-map to_bgp_ddos neighbor 169.254.0.2 remote-as 11111 neighbor 169.254.0.2 activate neighbor 169.254.0.2 soft-reconfiguration inbound neighbor 169.254.0.2 route-map from-def in no synchronization network 0.0.0.0 !А вот это – адресация одного из VLANов. Все помнят, что площадок может быть несколько, и мы не хотим транжирить узкое адресное пространство? network 198.51.103.0 mask 255.255.255.240 !И надо бы анонсировать линк до ASA, чтобы гипотетическим iBGP пирам выдавать next hop'ом сразу адрес ASA. network 172.31.0.0 mask 255.255.255.248 !Ах да, забыли про интерфейс до sw-ddos: interface GigabitEthernet2/0/6 no switchport ip address 169.254.0.1 255.255.255.252 !Напоследок, создадим VLAN, в котором окажутся сервера: interface Vlan500 ip vrf forwarding DDOS ip address 198.51.103.0 255.255.255.240
Всё сделано. Осталось лишь посмотреть, как все это выглядит. Вот когда все хорошо:
Core#show ip bgp vpnv4 vrf DDOS BGP table version is 19376, local router ID is 192.168.0.16 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 10:10 (default for vrf DDOS) *> 0.0.0.0 172.31.0.1 0 100 0 i *> 10.0.0.0 172.31.0.1 0 100 0 ? *> 198.51.103.0/28 0.0.0.0 0 11111 i *> 172.16.0.0/12 172.31.0.1 0 100 0 ? *> 192.168.0.0/16 172.31.0.1 0 100 0 ? *> 192.168.0.15/32 169.254.0.2 0 200 0 11111 i
sw-ddos#show ip bgp BGP table version is 136, local router ID is 192.168.0.15 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, x best-external Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 10.0.0.0 169.254.0.1 0 0 65000 ? s 198.51.103.0/28 169.254.0.1 0 0 65000 i *> 198.51.103.0/24 0.0.0.0 4294967295 11111 i *> 172.16.0.0/12 169.254.0.1 0 0 65000 ? *> 172.31.0.0/29 169.254.0.1 0 0 65000 i *> 192.168.0.0/16 169.254.0.1 0 0 65000 ? *> 192.168.0.15/32 0.0.0.0 0 11111 i
Вроде все готово, пора приступать к тестированию. Защитники выдают нам маршрут на 0.0.0.0/0 и выпускают от себя наружу полученный от нас 198.51.103.0/24 (я, кажется, забыл упомянуть, что мы должны внести соответствующую запись в RIPE, иначе магистральщики не примут от них префикс). С 10.10.0.5 прилетел маршрут с MED 50, а от 10.10.0.1 MEDа вообще не было, потому «bgp bestpath med missing-as-worst» поставил там нечто большое и страшное.
sw-ddos#show ip bgp BGP table version is 9, local router ID is 192.168.0.15 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, x best-external Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path * 0.0.0.0 10.10.0.1 4294967295 0 2222 i *> 10.10.0.5 50 0 2222 i *> 10.0.0.0 169.254.0.1 0 0 65000 ? s> 198.51.103.0/28 169.254.0.1 0 0 65000 i *> 198.51.103.0/24 0.0.0.0 4294967295 11111 i *> 172.16.0.0/12 169.254.0.1 0 0 65000 ? *> 192.168.0.0/16 169.254.0.1 0 0 65000 ? *> 192.168.0.90/32 0.0.0.0 0 11111 i
А вот как оно долетело до ядра:
core#show ip bgp vpnv4 vrf DDOS BGP table version is 19312, local router ID is 192.168.0.16 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 10:10 (default for vrf DDOS) *> 0.0.0.0 169.254.0.2 0 200 0 11111 2222 i *> 10.0.0.0 172.31.0.1 0 100 0 ? *> 198.51.103.0/28 0.0.0.0 0 11111 i *> 172.16.0.0/12 172.31.0.1 0 100 0 ? *> 192.168.0.0/16 172.31.0.1 0 100 0 ? *> 192.168.0.15/32 169.254.0.2 0 200 0 11111 i
Проверка через несколько произвольных looking glass показала, что общее время расхождения маршрута – от полутора до двух минут. Разумеется, в течение этого времени снаружи будут недоступны абсолютно все ресурсы, размещенные в сети 198.51.103.0/24. Причина проста: мы принимаем маршрут на 0.0.0.0/0 мгновенно, а интернет узнает о 198.51.103.0/24 не сразу. Внешний пользователь отправляет SYN, тот пролетает через ASA (она это отмечает в таблице соединений) и попадает на сервер. Тот отзывается SYN ACK, который успешно промахивается мимо ASA, улетая через туннель. И когда клиент возвращает ACK, ASA успешно дропает этот пакет. Но две минуты – это не два часа, такое время простоя сервисов в исключительных ситуациях (например, при DDoS атаке...) допустимо.
Подведем итоги и рассмотрим преимущества и недостатки выбранной архитектуры.
Преимущества:
• Безграничная масштабируемость. Парой команд можно разместить VLAN с защищаемыми ресурсами на любой площадке. Можно легко добавить новые устройства, терминирующие GRE туннели до провайдеров. Можно резервировать линки от них до нескольких маршрутизаторов ядра без малейшего усложнения конфигурации.
• Максимальная защита ресурсов сетевых устройств от атак.
• Простота и надежность архитектуры.
• Отсутствие необходимости будить сетевика в момент начала атаки (формально – сведение к минимуму риска человеческой ошибки).
Недостатки:
• Нет сокрытия внутренней адресации защищенного от DDOS атак VRFа. Критичность этого оцениваю как примерно нулевую. В обычном DMZ продолжает использоваться NAT. Между DMZ и DDOS сегментами доступ ограничивается ASA. Ну узнают, что у нескольких публикуемых наружу ресурсов нет отдельных внутренних адресов – и что?
• А что будет, если атаковать начнут ресурсы, не размещенные в VRF DDOS? Правильно, им поплохеет вместе с каналами. Но на этот случай разработан отдельный план действий, о котором я рассказывать не буду, потому что он подразумевает наличие острого ножа и как-то связан с японским словом «харакири».
• После переключения на пару минут ломаются вообще все сервисы, расположенные в защищенной сети.
• Администраторы серверов по три раза переспрашивают, какой внутренний адрес надо ставить, и только потом до них доходит.
Автор: JDima