{"id":199,"date":"2012-05-18T14:19:43","date_gmt":"2012-05-18T13:19:43","guid":{"rendered":"http:\/\/blog.brimbelle.org\/?p=199"},"modified":"2012-05-19T23:12:23","modified_gmt":"2012-05-19T22:12:23","slug":"openbsd-pf-match-altq-et-priorite-des-ack","status":"publish","type":"post","link":"https:\/\/blog.brimbelle.org\/index.php\/2012\/05\/18\/openbsd-pf-match-altq-et-priorite-des-ack\/","title":{"rendered":"OpenBSD PF : &lsquo;match&rsquo; et priorit\u00e9 des ACK"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" title=\"ppuf100X91.gif\" src=\"\/wp-content\/uploads\/ppuf100X91.gif\" alt=\"ppuf100X91.gif\" width=\"100\" height=\"91\" align=\"left\" border=\"0\" hspace=\"10\" \/>Du fait du fonctionnement du protocole TCP, il arrive tr\u00e8s souvent que lorsque l&rsquo;on t\u00e9l\u00e9charge et re\u00e7oit simultan\u00e9ment plusieurs fichiers, la vitesse soit fortement r\u00e9duite, bien en de\u00e7\u00e0 des capacit\u00e9s de notre connexion internet. Ce comportement est tr\u00e8s amplifi\u00e9 par les connexions ADSL, par nature asym\u00e9triques.<\/p>\n<p>Je propose dans cet article une mani\u00e8re efficace et rapide de corriger cela sur une passerelle <a title=\"OpenBSD website\" href=\"http:\/\/www.openbsd.org\/\" target=\"_blank\">OpenBSD<\/a> \u00e0 l&rsquo;aide de quelques r\u00e8gles <a title=\"FAQ de PF\" href=\"http:\/\/www.openbsd.org\/faq\/pf\/index.html\" target=\"_blank\">PF<\/a> en utilisant une premi\u00e8re approche avec le <a title=\"FAQ de ALTQ\" href=\"http:\/\/www.openbsd.org\/faq\/pf\/queueing.html\" target=\"_blank\">moteur de priorisation ALTQ<\/a> et la nouvelle souplesse des r\u00e8gles <em>match<\/em> depuis la version 4.6, puis en utilisant le nouveau moteur de priorisation int\u00e9gr\u00e9 disponible \u00e0 partir de la version 5.1.<\/p>\n<p><!--more--><\/p>\n<p style=\"padding-left: 30px;\"><strong>1. D\u00e9tail du probl\u00e8me<\/strong><\/p>\n<p>Lorsque l&rsquo;on t\u00e9l\u00e9charge un fichier en utilisant le protocole TCP, les donn\u00e9es que nous recevons sont contenues dans des paquets TCP ayant des donn\u00e9es \u00ab\u00a0utiles\u00a0\u00bb. Selon le fonctionnement du protocole TCP, nous devons acquitter au fur et \u00e0 mesure les donn\u00e9es re\u00e7ues, en envoyant au serveur des paquets TCP vides, mais acquittant de la r\u00e9ception des donn\u00e9es (ces paquets contiennent le drapeau ACK). Lorsque nous envoyons un fichier sur internet, c&rsquo;est le m\u00e9canisme inverse qui se produit : la machine recevant notre fichier nous envoie des paquets d&rsquo;acquittement. Pour plus de d\u00e9tails, lire la <a title=\"TRANSMISSION CONTROL PROTOCOL\" href=\"https:\/\/www.ietf.org\/rfc\/rfc793.txt\" target=\"_blank\">RFC 793<\/a>.<\/p>\n<p>Si \u00e0 un moment donn\u00e9, les paquets d&rsquo;acquittement sont ralentis ou perdus, alors le trafic est ralenti puisque la machine envoyant les donn\u00e9es, doit attendre voir r\u00e9-\u00e9mettre les donn\u00e9es : car les paquets auront \u00e9t\u00e9 acquitt\u00e9s tardivement ou pas du tout. Avec les connexions ADSL, fortement asym\u00e9triques, que nous avons aujourd&rsquo;hui, on voit ais\u00e9ment le probl\u00e8me qui peut survenir : si nous lan\u00e7ons sur notre connexion internet, plusieurs envois\/r\u00e9ceptions de fichiers simultan\u00e9s, il est facile de saturer notre d\u00e9bit d&rsquo;\u00e9mission. Ce qui a pour effet de ralentir l&rsquo;\u00e9mission des paquets d&rsquo;acquittement pour les fichiers que l&rsquo;on t\u00e9l\u00e9charge, et donc de ralentir la vitesse de t\u00e9l\u00e9chargement de nos fichiers.<\/p>\n<p style=\"padding-left: 30px;\"><strong>2. Solution A<\/strong><\/p>\n<p>Le filtre de paquets PF d&rsquo;OpenBSD poss\u00e8de depuis longtemps un moteur tr\u00e8s souple, ALTQ, permettant de prioriser les flux suivant diff\u00e9rents algorithmes et param\u00e8tres. Sa configuration est d\u00e9taill\u00e9e dans la page de manuel <a title=\"PF.CONF(5)\" href=\"http:\/\/www.openbsd.org\/cgi-bin\/man.cgi?query=pf.conf&amp;apropos=0&amp;sektion=0&amp;manpath=OpenBSD+Current&amp;arch=i386&amp;format=html\" target=\"_blank\">pf.conf(5)<\/a>. Nous ne d\u00e9taillerons pas sa syntaxe, juste les quelques r\u00e8gles qui nous int\u00e9ressent. Voyons tout d&rsquo;abord comment cr\u00e9er une queue permettant de prioriser les paquets. Ajoutons cette section au fichier \/etc\/pf.conf :<br \/>\n<code><br \/>\next_if = vr3<br \/>\naltq on $ext_if priq bandwidth 920Kb queue { q_pri, q_def }<br \/>\nqueue q_pri priority 7<br \/>\nqueue q_def priority 1 priq(default)<\/code><\/p>\n<p>Ici nous avons cr\u00e9\u00e9 une macro <em>ext_if<\/em>, nommant notre interface externe <em>vr3<\/em> sur laquelle nous allons prioriser nos paquets. Puis, nous cr\u00e9ons une queue m\u00e8re sur l&rsquo;interface <em>$ext_if<\/em> en utilisant l&rsquo;algorithme <em>priq<\/em> (simple algorithme de priorit\u00e9). Cette queue m\u00e8re se voit affecter 820Kb et deux queues filles : <em>q_pri<\/em> ayant une priorit\u00e9 \u00e9lev\u00e9e de 7 et <em>q_def<\/em> la queue par d\u00e9faut ayant une priorit\u00e9 plus basse de 1.<\/p>\n<p>L&rsquo;algorithme priq est le plus simple pr\u00e9sent dans ALTQ : on affecte une priorit\u00e9 diff\u00e9rente aux sous-queues (de 0 \u00e0 15), les paquets de la queue ayant la priorit\u00e9 la plus \u00e9lev\u00e9e sont trait\u00e9s en premier.<\/p>\n<p>Dans la d\u00e9claration de la queue m\u00e8re, j&rsquo;ai r\u00e9serv\u00e9 920Kb de bande passante. Ma connexion internet synchronise \u00e0 environ 6Mb en r\u00e9ception et 1Mb en \u00e9mission. Avec l&rsquo;encapsulation IPoA chez Free, j&rsquo;ai un d\u00e9bit effectif d&rsquo;environ 920Kb. Je vous conseille de faire quelques essais : si vous ne r\u00e9servez pas assez de bande passante, la priorisation sera inefficace, et si vous r\u00e9servez trop de d\u00e9bit, vous allez brider inutilement votre connexion.<\/p>\n<p>Une fois les queues d\u00e9clar\u00e9es, passons maintenant \u00e0 leur affectation dans nos r\u00e8gles de filtrage. J&rsquo;\u00e9crivais pr\u00e9c\u00e9demment que depuis OpenBSD 4.6, une nouvelle fa\u00e7on de filtrer est apparue avec le mot cl\u00e9 <em>match<\/em>. En effet, depuis cette version, de profonds changements structurels ont \u00e9t\u00e9 apport\u00e9s \u00e0 PF, r\u00e9sultant en une bien meilleure souplesse d&rsquo;\u00e9criture. Le mot cl\u00e9 &lsquo;match&rsquo; permet ainsi de \u00ab\u00a0matcher\u00a0\u00bb certains flux pour modifier leur filtrage \u00e0 la vol\u00e9e, sans arr\u00eater leur \u00e9valuation dans le fichier de r\u00e8gles : c&rsquo;est \u00e0 dire sans modifier l&rsquo;action finale <em>block<\/em> ou <em>pass<\/em>.<\/p>\n<p>Alors que pr\u00e9c\u00e9demment, l&rsquo;affectation des queues ALTQ aux flux se faisait \u00e0 chaque r\u00e8gle de filtrage, il est maintenant possible d&rsquo;affecter nos queues par une simple r\u00e8gle <em>match<\/em> au d\u00e9but des r\u00e8gles de filtrage :<br \/>\n<code>match on $ext_if inet proto tcp queue (q_def, q_pri)<\/code><\/p>\n<p>Ainsi, toutes les connexions TCP sur l&rsquo;interface externe <em>$ext_if<\/em> se verront affecter nos deux queues : <em>q_def<\/em> et <em>q_pri<\/em>. L&rsquo;\u00e9valuation des r\u00e8gles continuera ensuite normalement.<\/p>\n<p>Notons que l&rsquo;ordre dans lequel nous avons mis les deux queues est indispensable. La premi\u00e8re queue pr\u00e9cis\u00e9e dans la r\u00e8gle <em>match<\/em> est la queue par d\u00e9faut : <em>q_def<\/em>. Si nous pr\u00e9cisons une deuxi\u00e8me queue (c&rsquo;est ce que nous avons fait), <em>q_pri<\/em>, alors PF lui affecte automatiquement les paquets ayant l&rsquo;option IP ToS positionn\u00e9e \u00e0 \u00ab\u00a0nodelay\u00a0\u00bb ainsi que les paquets TCP sans charge utile ayant le drapeau ACK. C&rsquo;est exactement le comportement que nous recherchons : nos acquittements TCP seront ainsi prioris\u00e9s par rapport aux autres paquets et nous diminuerons les risques de ralentissement.<\/p>\n<p style=\"padding-left: 30px;\"><strong>3. Solution B<\/strong><\/p>\n<p>La solution pr\u00e9c\u00e9dente relativement simple, peut \u00eatre encore beaucoup plus simplifi\u00e9e, depuis OpenBSD 5.1. En effet, de gros travaux sont en cours pour int\u00e9grer totalement \u00e0 PF les fonctionnalit\u00e9s de ALTQ. Aujourd&rsquo;hui, ALTQ peut \u00eatre tr\u00e8s p\u00e9nalisant en terme de performance et sa complexit\u00e9 rend difficile son \u00e9volution.<\/p>\n<p>Ainsi, le mot-cl\u00e9 <em>prio<\/em> est apparu, permettant \u00e0 chaque r\u00e8gle d&rsquo;affecter une priorit\u00e9 au trafic vis\u00e9. Ce nouveau syst\u00e8me de priorisation peut \u00eatre combin\u00e9 avec les r\u00e8gles <em>match<\/em>. Ainsi, les quelques lignes pr\u00e9c\u00e9dentes avec ALTQ peuvent \u00eatre simplifi\u00e9es en :<br \/>\n<code>match on $ext_if inet proto tcp prio (2, 5)<\/code><\/p>\n<p>Ici, plus besoin de d\u00e9claration de queues et d&rsquo;algorithme. Nous affectons une priorit\u00e9 2 au trafic normal et une priorit\u00e9 5 aux paquets ayant un champ IP TOS <em>nodelay<\/em>, ou les paquets TCP ACK sans donn\u00e9e utile.<\/p>\n<p>A noter qu&rsquo;en utilisant ce nouveau m\u00e9canisme de priorisation, nous avons \u00e0 notre disponibilit\u00e9 8 queues (priorit\u00e9 de 0 \u00e0 7. De plus, certains trafics sont automatiquement prioris\u00e9s :<\/p>\n<ul>\n<li>Les priorit\u00e9s des VLAN sont h\u00e9rit\u00e9es,<\/li>\n<li>Le trafic CARP est prioris\u00e9.<\/li>\n<\/ul>\n<p><em><strong>Attention :<\/strong> la syntaxe est sujette \u00e0 \u00e9volution, puisque l&rsquo;int\u00e9gration des autres parties de ALTQ est en cours.<\/em><\/p>\n<p style=\"padding-left: 30px;\"><strong>4. Illustration<\/strong><\/p>\n<p>Voici maintenant en pratique le r\u00e9sultat. Le premier graphe correspond \u00e0 notre politique de filtrage sans ALTQ, le second avec ALTQ.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" title=\"vr3_ackpri_off.jpg\" src=\"\/wp-content\/uploads\/altq_ackpri\/vr3_ackpri_off.jpg\" alt=\"vr3_ackpri_off.jpg\" width=\"740\" height=\"300\" align=\"left\" border=\"0\" \/><\/p>\n<p>Dans ce premier graphe, les trois premi\u00e8res minutes consistent \u00e0 t\u00e9l\u00e9charger quelques fichiers. Ensuite, je lance une \u00e9mission de fichier simultan\u00e9e aux t\u00e9l\u00e9chargements durant les quatre minutes suivantes. On peut voir que non seulement la r\u00e9ception de mes fichiers (en vert) est perturb\u00e9e par rapport \u00e0 la premi\u00e8re partie du graphe, mais \u00e9galement l&rsquo;\u00e9mission de mon fichier qui n&rsquo;utilise pas les 1Mb de bande passante disponible.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" title=\"vr3_ackpri_on.jpg\" src=\"\/wp-content\/uploads\/altq_ackpri\/vr3_ackpri_on.jpg\" alt=\"vr3_ackpri_on.jpg\" width=\"740\" height=\"300\" align=\"left\" border=\"0\" \/><\/p>\n<p>Dans ce second graphe, les deux premi\u00e8res minutes correspondent \u00e0 plusieurs t\u00e9l\u00e9chargements de fichiers. Puis, je lance une \u00e9mission de fichier durant quatre minutes. On peut voir que ALTQ fait correctement son travail : la r\u00e9ception de mes fichiers n&rsquo;est absolument pas perturb\u00e9e par l&rsquo;\u00e9mission de mon autre fichier qui se fait en utilisant au maximum les 1Mb de capacit\u00e9 d&rsquo;\u00e9mission de mon lien internet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Du fait du fonctionnement du protocole TCP, il arrive tr\u00e8s souvent que lorsque l&rsquo;on t\u00e9l\u00e9charge et re\u00e7oit simultan\u00e9ment plusieurs fichiers, la vitesse soit fortement r\u00e9duite, bien en de\u00e7\u00e0 des capacit\u00e9s de notre connexion internet. Ce comportement est tr\u00e8s amplifi\u00e9 par les connexions ADSL, par nature asym\u00e9triques. Je propose dans cet article une mani\u00e8re efficace et [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[123,122,129,6,7,131,124,126,125,128,127,130],"class_list":["post-199","post","type-post","status-publish","format-standard","hentry","category-informations-pour-les-geeks","tag-ack","tag-altq","tag-download","tag-openbsd","tag-pf","tag-pfstat","tag-priority","tag-priq","tag-queueing","tag-telechargement","tag-tcp","tag-upload"],"_links":{"self":[{"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/posts\/199","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/comments?post=199"}],"version-history":[{"count":0,"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/posts\/199\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/media?parent=199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/categories?post=199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.brimbelle.org\/index.php\/wp-json\/wp\/v2\/tags?post=199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}