Cet article extrait de [ http://www.minithins.net/warehouse/DDoS.txt ] offre un aperçu - un instantané même - des méthodes les plus
avancées, en cours de déploiement, d'expérimentation ou de développement,
permettant de lutter contre les Distributed Denial of Service et même, parfois,
d'identifier leurs auteurs. Ces techniques agissant soit directement sur le
chemin, soit sur le management de queues, elles s'appliquent de facto à
l'infrastructure réseau et en particulier aux routeurs, constituant le coeur du
net, son squelette. Ce document se focalise sur le matériel Cisco mais abordera
éventuellement d'autres systèmes, libres (*BSD, Linux, Zebra) ou propriétaires
(Juniper). Il est admis que vous connaissez au moins basiquement ces systèmes
et que vous possédez une bonne compréhension du modèle TCP/IP et des
disciplines d'évitement de congestion des implémentations TCP (New)Reno. La
sécurisation complète d'infrastructure Cisco (pas uniquement contre les DoS)
est par ailleurs résumée dans une présentation en [FIS02].
1. Rappels
2. Path-oriented
2.1. ACL
2.2. RPF
2.3. Route filtering
2.4. {Black,Sink}hole
2.5. NBAR
2.6. iTrace
2.7. SPIE
2.8. IP Source Tracker
3. Exhaustion-oriented
3.1. RED
3.2. ECN
3.3. CAR
3.4. ACC
3.5. CBAC
3.6. TCP SYN Cookies
4. Conclusion
5. Références
Last Update > 02/01/2004
> ACL & CBAC fixed, Linux support added, new year's pre release
To Do > NBAR configuration (ongoing)
> configuration for Juniper and/or Foundry
ACL, rate-limit, AQM, CBAC-like, {black,sink}holing
http://www.juniper.net/techpubs/software/junos/junos60/swconfig60-routing/html/
http://www.foundrynet.com/services/documentation/index.html
> DocBook translation (then make a big chunky html)
"Semper ego auditor tantum ? Nunquamne reponam ?"
Thomas de Quincey, De l'Assassinat considéré comme un des Beaux-Arts
1. Rappels
Tout d'abord, quelques rapides rappels sur ce que sont les DoS et leurs
différents types, qui ne cessent d'augmenter et de s'étoffer de jour en jour
[CHAR]. Un Denial of Service ou DoS est une attaque destinée à limiter ou
empêcher le bon fonctionnement, la disponibilité d'une machine. Les DoS
agissent la plupart du temps par Ressource Starvation, c'est-à-dire qu'ils
consomment un maximum de ressources (CPU, RAM...) de la machine attaquée afin
de la rendre inopérante. Avec assez de ressources du côté attaquant, n'importe
quelle machine est susceptible d'être victime d'un DoS par 'ressource
starvation'. Mais il existe plusieurs méthodes permettant de faire beaucoup de
dégâts avec peu de ressources.
En premier lieu desquelles, et sans doute par ordre de célébrité, on trouve les
smurfs. Les smurfs agissent à partir du protocole ICMP et des adresses IP
broadcast. L'attaquant envoie un paquet ICMP echo request à une ou même
plusieurs adresses broadcast (de préférence appartenant à des réseaux de
classes B voire A) en usurpant l'adresse de l'hôte cible, ainsi les echo reply
de la totalité des hôtes se trouvant derrière l'adresse broadcast (jusqu'à
65535 machines pour une classe B) répondront à la machine cible tous en même
temps entraînant la situation de DoS. Le réseau de l'adresse broadcast agit ici
comme réflecteur pour le DoS.
Une autre méthode très répandue est le SYN flood. Elle exploite TCP en créant
un nombre important de connexions semi-ouvertes dans un intervalles de temps
restreint. Chaque segment TCP avec le flag SYN déclenche chez l'hôte cible la
création d'un espace mémoire communément appelée TCP Control Block (TCB)
contenant les informations relatives à la connexion. Une fois le SYN reçu,
l'hôte renvoie un SYN/ACK puis attendant de recevoir un ACK afin de compléter
le processus d'initialisation. Cependant, les segments du SYN flood auront été
spoofé de sorte que l'hôte cible ne reçoive jamais de ACK en réponse et reste
en état SYN-RECEIVED. La succession rapide de création de TCB remplissant les
queues de connexions en état incomplet finit par consommer assez de mémoire
pour ralentir ou stopper l'hôte cible.
Une variation récente de cette attaque, appelée Naptha [NAP00], a été dévoilé.
Le principe reste le même, à savoir la consommation des ressources mémoire par
la création rapide d'un grand nombre de TCB. Mais afin de contourner les
nombreuses parades qui ont été mise en place contre les SYN floods, le naptha
tente d'initialiser complètement une connexion puis de laisser l'hôte cible en
état ESTABLISHED après avoir envoyé un unique ACK après le SYN/ACK, ou en état
CLOSE-WAIT après lui avoir un ACK suivi d'un FIN initialisant le four-way
handshake de déconnexion. Pour éviter de consommer un TCB de son côté,
l'attaquant doit ici réaliser une connexion en TCP blind spoofing. Ce dernier
détail rend l'attaque bien plus complexe puisqu'elle nécessite la prédiction
de Sequence Number TCP générés par des Pseudo Random Number Generator (PRNG).
Cependant de récents travaux [ZAL01] sur l'utilisation des attracteurs étranges
pour l'identification de patterns de génération pourrait faciliter la mise en
application des napthas.
Mais une condition de DoS peut aussi apparaître avec un faible nombre de
paquets par exemple à cause d'une erreur dans une application. Ce cas de figure
s'est par exemple présenté début 2002 dans BlackICE Defender, outil de sécurité
réseau propriétaire. En interceptant un paquet ICMP similaire à un Ping of
Death - c'est-à-dire légitime mais fragmenté et forgé de manière à être hors
limite une fois réassemblé par le destinataire, causant crash ou ralentissement
- crashait à son tour, entraînant parfois son hôte à sa suite. La faille, qui
s'est finalement avérée être un buffer overflow, était ici due à un bug de
gestion du trafic en sortie du driver propriétaire utilisé par BlackICE pour
l'interception des paquets sous Windows 2000 et Windows XP. De même il y a
quelques années existait le small footprint DoS, contre TCPdump et ses dérivés,
consistant en un unique paquet avec les champs IP Version et IP Total Length
mis à 0. Ces cas sont doublement dangereux puisqu'ils représentent des DoS
applicatifs nécessitant une signature mais attaquent en plus les applications
utilisant ces signatures. Ces types de vulnérabilités peuvent être spécifiques
à un système, un logiciel, ou même une configuration particulière de plusieurs
d'entre eux. Plus simple mais tout aussi destructeur, une attaque, semblable
aux SYN flood que nous avons vus, peut être ciblé contre une machine ou un
service critique dont la dégradation des performances entraînera un effet de
bord assimilable à un DoS. C'est par exemple ce qu'à souligné un récent draft
IETF sur la sécurité du protocole BGPv4 [MUR03].
Toutes ces méthodes peuvent aisément être combinées. Une dizaine d'année de
cela, les ISP ont remarqué le développement inquiétant du phénomène de 'route
flap'. Ce terme désigne le retrait et l'annonce successive et répétée de routes
sur une courte échelle de temps. Chaque flap pousse le routeur à mettre à jour
sa table de routage, causant une surcharge non néglibéable. D'autre part, les
délais de convergence des routes au niveau global donnent aux flaps un impact
important sur la stabilité du routage. En réponse, les organisations liées au
routage ont rapidement déployée une proposition de Curtis Villamizar, résumée
ensuite dans la RFC 2439 [2439], nommée route flap damping. Cette technique
consiste à surveiller les retraits et réannonces, en ajoutant une pénalité à
une route à chaque retraiit. Lorsqu'on dépasse une certaine valeur de pénalité,
c'est-à-dire qu'on observer un nombre de flap élevé sur une courte période, la
route n'est plus utilisée ni annoncée pour une durée prédéterminée partant du
dernier flap ; chaque flap redéclenchant le timer en augmentant le compteur de
pénalité. En effet, ce compteur diminue en fonction du temps, tant qu'on
observe plus aucun nouveau flap. Lorsqu'il repasse au-dessus d'un seuil de
réutilisation, la route retrouve sa place dans les tables de routage. Le
problème vient alors du fait qu'un attaquant peut très bien forcer une route à
"flapper" pour subir des pénalités et donc disparaître d'Internet. Une vaste
attaque coordonnée peut même complétement couper un réseau des autres. Il
suffit de lancer un flood sur le routeur, en particulier sur le port 179/tcp
habituellement utilisé pour les sessions BGP. Le manque de ressources
provoquera éventuellement des timeouts voire un reboot du routeur. Cette
interruption des sessions, si répétée, sera rapidement assimilée à du flapping,
et donc pénalisée. Le RIPE a publié un document très complet sur la bonne
utilisation du damping [RIPE01] encourageant notamment l'utilisation des
messages BGP du type REFRESH et des équivalents à la 'soft-configuration' de
Cisco. Ces deux techniques permettent en effet de modifier une politique BGP
sans nécessiter une réinitialisation de la session, assimilée éventuellement à
du flapping. De même, le "proggressive damping" incite à pénaliser plus
fortement les prefixes courts puisque les prefixes longs sont plus stables et
leur suppression causerait, selon toute vraisemblance, plus de désagréments
pour les utilisateurs. Cela revient concrêtement à encourager fortement
l'agrégation des routes. Enfin, les serveurs racines DNS sont protégés et
listés comme 'Golden Networks'. Malgré tout, ce type d'attaques combinées,
entraînant un DoS en cascade, demeure réalisable pour qui dispose de
connaissances et d'une organisation rigoureuse.
La dernière classe de DoS que nous aborderons n'est pas réellement une méthode
en soit mais plutôt un raffinement. Il s'agit de faire partir l'attaque non
plus d'un unique hôte attaquant, mais d'une multitude de serveurs esclaves
contrôlés par un client maître, potentiellement via plusieurs proxies. C'est
ainsi que fonctionnent les outils Trinoo, Tribal Flood Network 2000 (TFN2k) et
Stacheldaht dont vous pourrez trouver des analyses individuelles détaillées sur
le site de Dave Dittrich [DITT]. Stacheldaht s'est rendu célèbre début 2001
lors des impressionnantes mais triviales attaques contre Yahoo!, CNN, eBay et
bien d'autres. Ces outils agissent habituellement par une génération simple
d'un grand nombre d'ICMP echo reply ou d'UDP echo sans grande finesse. Mais
n'importe laquelle des attaques déjà décrites peut être appliquée à cette
architecture distribuée, à laquelle on a attribué la dénomination DDoS pour
Distributed Denial of Service. Ils nécessitent de plus le contrôle d'un nombre
important de machines ce qui pousse leurs utilisateurs à l'intrusion massive,
quasiment industrielle, allant jusqu'à exploiter des worms, comme ce fut le cas
de Code Red II en 2001 dont chaque instance ciblait le site de la Maison
Blanche.
Outre les DoS massifs ou non, protocolaires ou applicatifs, il faut également
remarquer une autre source involontaire mais néanmoins dévastatrice : les
worms. Depuis 1988 et l'Internet Worm de Robert Morris, ces applications
automatiques se propageant sur les réseaux au gré des vulnérabilités ont
énormément évolués [PAX+02]. Ainsi les nouvelles concernant l'apparition de
nouveaux worms se sont multipliés ces dernières années, et des noms comme Code
Red et Nimda entre juillet et septembre 2001, ou Sapphire début 2003, sont
désormais célèbres. L'analyse de ce dernier [WEA+03], a permis d'établir une
classification entre Sapphire, restraint par la bande passante, et Code Red et
Nimda de l'autre côté, limités par la latence. En effet, Sapphire, exploitant
une faille SQL Microsoft, ne nécessitait qu'un unique paquet UDP de 404 octets,
permettant une propagation rapide et aveugle. Le vers a ainsi pu contaminé 90%
des hôtes vulnérables en 10 minutes, utilisant dans ce laps de temps
énormément de bande passante :
"[Sapphire] caused considerable harm simply by overloading networks and
taking database servers out of operation. Many individual sites lost
connectivity as their access bandwidth was saturated by local copies of
the worm and there were several reports of Internet backbone disruption"
[WEA+03]
A l'opposé, Code Red et Nimda utilisaient des transmissions TCP et se
trouvaient limités par la durée de synchronisation, imposée par le protocole
via le three-way handshake, et les procédures d'acquittement. La vitesse de
propagation étaient donc fonction des délais dans les réseaux. La quantité de
mise en tampon - Code Red faisant 4ko et Nimda 60ko - a nécessairement dégradé
ces délais et la fiabilité des transmissions. Malgré cela, une meilleure
utilisation du multithreading aurait pu rendre ces vers tout aussi
dévastateurs, du point de vue des DoS, que Sapphire, comme l'ont montré Paxson
& al. en [WEA+03]. Plus particulièrement, Code Red I, attaquant les serveurs
Microsoft IIS, se propageait par l'intermédiaire de 99 threads concurrents avec
en plus un bug qui poussait un thread particulier à scanner la même séquence
d'adresses IP, créant potentiellement des situations de DoS vers ces adresses.
Nimda quant à lui utilisait jusqu'à 5 vecteurs de propagation, du web au mail
en passant par les partitions partagés, multipliant d'autant l'apparition de
conditions de DoS pendant son expansion.
Comme vous le voyez, le risque est omniprésent et nécessite donc une large
protection. Notez cependant que les technologies présentées dans cet article ne
concernent en aucun cas les attaques applicatives, du fait de leur spécifité.
Les seules protections résideraient alors en un processus complexe d'audit
permettant de dégager des signatures uniques. Celles-ci pourraient ensuite être
éventuellement utilisées par un IDS pour détecter ces attaques, et parfois même
les arrêter. Bien que le principe de contre-mesures soit encore bien peu
développé dans le domaine de la sécurité, vous pouvez déjà trouver quelques
exemples d'application dans les IDS Prelude et les développements de Snort tels
Guardian, Hogwash ou encore FlexResp (ou même, dans une certaine mesure, Cisco
Firewall IDS et NBAR, étudiés dans cet article). Cette catégorie d'outils
intégrés étant désormais nommés Intrusion Prevention System. Nous nous
intéresserons ici principalement aux technologies capables de détecter,
prévenir ou identifier un DDoS. Elles doivent alors pouvoir s'appliquer à un
réseau entier à travers le matériel en formant l'architecture. C'est à cause de
cette optique généraliste que les technologies étudiées suivront le plus
souvent un modèle anomaly-based et se baseront sur les statistiques.
Les deux orientations que nous avons suivies pour notre étude sont
l'identification et le contrôle des DDoS en fonction de leur chemin
(path-oriented) ou en fonction de l'utilisation des ressources
(exhaustion-oriented). La première partie accueille également les descriptions
de plusieurs schémas d'identification de la source. Ce n'est pas seulement un
élément utile lors de la phase de forensic mais également, devant le manque
criant de mesures automatiques dans la lutte contre les DDoS, une source
d'information essentielle à obtenir le plus rapidement afin d'appliquer des
mesures réactives au plus près de la source. La seconde approche s'est quant à
elle vu récemment confirmée dans un article évoquant la limitation des DoS par
une surveillance stricte du Quality of Service (QoS) [RED+02].
2. Path-oriented
Les DoS ont toujours une source, qu'elle soit directe ou indirecte. Une
solution évidente pour arrêter un DoS est tout simplement de bloquer les
paquets vecteurs de condition de DoS. Cependant, lorsqu'on s'intéresse plus
particulièrement aux DDoS, non applicatifs le plus souvent, les sources se
multiplient et se falsifient plus aisément. Il dévient alors des plus ardus
d'en identifier la source afin de constituer un agrégat capable de servir au
pistage, dit traceback, ou au simple blocage.
D'autre part, le protocole BGP, utilisé pour l'annonce de routes entre
routeurs, offre certaines possibilités de configuration dangereuse, telles
l'annonce de routes vers des adresses privées ou non allouées ainsi que, plus
généralement, l'annonce de prefixes n'appartenant pas au réseau annonceur. Ces
erreurs, intentionelles ou non, peuvent alors renforcer un DDoS en suscitant
d'importantes quantités de messages ICMP host unreachable, éventuellement en
supprimant toute possibilité de communication avec les prefixes illégalement
annoncés.
Dans cette première partie, nous allons donc nous intéresser en particulier aux
procédés touchant à la caractérisation et au cheminement du paquet dans le
réseau. Plus concrètement, cela indique une étude poussée des mécanismes liés
au filtrage, blocage ou comptabilité du trafic.
2.1. ACL
ACL, pour Access Control List, est le terme désignant les règles de filtrage
sur les systèmes Cisco. Plus généralement, nous aborderons les techniques
logicielles permettant, à un routeur ou un firewall, de filtrer le trafic selon
agrégat. Les principales DDoS ne possédant pas de signature particulière ou
bien facilement modifiable, la détection par pattern matching comme dans les
IDS s'avère inopérante. Le filtrage dynamique brut contre un attaquant s'avère
également peu utile puisque la bande passante en amont s'avère toujours
utilisée. Ce point force d'ailleurs les responsables d'une infrastructure
réseau à placer les protections le plus proche possible de l'attaquant, donc
généralement au niveau des border routers. Mais la principale opposition au
filtrage dynamique est tout simplement l'utilisation systématique du spoofing
dans ces techniques. Pour limiter cela, quelques règles simples peuvent être
appliquées.
D'abord pour éviter que notre réseau ne serve de réflecteur pour un smurf, nous
avons la possibilité chez Cisco d'interdire les réponses à un broadcast issue
d'une adresse unicast. Notez que cette configuration est celle par défaut
depuis IOS 12.0.
router(config)#interface e0
router(config-if)#no ip directed-broadcast
Nous allons ensuite filtrer plusieurs blocs d'adresses que nous savons
attribuées à des réseaux privés non routables sur Internet, ou bien
réservées à des usages expérimentaux. Cette politique de filtrage ingress est
résumée parfaitement dans la RFC 2267 [1812][2267]. Plusieurs de ces adresses
sont indiquées dans la RFC 1918 accompagnées de leur politique de routage comme
ci-dessous
"Because private addresses have no global meaning, routing information
about private networks shall not be propagated on inter-enterprise
links, and packets with private source or destination addresses
should not be forwarded across such links. Routers in networks not
using private address space, especially those of Internet service
providers, are expected to be configured to reject (filter out)
routing information about private networks. If such a router receives
such information the rejection shall not be treated as a routing
protocol error."
Les blocs que nous filtreront selon la RFC 1918 sont :
- 0.0.0.0/8 représentant une machine sans adresse ce qui ne doit pas exister
- 127.0.0.0/8 représentant l'interface de loopback
- 169.254.0.0/16 utilisé comme adresse d'autoconfiguration en cas d'échec
avec DHCP
- 192.0.2.0/24 réservé pour documentation et test
- 192.168.0.0/16 ; 172.16.0.0/12 et 10.0.0.0/8 pour les adresses privées
- 224.0.0.0/3 représentant des réseaux multicast de classe D notamment utilisé
par OSPF et certains broadcast videos, et expérimentaux de classe E
Pour plus d'informations sur l'assignation d'espaces d'adresses et même de
numéros d'Autonomous System (privés de 64512 à 65535), référez vous aux RFC
1166 et 1466 et aux registres de l'IANA sur l'adressage IPv4 listant plusieurs
classes C : http://www.iana.org/assignments/ipv4-address-space. Enfin, fin
2002, l'IANA a souhaité résumé en un seul document ces contenus dispérsés au
sein de la RFC 3330 [3330].
Sur les routeurs Cisco, nous allons configurer des access-list. Cette opération
s'effectue en mode 'configure terminal' :
router#configure
Configuring from terminal, memory, or network [terminal]?
Enter configuration commands, one per line. End with CNTL/Z.
router(config)#
La commande access-list se décompose de la manière suivante :
access-list {permit | deny | remark}
[log [log-input]]
Number a la double fonction de numéroter l'access list, et donc par extension,
l'access group, tout en spécifiant le type d'ACL souhaité. De 1 à 99 ce sont
des ACL standards tout comme de 1300 à 1999 si cela ne suffit pas ; de même, de
100 à 199 et de 2000 à 2699, nous avons affaire à des Extended ACL. La liste
n'est pas exhaustive, et vous en apprendrez bien plus en tapant :
router#access list ?
Nous utiliserons les EACL contrôlant la source, la destination, le protocole et
le port. Les différents mots-clés qu'elles nous permettent d'utiliser sont les
suivants :
- 'permit' et 'deny' permettent de laisser passer ou de bloquer un paquet
tandis que 'remark' permet de placer un commentaire
- 'protocol' matche les paquets d'un protocole donnée (eigrp, gre, icmp, igmp,
igrp, ip, ipinip, nos, ospf, tcp, ou udp)
- 'source' correspond à l'adresse IP à bloquer, et 'source mask' à son masque
de sous-réseau en notation inversée. En mettant ce champ à any, votre règle
sera valable quelque soit l'adresse.
- le champ suivant est constitué d'un opérateur 'lt' pour inférieur à, 'gt'
pour supérieur à, 'eq' pour égal ou 'neq' pour différent, suivi du numéro de
port source. L'utilisation de comparateurs permettra de filtrer selon une
gamme de ports.
- 'destination', 'destination mask' et 'destination port', sont équivalent aux
champs précédents pour la destination
- 'options' peut prendre pour valeur 'tos' (max-reliability, max-throughput,
min-delay, min-monetary-cost, normal) ou 'precedence' (critical, flash,
flash-override, immediate, internet, network, priority, routine) avec le
protocole IP pour filtrer selon le ToS ou l'IP Precedence, respectivement.
Mais vous pouvez également spécifier l'état 'established' pour TCP vérifiant
ainsi la présence du flag ACK, ou bien, pour ICMP, la paire type/code ou
simplement le nom du message.
- Les derniers mots-clés coïncident avec les instructions de journalisation,
soit 'log' pour une journalisation classique des informations du paquet,
suivi éventuellement de 'log-input' pour ajouter à ces informations les
adresses MAC et l'interface de réception. Notez qu'un paquet unique n'est
enregistré qu'une seule fois toute les 5 minutes, les données journalisées
se voyant alors complétées par un compter du nombre d'occurence.
------------------------------------ SNiP -------------------------------------
no access-list 101
! filtrage selon les RFCs 1918, 1166, 1466 et 3330
access-list 101 deny ip 0.0.0.0 0.0.0.255 any log log-input
access-list 101 deny ip 10.0.0.0 0.0.0.255 any log log-input
access-list 101 deny ip 14.0.0.0/8 0.0.0.255 any log log-input
access-list 101 deny ip 24.0.0.0/8 0.0.0.255 any log log-input
access-list 101 deny ip 127.0.0.0 0.0.0.255 any log log-input
access-list 101 deny ip 169.254.0.0 0.0.255.255 any log log-input
access-list 101 deny ip 172.16.0.0 0.0.240.255 any log log-input
access-list 101 deny ip 192.0.2.0 0.255.255.255 any log log-input
access-list 101 deny ip 192.18.0.0/15 0.0.254.255
access-list 101 deny ip 192.88.99.0/24 0.255.255.255
access-list 101 deny ip 192.168.0.0 0.0.255.255 any log log-input
access-list 101 deny ip 224.0.0.0 0.0.0.108 any log log-input
access-list 101 deny ip 240.0.0.0/4 0.0.0.240
! Bonus Track : Sun Microsystems cluster interconnects
access-list 101 deny ip 204.152.64.0 0.255.255.255 any log log-input
! adresses internes arrivant depuis l'extérieur
access-list 101 deny ip any log log-input
------------------------------------ SNiP -------------------------------------
Il ne reste plus qu'à appliquer cette configuration à votre routeur, sur
l'interface de sortie, bien entendu :
router(config)#interface e0
router(config-if)#ip access-group 101 in
router(config-if)#^Z
router#write
Building configuration...
[OK]
router#
Cette configuration est à appliquer sur l'interface externe en entrée. Mais
elle peut - et même doit ! - s'appliquer tout aussi bien en output sur l'une
des interfaces pour éviter de laisser fuir des adresses non-autorisées.
Si vous êtes chargés de l'administration d'un réseau important, et remaquez que
vos access-lists s'allongent de manière inquiètante pour les performances de
vos routeurs, sachez qu'il existe une solution. En effet, depuis IOS 12.0(6)S,
les ACL ont la possibilité d'être compilées, devenant ainsi des Turbo ACL. Le
ruleset est remplacé par une structure de données, dites lookup tables, proche
des tables de routage. Le parcours du ruleset est alors remplacé par des
comparaisons avec entre les en-têtes de paquets et ces lookup tables. Le tout
en conservant la règle du "first match win" (arrêt à la première équivalence
entre un paquet et une règle) propres aux ACL Cisco.
Il suffit, pour effectuer la compilation, d'entrée la ligne suivante :
router(config)#access-list compiled
La documentation Cisco [TACL] affirme que pour des rulesets de plus de 3
entrées, grâce aux lookup tables, la charge CPU et la durée de recherche de
concordance sont désormais fixes, quelqu'eût été la taille du ruleset d'origine
maintenant compilé. La compensation est une consommation supérieure à la
normale de mémoire, de l'ordre de un Mo par access-group. Il devient alors
capital de correctement grouper ses règles. D'autre part, si votre ruleset
comporte des ACL de type reflexive, dynamique ou bornées dans le temps,
celles-ci se verront exclues de la compilation. Ce genre de configuration peut
créer des situations peu confortables ou ACL exotiques en liste et ACL
classiques compilées fonctionnent parallèlement. Les Turbo ACL demeurent
toutefois intéressantes pour obtenir un filtrage restrictif qui ne pénalise les
opérations de routage à son profit.
La commande 'show access-list compiled' propose des informations très complètes
en particulier pour déterminer les règles exotiques qui n'ont pas pu être
compilées. Celle-ci seront alors affichées par la commande accompagnées de la
mention "Unsuitable" dans la colonne "State" :
router#show access-list compiled
Vous trouverez plus de détails sur les ACL en [RIP]. Sachez également, dans un
souci d'interopérabilité, que la configuration et la syntaxe des ACL sont très
similaires pour GNU Zebra [ZEB], le sous-système de routage libre le plus
complet à ce jour.
Pour aller encore un peu plus loin avec les technologies Cisco, sachez que vous
disposez d'un des rares dispositifs intégrés liant IDS et firewall, au sein du
Firewall IDS [FIDS], présent depuis IOS 12.0(5)T. Comme tout bon IDS, il
inspecte chaque paquets ou sessions traversant le routeur, à la recherche
d'analogies avec l'une de ses 59 signatures. Il est alors capable, en outre de
la classique journalisation, de prendre des actions en réponses à une alerte
afin de contrecarrer une attaque en cours, et ce de manière complètement
automatisée. Pour les amateurs de Cisco jusqu'au bout des ongles, il sera même
possible de l'intégré comme senseur du Secure IDS (c'est-à-dire NetRanger) et
d'obtenir un système de journalisation des alertes centralisé.
Les signatures utilisées sont basiquement hierarchisée, entre 'atomic' pour
celles concernant un unique paquet et 'compound' lorsqu'on surveille une suite
d'actions ou d'états (hierarchie interne au système), ou entre 'info' pour les
actions de reconnaissances (généralement atomiques) et 'attack' pour les
attaques complètes (plutôt compound). Les réponses, quant à elles, sont 'alarm'
pour alerter via syslog, 'drop' pour rejeter le paquet et 'reset', reservé au
transmission TCP, qui permet de terminer une connexion en envoyant un segment
RST à chaque extrêmité. Vous pouvez tout d'abord configurer le comportement par
défaut pour les deux types de signatures attack et info, c'est-à-dire une ou
plusieurs des 3 actions présentées :
router(config)#ip audit info action alarm
router(config)#ip audit attack action alarm drop reset
Comme notre sujet se concentre sur les DDoS, il est assez inutile de consommer
des ressources au niveau des routeurs pour tenter de détecter toutes les
attaques. Firewall IDS est en effet un gros consommateur de ressources, comme
tout IDS ou firewall, à cause de la recherche de correspondances ou de la
notification. D'autre part, il apparaît évident que 59 signatures sont bien peu
de choses face aux nouvelles attaques découvertes chaque jour. Même si la
volonté de Cisco était de constituer un système à jour, ce qui nécessiterait
des mises à jour régulières, la méthodologie de mise à jour d'IOS deviendrait
vite épuisante. Un IDS dédié sera plus à même de se consacrer à la détection
d'attaques, disposant d'un ruleset certainement plus à jour. Heureusement,
Firewall IDS offre la possibilité de désactiver des signatures.
router(config)#ip audit signature {disable | list }
Signature-id est un numéro d'identification d'une signature. Vous pourrez
trouver la liste complète dans la documentation Cisco [FIDS] ou dans la
NetRanger Network Security Database. Dans notre cas, elles seront toutes
désactivées (disable) à l'exception des signatures 3050 (SYN flood), 2154 (Ping
of Death) et 3106 (spam). La seconde option, list, permet d'attacher une
signature à un numéro d'ACL. Mais cette opération sera de toutes manières
réalisée par la commande suivante :
router(config)#ip audit name {info | attack} [list ]
[action [alarm] [drop] [reset]]
'ip audit name' permet d'attacher un type entier de signatures à une ACL, tout
en définissant les actions à prendre. Ces dernières prendront le dessus sur la
configuration par défaut. Vous trouverez ci-dessous un exemple d'application avec
et sans couplage à une ACL.
------------------------------------ SNiP -------------------------------------
! application sans ACL
ip audit signature 1000 disable
ip audit name reco info action alarm
! seules les Standard ACL sont acceptées
ip audit name forged list 99 alarm drop reset
access-list 99 deny 198.162.0.0 0.0.255.255
------------------------------------ SNiP -------------------------------------
Remarquez que lier une règle d'audit et une ACL n'est absolument pas
obligatoire. Cette méthode permet seulement, avec 'ip audit signature', de
personnaliser totalement le set de signatures utilisées selon l'hôte ou le
réseau, pour protéger ce qu'on appelle communemment des trusted hosts.
Il ne reste plus alors qu'à attacher vos règles d'audit à une interface, comme
pour une ACL :
router(config)#interface e0
router(config-if)#ip audit {in | out}
Typiquement, on attachera les règles dans le sens rentrant (in) pour une
interface externe et dans le sens sortant (out) pour une interface interne.
Notez que la règle 3106 se rapportant à la détection du spam nécessite une
petite configuration supplémentaire. Elle se base en effet sur le nombre
d'adresses mails contenues par le champ SMTP RCPT TO, c'est-à-dire le champ
indiquant les destinataires. La valeur par défaut est 250, mais vous avez tous
loisirs de l'ajuster de la manière suivante :
router(config)#ip audit smtp spam 50
Enfin, pour la notification par la journalisation, vous avez également une
marge de configuration permettant de définir son format (syslog par défaut).
Ceci vous permettra par exemple d'adopter un format lisible en cas de
notification distante vers NetRanger. Ci-dessous, la commande en question :
router(config)#ip audit notify log [nr-director | syslog]
Enfin, vous disposez des habituelles commandes d'afficage du sous-système,
toutefois un peu plus complètes qu'à l'habitude pour le Firewall IDS. Outre
l'afficache de la configuration globale, vous pouvez consulter la
configuration par interface, ainsi que des statistiques d'utilisation :
router#show ip audit configuration
router#show ip audit interface
router#show ip audit statistics
Ces dernières peuvent être remises à zéro de la manière suivante :
router#clear ip audit statistics
Tandis que la configuration globale d'audit peut être supprimée avec la
commande qui suit :
router#clear ip audit configuration
Bien sûr vous pouvez vouloir appliquer une protection minimale contre les
paquets forgés, tirant parti d'adresses non routables, sans avoir un large
réseau disposant de routeurs. Pour cela il vous suffit d'appliquer la même
configuration à vos firewalls. Ci-dessous un exemple de configuration pour
IPFilter [IPF] (et sans doute Packet Filter d'OpenBSD). Ce firewall existe sur
de nombreux systèmes et le ruleset est aisément traduisible.
------------------------------------ SNiP -------------------------------------
# bloque et log les paquets avec les adresses sources suivante en entrée sur
# l'interface fxp0, assumant que celle-ci est l'interface externe
extinf=fxp0
us=/
block in log quick on $extinf from 0.0.0.0/8 to any
block in log quick on $extinf from 10.0.0.0/8 to any
block in log quick on $extinf from 14.0.0.0/8 to any
block in log quick on $extinf from 24.0.0.0/8 to any
block in log quick on $extinf from 127.0.0.0/8 to any
block in log quick on $extinf from 169.254.0.0/16 to any
block in log quick on $extinf from 172.16.0.0/12 to any
block in log quick on $extinf from 192.0.2.0/24 to any
block in log quick on $extinf from 192.18.0.0/15 to any
block in log quick on $extinf from 192.88.99.0/24 to any
block in log quick on $extinf from 192.168.0.0/16 to any
block in log quick on $extinf from 204.152.64.0/24 to any
block in log quick on $extinf from 224.0.0.0/3 to any
block in log quick on $extinf from 240.0.0.0/4 to any
block in log quick on $extinf from $us to any
------------------------------------ SNiP -------------------------------------
Afin de vous faciliter la vie, voici les mêmes règles traduites pour iptables,
le firewall du projet Netfilter, disponible depuis Linux 2.4.x.
------------------------------------ SNiP -------------------------------------
# même principe, interface d'exemple eth0
EXTINF=eth0
US=/
iptables -A INPUT -i $EXTINF -s 0.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTINF -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTINF -s 14.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTINF -s 24.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTINF -s 127.0.0.0/8 -j DROP
iptables -A INPUT -i $EXTINF -s 169.254.0.0/16 -j DROP
iptables -A INPUT -i $EXTINF -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i $EXTINF -s 192.0.2.0/24 -j DROP
iptables -A INPUT -i $EXTINF -s 192.18.0.0/15 -j DROP
iptables -A INPUT -i $EXTINF -s 192.88.99.0/24 -j DROP
iptables -A INPUT -i $EXTINF -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i $EXTINF -s 204.152.64.0/24 -j DROP
iptables -A INPUT -i $EXTINF -s 224.0.0.0/3 -j DROP
iptables -A INPUT -i $EXTINF -s 240.0.0.0/4 -j DROP
iptables -A INPUT -i $EXTINF -s $US -j DROP
iptables -A INPUT -i £EXTINF -j LOG -log-prefix "incoming pkts on extif:"
------------------------------------ SNiP -------------------------------------
Pour les programmes de DDoS, il ne sert à rien d'essayer de filtrer les ports
de leur daemons et proxies puisqu'ils utiliseront en général pour communiquer
des covert channels, tels que la célèbre paire ICMP echo request/reply. Pour
utiliser un système similaire au Cisco Firewall IDS, vous pouvez utiliser Snort
couplé à Guardian [GRD]. Ce dernier scan les logs Snort et, en cas d'alertes,
exécute un shell script insérant une règle dynamique dans le firewall. Ce
mécanisme fonctionne avec iptables, ipchains et ipfwadm sur Linux et ipfw sur
FreeBSD. Cependant cette alternative est peu élégante et multiplie les
possibilités d'erreurs ou d'abus, nous faisant préférer des systèmes intégrés
comme Cisco IOS ou bien, en open source, Prelude IDS [PREL].
L'intérêt principal, dans le fait d'aborder le filtrage, est de donner un
aperçu des capacités disponibles sur tous les systèmes récents. Vous disposez
ainsi d'un moyen simple de vous protéger unilatéralement d'attaques par
spoofing des plus basiques, ainsi que d'erreurs ou d'exploitation dans des
configurations BGP laxistes. Toutes ces erreurs peuvent mener à des DDoS.
2.2. RPF
Le Reverse Path Forwarding est une technologie Cisco qui peut s'avérer très
utile dans la lutte contre le spoofing. Lorsqu'un paquet arrive sur une
interface, RPF vérifie que l'interface ayant reçu ce paquet coïncide avec le
plus court chemin du routeur à la source. C'est seulement à cette condition que
le routeur pourra faire suivre le paquet. Dans le cas contraire, cela signifie
que le paquet est illégitime (délibérément construit lors d'une attaque, ou
bien issue d'une erreur de routage) et il est donc rejeté. Le Unicast RPF [RPF]
activé sur des routeurs externes (type eBGP) offre une manière simple et
élégante d'éviter l'arrivée de paquets forgés sur l'interface externe avec,
en source, une adresse correspondant à l'un des réseaux directement connectés
au routeur. En effet, selon les critères de RPF, le routeur les verra comme
arrivant par une mauvaise interface, c'est-à-dire n'empruntant pas le chemin le
plus court. Et ainsi quelque soit les adresses, privées ou publiques, globales
ou de sous-réseau, se trouvant derrière ledit routeur.
Cette vérification s'effectue grâce à une autre technologie Cisco, le Cisco
Express Forwarding ou CEF [CEF], basée sur une image de la table de routage
appelée Forward Information Base (FIB) maintenant une liste de next-hop par
prefixe IP, ainsi qu'une Adjacency Table listant le next-hop au layer 2 pour
chaque entrée dans la FIB. Un raffinement du CEF consiste à faire par défaut
du load balancing par destination : chaque paire d'adresses conserve le même
chemin mais différentes paires peuvent avoir différents chemins de valeur
métrique équivalente.
Le Unicast RPF s'active par interface, après l'activation de CEF, le tout en
utilisant la séquence des commandes ci-dessous.
------------------------------------ SNiP -------------------------------------
ip cef
! per-destination est le comportement par défaut
ip load-sharing per-destination
interface e0
ip verify unicast reverse-path
------------------------------------ SNiP -------------------------------------
Notez que vous pouvez ajouter à la fin de la commande 'ip verify unicast
reverse-path' le numéro d'une ACL qui déterminera le traitement du paquet en
cas d'echec au test RPF. Ce tour de passe-passe vous permet grâce à une règle
deny de loguer les paquets rejetés, fonctionnalité non offerte par RPF.
Devant l'intérêt suscité par cette fonctionnalité, il n'a pas fallu attendre
longtemps pour en retrouver des équivalents dans le logiciel libre.
L'importance d'une telle commande est de simplifier le travail de
l'administrateur en remplaçant aisément les configurations complexes
nécessaires auparavant pour atteindre le même but. En effet, sur tout firewall
gérant correctement les opérateurs logiques, il sera possible d'écrire une
règle empêchant tous paquets marqués d'une certaine adresse de passer par autre
chose que l'interface à laquelle cette adresse est normalement attachée. Par
exemple, en suivant une syntaxe type IPF (ou PF), la configuration serait telle
que ci-dessous (avec extif l'interface externe et subnet le réseau privé) :
block drop in on !$extif inet from $subnet to any
Depuis Linux 2.4, vous pouvez activer une telle fonctionnalité par interface
via les variables disponibles dans /proc/sys/net/ipv4/conf/. Même si il est
exprimé différemment, le raisonnement reste le même. Pour Linux, si l'interface
par laquelle le paquet analysé est supposé quitter son réseau ne correspond pas
à celle par laquelle il rentre, alors il est considéré comme invalide et
rejeté. Concrètement, cela revient à vérifier dans la table de routage si ce
paquet entre bien par l'interface directement connectée à son réseau d'origine.
Pour l'activer dans une interface donnée, exécutez la ligne suivante :
# echo "1" > /proc/sys/net/ipv4/conf//rp_filter
Où 'interface' est à remplacer par le nom de l'interface. Pour étendre cette
configuration à l'ensemble de vos interfaces, remplacez 'interface' par
'default" ou 'all'. Enfin, pour la rendre persistante, il vous faudra ajouter
cette commande sous forme de script à /etc/rc.d/init.d/.
Pour détecter quels paquets sont effectivement rejetés, afin de corriger
éventuellement une configuration indésirable, ajoutez également cette entrée :
# echo "1" >/proc/sys/net/ipv4/conf//log_martians
Pour étendre cette configuration, suivez les mêmes instructions que pour
rp_filter. Plus de détails dans le Linux Advanced Routing & Traffic Control
(LARTC) Howto [LARTC].
Pour ce qui est de FreeBSD, la ré-implémentation d'IPFW, sous le nom IPFW2,
a vu l'ajout - dans FreeBSD 4.8 avec l'option IPFW2, ou dans -CURRENT avec
l'option IPFW classique - du mot-clé 'verrevpath' [VRP], référence directe à la
commande correspondante chez Cisco. Le fonctionnement est strictement similaire
à Linux. Pour chaque paquet correspondant aux règles affublées de verrevpath,
ipfw vérifie, au sein de la table de routage, si l'interface par laquelle un
paquet entre, coincide avec celle liée à la route vers le réseau d'origine du
paquet. Par précaution, tous les paquets sortant ou bien ceux qui ne possèdent
pas d'interface de sortie correspondante à leur adresse source (c'est-à-dire
venant d'un réseau non directement connectée) passent le test.
Un règle ipfw appliquant cette sécurité à tous les paquets entrant dans un
réseau ressemblera à celle qui suit, avec extif représentant l'interface
d'entrée :
ipfw add 100 allow log all from any to any via ${extif} verrevpath
Le dernier à suivre ce mouvement fut OpenBSD, avec PF [PF]. Depuis la release
3.3, celui-ci dispose du mot-clé 'antispoof' sur lequel vous trouverez des
informations complètes dans pf.conf(5)[MANPF]. La commande type IPF que nous
avons vu plus haut, peut désormais être remplacée, dans pf.conf, grâce à
antispoof, de la façon suivante :
antispoof for $extif inet
Outre la vérification qu'aucun paquet ayant pour source une adresse du réseau
auquel est attachée une certaine interface (ici extif) ne sorte pas une autre,
une seconde protection, spécifique à OpenBSD, est ajoutée en rejetant
complétement tout paquet ayant pour source l'adresse de l'interface protégée.
Elle remplace donc aussi la règle suivante, où 192.168.0.1 correspondait à
l'interface protégée :
block drop in inet from 192.168.0.1 to any
Notez que les applications qui communiquent avec les interfaces locales via
l'interface loopback peuvent se trouver perturbées, comme précisé dans la man
page pf.conf(5). Pensez alors à ajouter une règle autorisant explicitement les
transmissions depuis l'interface de loopback.
L'autre problème majeur que vous pouvez rencontrer avec RPF sera le rejet de
paquets légitimes à cause des routes asymétriques auxquelles peuvent conduirent
les protocoles de routage dynamique. Pour cette raison, il sera préférable de
n'appliquer RPF que pour des adresses d'un réseau directement connecté (donc
sur des interfaces privées) et d'enregistrer les paquets rejetés afin de
pouvoir déteter un tel problème.
2.3. Route filtering
Poursuivant notre lutte acharnée contre le spoofing, il apparaît rapidement
judicieux et nécessaire d'éviter simplement la possibilité de router un paquet
apparemment forgé. En effet, les auteurs de spam et de DDoS disposent de
plusieurs techniques permettant l'usurpation ou le détournement temporaire
d'adresses afin de lancer leurs attaques. Un routeur malin peut ainsi servir
à introduire dans la table BGP Internet globale des annonces de routes de
courte durée vers des adresses privées. Dans la même veine, la désagrégation
consiste à annoncer des routes plus spécifiques, c'est-à-dire d'une longueur
de prefixe (en notation CIDR) plus grande, la rendant ainsi prioritaire dans le
processus de prise de décision BGP pour l'installation d'une route.
Afin de contrôler au plus près les annonces reçues et distribuées, Cisco (et,
par extension, Zebra) dispose de plusieurs mécanismes à même d'effectuer un
filtrage des routes propagées, via BGP, au niveau de vos routeurs externes,
dits routeurs eBGP. Chaque réseau se voit attribué dans sa globalité un numéro
d'AS (Autonomous System). La distinction entre routeur externe (eBGP) et
interne (iBGP) se base alors sur les numéros d'AS utilisés pendant une session.
Si'ils diffèrent entre deux routeurs voisins, nous nous trouvons en présence
d'une liaison eBGP, c'est-à-dire entre deux réseaux, soutendant des modes de
propagation de routes différents. Les méthodes décrites ci-après permettent de
ne pas tenir compte de certaines annonces de routes en les filtrant simplement
dès l'entrée de votre réseau. Ainsi, il n'y aura jamais aucune route, dans nos
tables de routage, vers ces adresses.
Les deux méthodes en question ont pour noms 'distribute-list' et 'prefix-list'.
Bien que relativement redondantes, nous évoquerons les deux pour plusieurs
raisons. Tout d'abord, elles sont mutuellement exclusive, ce qui signifie que
vous ne pouvez en aucun cas les appliquer simultanément sur un même routeur. Il
est même recommander de rester cohérent de d'utiliser la même technique à
l'échelle de votre réseau. La différence majeure entre ces deux commandes
demeure la catégorisation des informations. Dans un cas, 'distribute-list', il
est fait appel aux ACL pour filtrer les adresses annoncées, tandis que
'prefix-list' utilise un mécanisme qui lui est propre. Les deux schémas se
configurent de manière similaire en mode BGP config.
Les distribute-list, présentes depuis IOS 10.0, comme toutes les innombrables
options de la commande 'neighbor', pourront s'appliquer individuellement à
chaque routeur voisin selon leur adresse IP, ou bien à tous les routeurs
voisins définis au sein d'un peer group. Voyez la documentation Cisco [CBGP]
pour de plus amples informations sur cette configuration très pratique.
Une distribute-list est en réalité une simple invocation d'une Standard ACL
contre laquelle les messages BGP seront testés. Pour appliquer une telle liste
aux messages en provenance d'un routeur voisin, utilisez la commande suivante :
router(config-router)#neighbor { | } distribute-list
{ | } {in | out}
Comme vous le voyez, la commande est assez simple. Outre la définition du
voisin ou du groupe de voisins auquel les ACL s'appliqueront, vous pouvez
ensuite spécifier le numéro de ces fameuses ACL ou bien, à défaut, préciser
le nom d'une prefix-list. La configuration finale, en reprenant les ACL vues
précédemment, devrait ressembler à l'exemple suivant.
------------------------------------ SNiP -------------------------------------
! filtrage de route annoncées par le voisin d'adresse x.x.x.x
neighbor x.x.x.x distribute-list 101 in
------------------------------------ SNiP -------------------------------------
La description des distribute-list a pu vous intringuer par la mise sur un pied
d'égalité des ACL et des prefix-list. En effet, ces dernières, apparues
seulement sur IOS 12.0, constituent un réel remplacement des ACL. Le but est de
fournir une amélioration des performances pour ce qui est du chargement de la
liste et des vérifications de validité des routes. D'après Cisco, l'objectif
est atteint, en particulier lorsque l'utilisateur manipule des listes
importantes.
Le remplacement pur et simple des ACL a également conduit à quelques
modifications dans le fonctionnement du filtrage. Ainsi désormais, une
politique restrictive est appliquée par défaut, ce qui signifie que, dès lors
qu'une prefix-list est activée, tout ce qui n'est pas expressement autorisé se
voit implicitement rejeté, comme l'explique la documentation Cisco attenante.
Un autre changement est intervenu dans l'ordonnancement des règles elles-mêmes.
En lieu et place des numéros d'ACL, les règles des prefix-list sont désignées
de manière unique par un numéro de séquence. Ces numéros s'incrémentent, par
défaut, de 5 à chaque nouvelle règle. L'idée sous-jacente est de pouvoir
ajouter des règles intermédiaires après coup, simplifiant la mise à jour de la
liste. Cependant, désactiver cette génération automatique peut s'effectuer très
simplement :
router(config-router)#no ip prefix-list sequence number
Il devient alors obligatoire de préciser le numéro de séquence de chacun de vos
règles. Cette option restait possible dans la configuration par défaut,
conservant l'incrément automatique de 5 entre une règle au numéro de séquence
spécifié et une laissée au soin de la génération automatique. Cette opération
est réalisé à travers l'option 'seq' de la commande 'ip prefix-list' qui suit :
router(config-router)#ip prefix-list [seq ] {deny | permit}
[ge ] [le ]
Cette commande permet d'une manière générale de créer une liste (dont le nom
remplace 'name') et d'ajouter des règles en spécifiant une adresse IP suivant
de la longueur de son masque de sous-réseau, juste après avoir précisé l'action
'deny' pour rejeter la route ou 'permit' pour l'autoriser. Les options ge
(greater-or-equal, >=) et le (lesser-or-equal, = | }
prefix-list {in | out}
La configuration finale, suivant les RFCs RFC 1918, 1166 et 1466, sera telle
que celle ci-dessous.
------------------------------------ SNiP -------------------------------------
! prefix-list 'rfc', avec seq automatique
ip prefix-list rfc deny 192.168.0.0/16
ip prefix-list rfc deny 172.16.0.0/12
ip prefix-list rfc deny 10.0.0.0/8
ip prefix-list rfc deny 127.0.0.0/8
ip prefix-list rfc deny 224.0.0.0/3
ip prefix-list rfc deny 169.254.0.0/16
ip prefix-list rfc deny 0.0.0.0/24
ip prefix-list rfc deny 192.0.2.0/24
ip prefix-list rfc deny 204.152.64.0/24
ip prefix-list rfc permit any
! application au neighbor x.x.x.x de la liste 'rfc'
neighbor x.x.x.x prefix-list rfc in
------------------------------------ SNiP -------------------------------------
Dans les deux cas, distribute-list et prefix-list, in indiquera de filtrer les
routes en provenance du voisin, tandis que out appliquera la liste spécifiée
aux annonces que votre routeur émet vers son voisin. Les deux configurations
simultanées sont souhaitables. Plus de précisions, en particulier sur les
commandes 'show' attenantes, sont disponibles en [CBGP].
Le routage BGP exige une certaine rigueur dans les configurations pour éviter
d'annoncer n'importe quoi n'importe comment. Comme nous avons déjà pu
l'évoquer, filtrer strictement les routes sortant ou entrant dans notre réseau
permet de se prévenir de nombreuses situations assimilables à un DoS. Une
configuration rejettant par défaut et autorisant explicitement (restrictive
stance) permettrait quant à elle d'éviter une bonne partie des attaques tirant
parti de configurations laxistes de la part des titulaires d'AS. En plus du
filtrage des adresses "spéciales" que nous venons de voir, vérifiez toujours
que vous n'annoncez effectivement que les préfixes sur lesquels vous avez une
autorité. Et n'oubliez jamais que la sécurité tient une place primordiale dans
l'amélioration de la qualité et de la continuité du service.
2.4. {Black,Sink}hole
Au sein de l'infrastructure réseau, nous avons également la possibilité de
définir un 'blackhole' [GRE02]. Un tel dispositif permet de faire totalement
disparaître le trafic à destination d'une machine. Ainsi, lorsqu'un DoS est
détecté, il suffit de blackholer la cible de l'attaque pour la protéger au
niveau de l'infrastructure. Sous Cisco, cela correspondra à la définition d'une
route statique sur nos routeurs, liant l'adresse de la cible et la
pseudo-interface null0. Concrètement, l'invocation de null0, sur les routeurs
disposant de la technologie CEF, implique une gestion particulière au sein de
l'Adjacency Table, entraînant à son tour le rejet pur et simple des paquets
transitant par la pseudo-interface. Il est alors intéressant de noter que les
processeurs utilisés dans les routeurs Cisco sont optimisés afin d'être plus
efficace dans des conditions de rejets que dans celles de forwarding.
Il existe cependant quelques inconvénients intrinsèques aux blackholes.
D'abord, la détection du DoS reste bien évidemment à la charge de
l'administrateur réseau via un dispositif parallèle. Cela implique que le
blackhole nécessite l'intervention manuelle du même administrateur pour être
mis en place, réduisant, par ce délai, l'efficacité de la mesure. L'autre
désavantage majeur est qu'aucune distinction ne peut être faite entre les
paquets effectivement à l'origine du DoS et le trafic légitime. Outre que cette
méthode se voit plutôt à des cas extrêmes et manifestes, dans lesquels une
interruption temporaire du service est préférable, le blackhole se verra
surtout utilisé ponctuellement afin d'identifier le point d'entrée de l'attaque
dans le réseau à partir des messages ICMP unreachable, puis de placer sur ce
point d'entrée des ACLs ou des politiques de limitation de débit (voir sections
2.1 et 3.3 respectivement).
La technique que nous décrivons nécessiterait cependant la configuration de
chacun de nos routeurs, travail ô combien fastidieux. Le bon sens nous indique
donc d'utiliser BGP pour redistribuer les informations concernant le blackhole.
L'idée est de préparamétrer sur tous les routeurs une route vers null0
attribuée à un bloc d'adresses inutilisé (très important puisque tous les
routeurs rejetteront de fait les paquets de et vers ces adresses) tel qu'un
bloc d'adresses RFC 1918. Attention dans ce cas aux interfaces sur lesquelles
vous appliquez vos filtres distribute-list, afin de ne pas empêcher la
redistribution de vos routes blackhole. La ligne suivante permet de lier le
bloc choisi à une route vers null0 :
router(config)#ip route 255.255.255.0 null0
Il est ensuite nécessaire de définir un routeur de moindre importance, dit
'blackhole server', depuis lequel nous définirons le blackhole et le
propagerons par BGP à toute l'infrastructure. Cette étape sera réalisé grâce à
une politique route-map. Celle-ci appliquera aux routes statiques locales
affublées d'un certain tag un nouveau next-hop correspondant au bloc
d'adresses inutilisé. Comme ce dernier est partout routé vers null0, tous les
paquets appartenant à ces routes statiques locales seront supprimés. La
route-map policy est de forme similaire à celle ci-dessous.
------------------------------------ SNiP -------------------------------------
! on the blackhole server (configuration phase) in 'configure bgp' mode
redistribute static route-map blackhole
route-map blackhole permit 10
match tag 1337
set ip next-hop
set local-preference 500
set community no-export
set origin igp
------------------------------------ SNiP -------------------------------------
Bien que la commande route-map soit sans doute l'une des plus familière aux
administrateurs Cisco, analysons cette séquence plus en détail. Le nom de la
politique est 'blackhole' et son numéro de séquence (cf. ACL et filter-list)
10. Cette politique s'applique à toutes les routes statiques possédant le tag
'1337'. Pour cette route, une série de 'set options' est alors prise. Le
next-hop est remplacé par le bloc inutilisé sélectionné précédemment, la
préférence locale est mise à 500 pour que la route vers le nouveau next-hop
soit choisie à coup sûr comme best-path selon le processus de décision de BGP
pour les routes de provenance interne (iBGP), le champ community est mis à
no-export pour ne pas annoncer cette nouvelle route en dehors de notre AS
(risque de blackhole complet de la part des peers), et enfin le 'BGP origin
code' est 'igp' indiquant que la source est un routeur interne.
L'application d'une politique route-map sur les routes reçues peut se faire
soit sur la base d'une interface, soit pour un voisin (neighbor) désigné. Dans
le premier cas, il faudra simplement entre en mode configuration interface :
router(config)#interface e0
router(config-if)#ip policy route-map blackhole
Dans le second cas de figure, il sera préférable de créer un groupe réunissant
l'ensemble des routeurs internes et d'appliquer à toutes les routes reçues
depuis ce groupe notre politique. Cette procédure s'effectue en mode
configuration bgp.
------------------------------------ SNiP -------------------------------------
neighbor peer-group
neighbor route-map blackhole in
neighbor remote-as
neighbor w.x.y.z peer-group
------------------------------------ SNiP -------------------------------------
Dans cette séquence, nous créons un peer-group que nous nommons (en remplaçant
pg-name) et dont les routeurs appartiennent à l'AS local puisqu'il regroupe
les routeurs internes (remplacer AS par le numéro d'AS local), nous lui
appliquons la route-map blackhole sur les routes entrantes, et enfin nous y
ajoutons autant de routeurs que nécessaires (en iBGP entièrement connecté,
sans réflecteurs de routes, cela correspond à la totalité des routeurs iBGP).
Lorsqu'un DoS occure, il suffira alors de placer, sur le blackhole server, une
route statique marquée du tag correspondant à la route-map policy, comme dans
l'exemple qui suit, en remplaçant par la cible du DoS :
router(config)#ip route 255.255.255.255 null0 tag 1337
Mais le mécanisme de blackhole permet également de remonter la source de
l'attaque spoofée, ceci en journalisant les paquets ICMP * unreachable et
l'interface qui les génère. Cela vous indiquera ainsi par déduction le point
d'entrée du trafic spoofé dans votre domaine. Appliquer cette méthode à de
larges échelles permettrait de remonter plus facilement la source d'un trafic
spoofé en passant d'AS en AS. La journalisation s'effectue très simplement par
les ACL :
router#access-list 101 permit icmp any any unreachables log log-input
Notez cependant que la redirection vers null0 risque de générer une forte
quantité de messages ICMP unreachable. Afin de ne pas surcharger le routeur, il
sera alors nécessaire de limiter le débit de ces messages - comme indiqué en
section 3.3. de cet article - ou bien carrément de les supprimer totalement
avec 'no ip unreachables'.
Comme nous l'avons déjà rapidement abordé, la méthode originale de blackholing
provoque un rejet complet du trafic à destination de la cible de l'attaque,
incluant le trafic potentiellement légitime. BGP offre pourtant des attributs
permettant d'identifier des chemins (path) distincts et donc de leur appliquer
des règles différentes. Face à ce constat, une méthodologie améliorée de mise
en oeuvre d'un blackhole est apparu en tant que draft IETF [TURK02].
Pour décrire ce raffinement du blackhole, nous prendrons un numéro d'AS
d'exemple, 1337. L'idée est que chaque routeur dispose d'une politique
route-map se déclenchant selon une valeur de l'attribut BGP community
différente pour chaque routeur. Pour simplifier la lecture de nos
configurations et aussi nous conformer à la RFC 1997 spécifiant le format de
l'attribut community (AS:NN, où AS est le numéro d'AS et NN un nombre
quelconque, chacun sur deux octets), entrez la commande suivante en mode de
configuration globale :
router(config)#ip bgp-community new-format
Comme pour un blackhole normal, il faut s'assurer que les routeurs en bordure
du réseau possède bien une route statique orientant le bloc inutilisé, servant
de nouveau next-hop en cas d'attaque, vers la pseudo-interface null0 :
router(config)#ip route 255.255.255.0 null0
Il est ensuite demandé de créer une AS-Path ACL permettant d'identifier les
annonces BGP provenant bien de notre AS (1337). Ceci servira ensuite à empêcher
un réseau externe d'utiliser nos valeurs de community pour blackholer n'importe
quel réseau en envoyant des annonces qui déclencheraient notre blackhole
amélioré. Il faut créer d'abord une ACL classique qui matchera tout le trafic,
puis l'appliquer à une AS-Path ACL qui cherchera une correspondance (regexp)
entre l'attribut AS et notre numéro d'AS.
------------------------------------ SNiP -------------------------------------
access-list 1 permit ip any
! appliquez-la à toutes les interfaces
interface e0
ip access-group 1 out
! voyez la documentation Cisco concernant les regexp
ip as-path access-list 1 permit ^1337 .*
------------------------------------ SNiP -------------------------------------
L'utilisation de la valeur de l'attribut community parmis les match criteria de
nos politiques route-map nécessite la création préalable de community ACL.
Chaque devant chercher sa propre community ainsi que celle englobant la
totalité des borders routeurs, il existera deux règles dans la liste ; la
première étant spécifique à chaque routeur.
------------------------------------ SNiP -------------------------------------
! la première ligne change pour chaque routeur
ip community-list 1 permit 1337:01
ip community-list 1 permit 1337:411
------------------------------------ SNiP -------------------------------------
Il ne reste plus qu'à installer sur chacun de nos border routers une politique
route-map permettant de déclencher un blackhole à l'appel de sa valeur de
community. C'est ici que l'on se rend particulièrement compte de l'intérêt de
cette méthode sur la classique. Au lieu de voir tous les routeurs relayer la
mesure de blackhole, seul le peer eBGP désiré le fait, laissant les autres
routes supposées légitimes intactes. Une mesure de blackhole général est
cependant prévue par l'auteur de cette technique améliorée puisqu'il préconise
d'installer également une politique route-map se déclenchant à la réception de
la valeur de community correspondant à l'ensemble des routeurs eBGP (1337:411).
Cette étape a été simplifié en utilisant un numéro de community-list englobant
les deux valeurs community.
------------------------------------ SNiP -------------------------------------
redistribute bgp route-map enhanced_blackhole
route-map enhanced_blackhole permit 20
match community 1
match as-path 1
set ip next-hop
set local-preference 500
set community no-advertise
set origin igp
------------------------------------ SNiP -------------------------------------
En cas d'attaque, il ne reste plus qu'à annoncer, par l'intermédiaire de BGP,
les routes vers la cible affublées de la valeur de community du peer eBGP
identifié comme point d'entrée de l'attaque. Vous remarquerez cependant ici une
lacune importante du draft. Celui-ci semble assumer que l'administrateur est
capable d'identifier le routeur eBGP par lequel transite l'attaque. Non
seulement ce postulat n'est pas évident dans la vie réelle mais, de plus, dans
le cas d'une attaque distribuée (DDoS), les points d'entrée peuvent être assez
nombreux. Il faudrait alors plutôt voir dans ce raffinement du blackhole un
remplacement du filtering classique apportant, en outre, une capacité
d'activation distante.
La modification de la valeur de community nécessite de passer par BGP, donc par
une politique route-map, à l'instar des route-maps utilisées pour la route
statique null0 sur un serveur blackhole. Suivez la séquence de commandes
suivante, en remplaçant 'ebgp_community' par la valeur de community du peer eBGP
point d'entrée présumé de l'attaque.
------------------------------------ SNiP -------------------------------------
redistribute static route-map trigger_blackhole
route-map trigger_blackhole permit 30
match tag 318
set community no-export :
set local-preference 500
set origin igp
------------------------------------ SNiP -------------------------------------
Comme à votre habitude, lorsqu'un DoS est détecté, il suffira d'ajouter
localement une route statique vers null0 pour déclencher le processus de
blackhole :
router(config)#ip route 255.255.255.255 null0 tag 318
De façon relativement récente, on a vu apparaître un raffinement supplémentaire
au blackhole. Le principe en est succintement décrit dans le draft abordant la
méthode de blackhole améliorée [TURK02] vue auparavant. Cette nouvelle
technique, nommée sinkhole par analogie aux blackholes dont elle reprend une
partie de la configuration, consiste, non plus à ré-annoncer une route donnée
afin que tout le trafic vers sa destination soit supprimé, mais à la place à
orienter ce trafic vers une installation dédiée à des fins d'analyse. Si nous
sommes effectivement face à une attaque de type DDoS, il peut être nécessaire
pour l'opérateur d'analyser le trafic d'attaque et d'en extraire le plus
possible d'information avant, éventuellement, de le faire suivre à sa
destination légitime, pour n'éveiller aucun soupçons. Dans une conférence
[GRE+03] donnée au NANOG (North American Network Operators Group), Barry Greene
comparait quant à lui les sinkholes aux honeypots. En effet, si
|