В Сети можно найти множество разных статей, описывающих Unicast Reverse Path Forwarding (uRPF) и два его режима: strict и loose. Как правило, авторы делают основной акцент на разнице поведения двух режимов; однако причина существования двух разных режимов обычно остаётся за рамками обсуждения, по крайней мере по результатам поиска в Google по словам “loose vs strict uRPF”. Сегодня я бы хотел исправить эту досадную оплошность и явным образом описать связь loose uRPF с пока ещё неизвестной нам функцией.

Перед тем, как обсуждать, чем же именно отличаются два режима и почему, стоит в общих чертах вспомнить предназначение функции-прародителя. RPF родом из мира multicast, где она предотвращает возникновение петель на уровне data plane: она сравнивает адрес источника IP пакета и содержимое RIB; если входящий интерфейс пакета совпадает с исходящим интерфейсом в сторону источника пакета, то проверка успешно пройдена и пакет можно слать дальше; в противном случае обнаружена петля, поэтому пакет необходимо отбросить. Unicast RPF основана на той же идее – она проверяет, что unicast пакет приходит с верного направления. Strict uRPF работает так же, как её визави из мира multicast; loose uRPF немного отличается: для успешного прохождения проверки достаточно лишь наличия маршрута, совпадение интерфейса необязательно. Впрочем, из этого краткого описания есть существенное исключение: если исходящий интерфейс до адреса отправителя – Null0, то такой пакет следует отбросить. Cisco, помимо описания loose uRPF, упоминает и сценарий её применения:

To provide ISPs with a DDoS resistance tool on the ISP-to-ISP edge of a network, Unicast RPF was modified from its original strict mode implementation to check the source addresses of each ingress packet without regard for the specific interface on which it was received. This modification is known as “loose mode.”

Вольный перевод: чтобы предоставить ISP механизм борьбы с DDoS на границе их сети, реализация Unicast RPF была изменена таким образом, чтобы проверять адрес источника каждого пакета независимо от того, через какой интерфейс этот пакет был получен. Эта модификация известна как “loose mode”.

Security Configuration Guide: Unicast Reverse Path Forwarding, Cisco IOS XE 17 (Cisco ASR 920 Routers)

Защита от DDoS на границе ISP – звучит знакомо, не правда ли? Это действительно задача Remotely Triggered Blackhole (RTBH). Destination-based RTBH использует BGP community, таким образом извещая провайдера об атакованных адресе или сети, чтобы провайдер мог заблокировать соответствующий вредоносный трафик. Очевидно, что при таком подходе под раздачу попадёт и легитимный трафик. Было бы недурно иметь возможность блокировать трафик на основе IP адреса атакующего вместо адреса жертвы, не так ли? Именно тут на сцену и выходит source-based RTBH: если добавить loose uRPF к схеме destination-based RTBH, появляется возможность пометить IP адрес злоумышленника c помощью тех же BGP community, тем самым отправляя вредоносный трафик в небытие. На просторах интернета есть неплохая статья про RTBH, описывающая реализацию решения на основе IOS XR.

Disclaimer: далее в статье не будет никаких существенных откровений, поэтому в случае, если читатель уже проникся идеей, он может спокойно пропустить оставшийся текст.

Построим простую топологию для тестирования loose uRPF в рамках RTBH:

Сеть ISP состоит из 2 PE-маршрутизаторов, находящихся в одной BGP AS. CE1 и CE2 – маршрутизаторы заказчиков, использующие eBGP для обмена маршрутной информацией с провайдером. Важное замечание: IOS XE требует, чтобы eBGP сосед и next-hop полученных от него маршрутов были доступны через один и тот же физический интерфейс; в противном случае маршруты считаются inaccessible. Впрочем, обойти эту досадную помеху несложно – достаточно команды disable-connected-check на PE, осуществляющем подмену next-hop. Ниже базовые настройки адресации и маршрутизации:

CE1#show run | section interface|router|ip route
interface Loopback0
 ip address 3.3.3.3 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.13.3 255.255.255.0
router bgp 3
 bgp router-id 3.3.3.3
 no bgp default ipv4-unicast
  neighbor 192.168.13.1 remote-as 12
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255
  neighbor 192.168.13.1 activate
  neighbor 192.168.13.1 send-community both
CE2#show run | section interface|router
interface Loopback0
 ip address 4.4.4.4 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.24.4 255.255.255.0
router bgp 4
 bgp router-id 4.4.4.4
 no bgp default ipv4-unicast
 neighbor 192.168.24.2 remote-as 12
 address-family ipv4
  network 4.4.4.4 mask 255.255.255.255
  neighbor 192.168.24.2 activate
  neighbor 192.168.24.2 send-community both
PE1#show run | section interface|router    
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
 ip ospf 1 area 0
interface FastEthernet0/0
 ip address 192.168.13.1 255.255.255.0
interface FastEthernet1/0
 ip address 192.168.12.1 255.255.255.0
 ip ospf 1 area 0
router ospf 1
 router-id 1.1.1.1
router bgp 12
 bgp router-id 1.1.1.1
 no bgp default ipv4-unicast
 neighbor 2.2.2.2 remote-as 12
 neighbor 2.2.2.2 update-source Loopback0
 neighbor 192.168.13.3 remote-as 3
 neighbor 192.168.13.3 disable-connected-check
 !
 address-family ipv4
  redistribute connected
  neighbor 2.2.2.2 activate
  neighbor 2.2.2.2 send-community both
  neighbor 192.168.13.3 activate
  neighbor 192.168.13.3 send-community both
PE2#show run | section interface|router
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
 ip ospf 1 area 0
interface FastEthernet0/0
 ip address 192.168.24.2 255.255.255.0
interface FastEthernet0/1
 ip address 192.168.25.2 255.255.255.0
interface FastEthernet1/0
 ip address 192.168.12.2 255.255.255.0
 ip ospf 1 area 0
router ospf 1
 router-id 2.2.2.2
router bgp 12
 bgp router-id 2.2.2.2
 no bgp default ipv4-unicast
 neighbor 1.1.1.1 remote-as 12
 neighbor 1.1.1.1 update-source Loopback0
 neighbor 192.168.24.4 remote-as 4
 neighbor 192.168.25.5 remote-as 5
 !
 address-family ipv4
  redistribute connected
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 send-community
  neighbor 192.168.24.4 activate
  neighbor 192.168.24.4 send-community both
  neighbor 192.168.25.5 activate
  neighbor 192.168.25.5 send-community both
Attacker#show run | section interface|router
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
interface FastEthernet0/1
 ip address 192.168.25.5 255.255.255.0
router bgp 5
 bgp router-id 5.5.5.5
 no bgp default ipv4-unicast
 neighbor 192.168.25.2 remote-as 12
 address-family ipv4
  network 5.5.5.5 mask 255.255.255.255
  neighbor 192.168.25.2 activate
  neighbor 192.168.25.2 send-community both

Вначале реализуем destination-based RTBH. Пусть BGP community 12:666 является маркером для трафика, который следует отбросить через Null0.

PE1#show run | s ip route|ip community|ip bgp|route-map|router bgp
router bgp 12
 address-family ipv4
  neighbor 192.168.13.3 route-map RTBH in
ip bgp-community new-format
ip community-list standard RTBH permit 12:666
ip route 10.0.0.0 255.255.255.255 Null0
route-map RTBH permit 10
 match community RTBH
 set local-preference 200
 set ip next-hop 10.0.0.0
route-map RTBH permit 20
PE2#show run | s ip route|ip community|ip bgp|route-map|router bgp
router bgp 12
 address-family ipv4
  neighbor 192.168.24.4 route-map RTBH in
  neighbor 192.168.25.5 route-map RTBH in
ip bgp-community new-format
ip community-list standard RTBH permit 12:666
ip route 10.0.0.0 255.255.255.255 Null0
route-map RTBH permit 10
 match community RTBH
 set local-preference 200
 set ip next-hop 10.0.0.0
route-map RTBH permit 20

Злоумышленник начал DDoS атаку на маршрут за CE1 – 3.3.3.3/32:

Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 40/48/52 ms

Чтобы заблокировать вредоносный трафик на границе своего провайдера, CE1 должен анонсировать маршрут 3.3.3.3/32, прикрепив к нему community 12:666.

CE1#show run | section route-map|router bgp
router bgp 3
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255 route-map RTBH
route-map RTBH permit 10
 set community 12:666

Атака успешно блокирована благодаря фильтру на уровне data plane:

Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
UUUUU
Success rate is 0 percent (0/5)

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

PE2#show ip bgp 3.3.3.3/32
BGP routing table entry for 3.3.3.3/32, version 27
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     3         
  Refresh Epoch 2
  3
    10.0.0.0 from 1.1.1.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 200, valid, internal, best
      Community: 12:666
PE2#
PE2#show ip cef 3.3.3.3/32 det
3.3.3.3/32, epoch 0, flags rib only nolabel, rib defined all labels
  recursive via 10.0.0.0
    attached to Null0

Впрочем, есть и негативный побочный эффект – CE2 также потерял связность:

CE2#ping 3.3.3.3 source loopback 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4 
UUUUU
Success rate is 0 percent (0/5)

Destination-based RTBH может быть полезен в ситуациях, когда нужно в сжатые сроки ограничить ущерб от DDoS атаки или выиграть время, чтобы получить дополнительную информацию о характере атаки. Предположим, что CE1 уже известен IP адрес атакующего – 5.5.5.5/32. Самое время, чтобы включить source-based RTBH, добавив в схему loose uRPF!

PE1#show run int f0/0
interface FastEthernet0/0
 ip verify unicast source reachable-via any
PE2#show run int f0/0  
interface FastEthernet0/0
 ip verify unicast source reachable-via any
PE2#show run int f0/1
interface FastEthernet0/1
 ip verify unicast source reachable-via any

Сеть ISP готова, осталось только подменить анонсы маршрутов на CE1, чтобы запустить source-based RTBH:

CE1#show run | s ip route|router bgp
router bgp 3
 address-family ipv4
  network 3.3.3.3 mask 255.255.255.255
  network 5.5.5.5 mask 255.255.255.255 route-map RTBH
ip route 5.5.5.5 255.255.255.255 Null0

ISP отбрасывает трафик от IP адреса атакующего на ближайшем к злоумышленнику маршрутизаторе:

PE2#show ip bgp 5.5.5.5/32
BGP routing table entry for 5.5.5.5/32, version 29
Paths: (2 available, best #1, table default)
  Advertised to update-groups:
     3         
  Refresh Epoch 3
  3
    10.0.0.0 from 1.1.1.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 200, valid, internal, best
      Community: 12:666
  Refresh Epoch 4
  5
    192.168.25.5 from 192.168.25.5 (5.5.5.5)
      Origin IGP, metric 0, localpref 100, valid, external
PE2#
PE2#show ip cef 5.5.5.5/32 det
5.5.5.5/32, epoch 0, flags rib only nolabel, rib defined all labels
  recursive via 10.0.0.0
    attached to Null0

Однако в этот раз ограничен только вредоносный трафик, легитимные соединения всё ещё активны:

CE2#ping 3.3.3.3 so lo 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 4.4.4.4 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 44/53/72 ms
Attacker#ping 3.3.3.3 source loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5 
.....
Success rate is 0 percent (0/5)

В реальной сети провайдер вряд ли позволит заказчику настолько свободно анонсировать маршруты; более вероятно, что ISP будет фильтровать принимаемые им префиксы или же использовать выделенный маршрутизатор для генерации RTBH обновлений. Тем не менее, идея использовать loose uRPF в связке со статическим маршрутом через Null0 остаётся неизменной, поэтому я надеюсь, что мне удалось построить дополнительный мостик между режимами uRPF и типовыми сценариями их применения.

Спасибо за рецензию: Анастасии Куралёвой

Канал в Телеграме: https://t.me/networking_it_ru

Комментарии (2)


  1. arider77
    02.10.2023 11:54

    Технология хорошая, понятная и вроде даже как рабочая.

    Не так давно сайт предприятия где я работал подвергся DDoS и защитить его подобным образом не вышло.

    Два провайдера (Verizon и Comcast) поддерживают такую схему работы, но как выяснилось по факту ничего заблокировано не было. Более того, "свободное" оперирование маршрутами со стороны клиента (нас) могло заставить провайдера блочить вполне легитимные подсети, хосты в которых были участниками какого-то ботнета. Да и процедура добавления тысяч ip-адресов в route-map была не так проста (а без скриптинга так и вообще не выполнима).

    Как итог компания подписала доп. соглашения к договорами на предоставление услуг, где защита от DDoS работала каким-то секретным способом, НО о том что атака началась\была в процессе приходилось каждый раз сообщать провайдеру отдельно на их клиентском портале через специальную форму. Схема работала, но мы так и не узнали - что там под капотом.


  1. poige
    02.10.2023 11:54

    большая часть одминов, ни капли не парясь пастит из инета sysctl'ы, где через установку rp_filter они мечтают избавиться от спуфинга, (чтобы добиться большей секурности!) на оконечном хосте, с одним gateway'ем, а тут такие тонкости. Смело. )