Forum Linux.redhat CentOS 8 - Problème difficile à dépanner - probablement au niveau du réseau

Posté par  . Licence CC By‑SA.
Étiquettes :
5
26
mai
2020

Sommaire

Bonsoir,

Je me permets de poster ce message pour solliciter la communauté à propos d'un problème qui nous tient en échec depuis plusieurs semaines mon équipe et moi même.

Description du problème

Nous avons un script développé en Python qui sert à rafraîchir une base de données PostgreSQL de test à partir d'un dump PostgreSQL de production :
- cet outil est développé et maintenu en interne
- il est utilisé depuis deux ans

Le client pg_restore est exécuté depuis une machine X et le serveur PostgreSQL est sur une machine Y : il y a donc communication au travers du réseau et les deux machines sont dans le même réseau (aucun routage entre les deux).

Pour le fonctionnement général du script :
- il exécute des scripts pré-restauration (kill des connexions, etc)
- il exécute un pg_restore : pour être plus précis, le dump étant compressé en bz2 on fait un pbunzip2 dump.bz2 | pg_restore [arguments]
- il exécute des scripts post-restauration (activation de comptes utilisateurs, etc)

Ce script est ordonnancé tous les dimanches grâce à un crontab et était à l'origine exécuté depuis une machine CentOS 7 : nous n'avons jamais eu aucun soucis.

Puis, dans le cadre d'un projet de migration CentOS 7 -> CentOS 8 toujours en cours, nous avons migré ce service sur une nouvelle machine virtuelle CentOS 8 :
- c'est bien une nouvelle machine installée en plus de la machine CentOS 7
- ce n'est donc pas une mise à jour majeure

Et là c'est le drame :
- quand ce script est exécuté depuis CentOS 7 : tout fonctionne bien
- quand ce script est exécuté depuis CentOS 8 : il échoue au bout d'un certain temps et sensiblement toujours au même endroit

Détails techniques

Ces deux machines virtuelles sont hébergées sur une infrastructure VMware 6.7U3 : elles se trouvent sur le même ESXi.

Elles ont la même quantité de mémoire, la même configuration au niveau des disques durs virtuels, le même nombre de vCPU, etc : bref elles sont identiques en tout point d'un point de vue virtualisation.

D'un point de vue système d'exploitation nous sommes en CentOS 7.6 d'un côté et CentOS 8.1 de l'autre.

La CentOS 8 a un kernel 4.18.0-147.5.1.el8_1.x86_64.

Changements majeurs entre CentOS 7 et CentOS 8

Il y en a beaucoup mais ceux sur lesquels nous nous sommes concentrés sont :

  • le réseau qui est maintenant (CentOS 8) géré par NetworkManager (network-scripts avant)
  • le pare-feu iptables qui utilise maintenant (CentOS 8) un backend nftables côté kernel

Il y a aussi la GLibc mais pour l'instant nous n'avons pas creusé de ce côté.

Détails et logs pour le problème rencontré

Alors déjà le problème se produit toujours plus ou moins au même endroit mais nous écartons un soucis dans le dump car à chaque restauration le dump utilisé est différent et, comme dit, ça fonctionne depuis une machine CentOS 7.

Ce serait donc plutôt sur le temps que ça se joue : je vérifie demain mais, de mémoire, le pg_restore tombe en échec après 4H30.

Voici un exemple de l'erreur retournée par pg_restore :

pg_restore: creating FK CONSTRAINT "myscheme1.mytable1 fkey_1"
pg_restore: [archiver (db)] Error from TOC entry 31721; 2606 45850 FK CONSTRAINT mytable1 key_1 myowner
pg_restore: [archiver (db)] could not execute query: no connection to the server
Command was: ALTER TABLE ONLY "myscheme1"."mytable1"
ADD CONSTRAINT "fkey_1" FOREIGN KEY ("MyColumn1") REFERENCES "myscheme2"."mytable2"("MyColumn2") DEFERRABLE INITIALLY DEFERRED;
pg_restore: [archiver (db)] could not execute query: no connection to the server
Command was:—Completed on 2020-05-09 06:14:59 CEST

pg_restore: [archiver (db)] could not execute query: no connection to the server
[...]
WARNING: errors ignored on restore: 12568

En utilisant strace, nous avons obtenu ceci :

recvfrom(6, 0x5172353, 5, 0, NULL, NULL) = -1 ECONNRESET (Connection reset by peer)
sendto(6, "\25\3\3\0\32\272\362\307j\311"..., 31, MSG_NOSIGNAL, NULL, 0) = -1 EPIPE (Broken pipe)

Ce qui a été testé

Beaucoup de choses :
- avec et sans SSL entre le client pg_restore et le serveur PostgreSQL
- mise à jour mineure de PostgreSQL côté client uniquement : 10.11 -> 10.12
- on a récupéré des paramètres avec "sysctl -a" depuis la machine CentOS 7 et nous avons injecté cela sur la machine CentOS 8
- mise à jour complète de la machine CentOS 8 avec "dnf update"
- avec et sans le paquet NetworkManager-config-server installé
- avec et sans notre script Python (un coup via le script, un coup via un pg_restore natif)
- avec NetworkManager
- sans NetworkManager mais avec network-scripts (l'ancien système de gestion du réseau de RHEL / CentOS)
- le backend firewall semble être nftables par défaut depuis CentOS 8 : nous avons essayé avec iptables en frontend, firewalld et nft
- avec un "nice -20"
- avec un keep alive dans la session PostgreSQL

Rien de tout ceci n'a donné de résultats.

Par contre, une chose donne un résultat positif : désactiver le pare-feu de la machine cliente CentOS 8 (celle depuis laquelle le pg_restore est exécutée).
Sur cette machine (comme sur la CentOS 7 d'ailleurs), nous avons quelques règles iptables pour n'autoriser que certains flux entrants et on ne filtre rien en sortie (on est en OUTPUT ACCEPT).

Si on désactive le pare-feu sur la machine cliente CentOS 8, nous avons un taux de réussite de 100% de nos restaurations avec pg_restore.

Alors ici ça me chiffonne.

Comme dit tout au début : nous passons par le réseau car les machines clientes et serveur sont distantes.
Par contre nous sommes dans le même réseau : il n'y a pas de routage ou que sais-je entre le client et le serveur (la connexion client -> serveur est donc directe).

Et on ne filtre rien en sortie côté pare-feu (OUTPUT -> ACCEPT).
Ici ça me permets déjà de supposer qu'en l'absence de règles de filtrage, à partir du moment ou le pare-feu est activé, alors les paquets réseaux vont traverser cette couche du kernel qui gère le pare-feu.
Êtes-vous d'accord avec cela ?

Le fait que le problème se produise à peu près (à quelques secondes / minutes près) après le même temps nous fait penser à une sorte de timeout.
Mais ça nous paraît bizarre car ce ne serait pas un timeout d'inactivité (le pg_restore bosse en continue) mais un timeout tout court.
Sauf que l'on ne voit rien nul part qui puisse expliquer cela.

2 tests ont été évoqués mais non réalisés :
- changer d'ESXi : on pourra essayer mais personnellement je n'y crois pas (les machines CentOS 7 et 8 sont sur le même ESXi)
- essayer un kernel plus récent : nous sommes en train de compiler un kernel 5.6 et nous allons essayer avec (probablement demain)

Est-ce quelqu'un aurait-il une idée qui puisse expliquer cela svp ?

Je vous remercie d'avance pour votre aide / vos idées :)

  • # idées ?

    Posté par  (Mastodon) . Évalué à 4. Dernière modification le 26 mai 2020 à 20:32.

    Quels sont les postgresql utilisés ? Ce sont ceux de CentOS des deux côtés ?? Et des canaux/dépôts par défaut ? Sur chaque système (7 & 8) on peut installer différentes versions (celle de base, celle via des canaux particuliers centos, voir des canaux externes, ou bien une compilation). Connaitre les versions est un élément important pour une aide éventuelle.

    Avez vous décomposé les phases du scripts pour les faire une à une à la main ? C'est long, OK, mais cela permet de mettre de côté ce script lui même et d'avoir une présomption supplémentaire sur le périmètre exact à l'origine du problème. A moins qu'aucun problème ne surgisse lors de l'exécution à la main des phases essentielles, alors là, il faudra voir le script, mais c'est à priori peu probable, cependant mérite de transformer le peu probable en certitude.

    A quel moment exact cela "time out" ? Une durée n'est pas suffisante, il faudrait préciser si cela se produit toujours à la même étape, et quelle est cette étape. Si c'est toujours à la même étape, alors le point précédent peut se concentrer là dessus uniquement.

    Enfin, toutes les opérations réussissent à tout les coups lorsque le pare-feu de centos8 est désactivé ? Ce point n'est pas bien clair or il semble primordial, car si c'est le cas, les précédents points sont inutiles : il faut se concentrer sur ça et éventuellement le pg_hba. à priori je ne pense pas, car sinon il n'y aurait pas ce long texte, mais n'étant pas sûr d'avoir bien compris ce point je préfère demander

    En résume ces informations importantes sont manquantes (ou je suis passé à côté ?), avec elles on saurait dans quel ordre faire.

    • [^] # Re: idées ?

      Posté par  . Évalué à 3.

      Quels sont les postgresql utilisés ? Ce sont ceux de CentOS des deux côtés ?? Et des canaux/dépôts par défaut ? Sur chaque système (7 & 8) on peut installer différentes versions (celle de base, celle via des canaux particuliers centos, voir des canaux externes, ou bien une compilation). Connaitre les versions est un élément important pour une aide éventuelle.

      PostgreSQL vient des dépôts PostgreSQL et non ceux de CentOS.
      Les versions :
      - serveur : PostgreSQL 10.11 sur CentOS 7.6
      - client quand on est sur CentOS 7 : PostgreSQL 10.11 sur CentOS 7.6
      - client quand on est sur CentOS 8 : PostgreSQL 10.11 sur CentOS 8.1 puis on a mis à jour en PostgreSQL 10.12 pour essayer (depuis la 10.13 est sortie mais nous n'avons pas essayé)

      Avez vous décomposé les phases du scripts pour les faire une à une à la main ? C'est long, OK, mais cela permet de mettre de côté ce script lui même et d'avoir une présomption supplémentaire sur le périmètre exact à l'origine du problème. A moins qu'aucun problème ne surgisse lors de l'exécution à la main des phases essentielles, alors là, il faudra voir le script, mais c'est à priori peu probable, cependant mérite de transformer le peu probable en certitude.

      Oui des tests manuels ont été réalisés et nous ont permis d'écarter la piste du script Python : nous avons testé le pg_restore sans les fameux scripts SQL et le problème est le même.
      En gros, quand on test un scénario, on se mets dans une boucle de minimum 4 itérations et on lance les pg_restore.

      A quel moment exact cela "time out" ? Une durée n'est pas suffisante, il faudrait préciser si cela se produit toujours à la même étape, et quelle est cette étape. Si c'est toujours à la même étape, alors le point précédent peut se concentrer là dessus uniquement.

      C'est toujours sur la même table mais les valeurs du "TOC" (Error from TOC entry 31721; 2606 45850 FK CONSTRAINT mytable1 key_1 myowner) que j'ai donné sont pas forcément les même : on est plus ou moins loin dans la table.
      Le truc c'est qu'on est toujours plus ou moins au même endroit du restore après un même temps d'exécution car nous avons globalement des performances constantes.

      Enfin, toutes les opérations réussissent à tout les coups lorsque le pare-feu de centos8 est désactivé ? Ce point n'est pas bien clair or il semble primordial, car si c'est le cas, les précédents points sont inutiles : il faut se concentrer sur ça et éventuellement le pg_hba. à priori je ne pense pas, car sinon il n'y aurait pas ce long texte, mais n'étant pas sûr d'avoir bien compris ce point je préfère demander

      C'est bien ça : avec le pare-feu désactivé, tout est ok.
      Niveau pare-feu nous avons essayé :
      - en conservant notre iptables historique (ça limitait nos changements déjà au combien nombreux pour ce projet)
      - en utilisant le frontend firewalld
      - en utilisant le frontend nft
      -> même soucis : si un pare-feu est activé sur le CLIENT CentOS 8, alors le pg_restore échoue.

      • [^] # Re: idées ?

        Posté par  (Mastodon) . Évalué à 3. Dernière modification le 26 mai 2020 à 22:51.

        Merci d'avoir précisé, entre temps la discussion se poursuit plus bas, ce n'est du coup probablement pas grand chose à régler :-)

  • # le firewall de centOS

    Posté par  . Évalué à 5.

    Si on désactive le pare-feu sur la machine cliente CentOS 8, nous avons un taux de réussite de 100% de nos restaurations avec pg_restore.

    donc c'est le firewall de CentOS8 qui joue dans l'équation

    il faut voir dans ce firewall s'il n'y a pas une limite de temps aux durées des transactions, voire paramétrer une zone sur laquelle il ne ferait rien pour les flux entre ces deux machines/ports

    • [^] # Re: le firewall de centOS

      Posté par  . Évalué à 5.

      il faut voir dans ce firewall s'il n'y a pas une limite de temps aux durées des transactions,

      C'est même sûr qu'il y en a une vu qu'il y a un filtre à l'entrée. J'imagine que seules les connections établies (ESTABLISH, RELATED) sont autorisée. Il est possible que le timeout conntrack ait changé entre la 7 et la 8 (voire qu'il a été manuellement modifié sur la 7). Je jouerais avec les différents paramètres de timeout: https://unix.stackexchange.com/questions/524295/how-long-does-conntrack-remember-a-connection

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: le firewall de centOS

      Posté par  (site web personnel) . Évalué à 2.

      La commande pour afficher les règles du pare-feu avec nftables :

      # nft list ruleset
      

      On trouve plein d'infos dans le wiki de nftables. Par contre, je ne vois pas comment/où une telle limite serait appliquée !

    • [^] # Re: le firewall de centOS

      Posté par  . Évalué à 1. Dernière modification le 26 mai 2020 à 21:52.

      On pense aussi que c'est côté firewall qu'il faut se concentrer bien qu'on puisse jamais être sur à 100%.
      En tout cas c'est la meilleure piste que nous avons :)

      Le truc c'est qu'on a cherché (peut être pas assez) et on a rien vu qui puisse nous aider.
      J'ai oublié de préciser qu'à un moment un collègue a tenté de logger via iptables et idem on a rien trouvé de probant pour nous aider…

      Attention par défaut nous sommes sur le frontend iptables pas nft (c'est historique : pour l'instant nous n'avons pas migré).
      Demain je pourrais donner un exemple de ce que l'on a en iptables :)

      Et effectivement il y a bien une règle pour le ESTABLISHED ;)

      • [^] # Re: le firewall de centOS

        Posté par  . Évalué à 4.

        Et effectivement il y a bien une règle pour le ESTABLISHED ;)

        Du coup, je regarderais les différences sur les deux systèmes avec:

        sysctl net.netfilter | grep timeout
        

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: le firewall de centOS

      Posté par  . Évalué à 1. Dernière modification le 26 mai 2020 à 21:55.

      Par rapport aux paramètres ici : https://unix.stackexchange.com/questions/524295/how-long-does-conntrack-remember-a-connection

      On peut essayer de chipoter à des valeurs dans un prochain test et vous donner le résultat :)
      Par contre comme dit on a pris l'ensemble de "sysctl -a" de CentOS 7 et on l'a appliqué sur CentOS 8.
      Évidemment, si une clef existe sur CentOS 8 et pas sur CentOS 7 alors je suis d'accord : la valeur n'a pas changée et donc ça mérite que l'on s'y intéresse quand même :)

      • [^] # Re: le firewall de centOS

        Posté par  . Évalué à 1.

        Bonjour,

        Voici des retours de bon matin.

        Concernant les règles de firewall en vigueur sur la machine :

        # sudo iptables -L -n
        Chain INPUT (policy DROP)
        target     prot opt source               destination         
        ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
        ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
        ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
        ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
        ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
        ACCEPT     tcp  --  192.168.0.6          0.0.0.0/0            tcp dpt:9100
        ACCEPT     tcp  --  192.168.0.7        0.0.0.0/0            tcp dpt:5565
        REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
        
        Chain FORWARD (policy DROP)
        target     prot opt source               destination         
        REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
        
        Chain OUTPUT (policy ACCEPT)
        target     prot opt source               destination         
        ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
        ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
        

        Concernant les valeurs de timeout :

        • CentOS 8 :
        net.netfilter.nf_conntrack_dccp_timeout_closereq = 64
        net.netfilter.nf_conntrack_dccp_timeout_closing = 64
        net.netfilter.nf_conntrack_dccp_timeout_open = 43200
        net.netfilter.nf_conntrack_dccp_timeout_partopen = 480
        net.netfilter.nf_conntrack_dccp_timeout_request = 240
        net.netfilter.nf_conntrack_dccp_timeout_respond = 480
        net.netfilter.nf_conntrack_dccp_timeout_timewait = 240
        net.netfilter.nf_conntrack_frag6_timeout = 60
        net.netfilter.nf_conntrack_generic_timeout = 600
        net.netfilter.nf_conntrack_gre_timeout = 30
        net.netfilter.nf_conntrack_gre_timeout_stream = 180
        net.netfilter.nf_conntrack_icmp_timeout = 30
        net.netfilter.nf_conntrack_icmpv6_timeout = 30
        net.netfilter.nf_conntrack_sctp_timeout_closed = 10
        net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3
        net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3
        net.netfilter.nf_conntrack_sctp_timeout_established = 432000
        net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 210
        net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0
        net.netfilter.nf_conntrack_tcp_timeout_close = 10
        net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
        net.netfilter.nf_conntrack_tcp_timeout_established = 432000
        net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
        net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
        net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
        net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
        net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
        net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
        net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
        net.netfilter.nf_conntrack_udp_timeout = 30
        net.netfilter.nf_conntrack_udp_timeout_stream = 120
        
        • sur CentOS 7 :
        net.netfilter.nf_conntrack_dccp_timeout_closereq = 64
        net.netfilter.nf_conntrack_dccp_timeout_closing = 64
        net.netfilter.nf_conntrack_dccp_timeout_open = 43200
        net.netfilter.nf_conntrack_dccp_timeout_partopen = 480
        net.netfilter.nf_conntrack_dccp_timeout_request = 240
        net.netfilter.nf_conntrack_dccp_timeout_respond = 480
        net.netfilter.nf_conntrack_dccp_timeout_timewait = 240
        net.netfilter.nf_conntrack_events_retry_timeout = 15
        net.netfilter.nf_conntrack_generic_timeout = 600
        net.netfilter.nf_conntrack_icmp_timeout = 30
        net.netfilter.nf_conntrack_sctp_timeout_closed = 10
        net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3
        net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3
        net.netfilter.nf_conntrack_sctp_timeout_established = 432000
        net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 210
        net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0
        net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0
        net.netfilter.nf_conntrack_tcp_timeout_close = 10
        net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
        net.netfilter.nf_conntrack_tcp_timeout_established = 432000
        net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
        net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
        net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
        net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
        net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
        net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
        net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
        net.netfilter.nf_conntrack_udp_timeout = 30
        net.netfilter.nf_conntrack_udp_timeout_stream = 180
        
        • du coup la différence brut est la suivante :
        < net.netfilter.nf_conntrack_frag6_timeout = 60
        ---
        > net.netfilter.nf_conntrack_events_retry_timeout = 15
        10,11d9
        < net.netfilter.nf_conntrack_gre_timeout = 30
        < net.netfilter.nf_conntrack_gre_timeout_stream = 180
        13d10
        < net.netfilter.nf_conntrack_icmpv6_timeout = 30
        34c31
        < net.netfilter.nf_conntrack_udp_timeout_stream = 120
        ---
        > net.netfilter.nf_conntrack_udp_timeout_stream = 180
        
        • donc les valeurs différentes sur CentOS 8 sont :
        net.netfilter.nf_conntrack_frag6_timeout
          - présente uniquement sur CentOS 8
          - elle n'existe pas sur CentOS 7
          - ça semble concerner IPv6 et nous n'utilisons IPv6
        
        net.netfilter.nf_conntrack_gre_timeout
          - présente uniquement sur CentOS 7
          - elle n'existe pas sur CentOS 8
        
        net.netfilter.nf_conntrack_gre_timeout
        net.netfilter.nf_conntrack_gre_timeout_stream
          - présentes uniquement sur CentOS 8
          - elles n'existent pas sur CentOS 7
        
        net.netfilter.nf_conntrack_icmpv6_timeout
          - présente uniquement sur CentOS 8
          - elle n'existe pas sur CentOS 7
          - ça semble concerner IPv6 et nous n'utilisons IPv6
        
        net.netfilter.nf_conntrack_udp_timeout_stream
          - valeur en CentOS 7 : 180
          - valeur en CentOS 8 : 120
        

        Du coup je n'ai pas l'impression qu'il y ait quelque chose de ce côté là si ? Vous en pensez quoi ?

        Il pourrait y avoir éventuellement nf_conntrack_udp_timeout_stream à monter à 180 mais nous avons déjà fait cela implicitement en appliquant tous les sysctl de CentOS 7 sur CentOS 8 :(

        • [^] # Re: le firewall de centOS

          Posté par  . Évalué à 5.

          Un truc dans les règles firewall, c'est le

          ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
          

          qui va déjà contourner conntrack (et ruine l'intérêt de la policy drop par défaut). Ou c'est-ce que c'est mis en place pour que ça fonctionne ?

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: le firewall de centOS

            Posté par  . Évalué à 1.

            En réalité, nous avons ceci dans notre fichier iptables :

            # ESTABLISHED
            -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
            -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
            -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
            -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
            

            C'est plus historique qu'autre chose et ça n'a donc pas été mis en place pour que ça fonctionne car dès que le pare-feu est actif ça ne fonctionne plus.

            Du coup tu faisais bien référence à la policy INPUT (la seule en drop par défaut) ?
            Je suis pas le plus fort du monde mais il me semblait qu'il fallait ça pour maintenir les connexions établies fonctionnelles ?

            Petites informations à jour :

            • j'ai dit que le soucis se produisait après 4H30 : erreur de ma part - c'est 4H
            • nous avons notre essai en cours avec un kernel à jour (5.6.14) : pour l'instant nous avons 3 succès sur 4 avec le pare-feu activé (nous sommes dans une boucle ; la dernière itération est en cours)
            • [^] # Re: le firewall de centOS

              Posté par  . Évalué à 3. Dernière modification le 27 mai 2020 à 18:29.

              Je suis pas le plus fort du monde mais il me semblait qu'il fallait ça pour maintenir les connexions établies fonctionnelles ?

              Il le faut si ta policy est en drop et que tu n'as rien d'autre qui match. Mais dans ton cas, tu as un INPUT en DROP mais une règle ACCEPT ALL. Du coup, c'est assez contradictoire.

              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

              • [^] # Re: le firewall de centOS

                Posté par  . Évalué à 1.

                Désolé j'étais en congé hier et n'ai pas eu le temps de poster de nouvelles dans ce post.

                Je ne comprends pas le soucis avec les règles iptables :/
                Quand je disais que je n'étais pas le plus fort du monde j'ai oublié des mots : en réseau / pare-feu.

                Tu me dis :

                Il le faut si ta policy est en drop et que tu n'as rien d'autre qui match. Mais dans ton cas, tu as un INPUT en DROP mais une règle ACCEPT ALL. Du coup, c'est assez contradictoire.
                

                Autant en OUTPUT, les deux règles semblent inutiles vu que l'on est en ACCEPT par défaut.
                Autant en INPUT je ne comprends pas. L'idée est pas justement d'autoriser une connexion déjà initiée quand il y a un changement de port dans la chaîne ? L'exemple typique qui me viendrait est le cas de FTP.

                On a pas encore essayé en désactivant ces règles mais on va tenter de tester ça aujourd'hui :)

                Par contre, on a testé un kernel 5.6.14 compilé par nous et ça fonctionne.
                On a pris le fichier config d'origine RedHat et pour toutes les nouvelles valeurs on a laissé les valeurs par défaut.

                Il semble donc qu'il y ait quelque chose entre 4.18 et 5.6.

                • [^] # Re: le firewall de centOS

                  Posté par  . Évalué à 1.

                  Nous venons de lancer l'essai en désactivant ces 4 règles d'iptables :

                  -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                  -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                  -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                  

                  -> ça ne marche pas du tout : notre connexion se fait pas et on tombe en timeout.

                  Il a fallu faire ça :

                  -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                  # -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                  # -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                  
                  • [^] # Re: le firewall de centOS

                    Posté par  . Évalué à 3.

                    Dans ce que tu as montré plus haut:

                    # sudo iptables -L -n
                    Chain INPUT (policy DROP)
                    target prot opt source destination

                    ACCEPT all — 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
                    ACCEPT all — 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
                    ACCEPT all — 0.0.0.0/0 0.0.0.0/0

                    Tu as une règle qui accepte tout (sans tenir compte de l'état). Du coup, ça me semble bizarre que cette règle ne soit pas suffisante.

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                    • [^] # Re: le firewall de centOS

                      Posté par  . Évalué à 1.

                      Désolé je n'ai pas été très actif sur ce problème car fort occupé ces derniers jours.

                      Alors effectivement le résultat d'un iptables -L -n mets le doute sur ce fameux ACCEPT ALL et je comprends mieux ton raisonnement maintenant :)

                      Par contre je pense que c'est juste une sorte d'erreur d'affichage/d'interprétation car voici 100% des règles que l'on applique :

                      *filter
                      # POLICY
                      :FORWARD DROP [0:0]
                      :INPUT DROP [0:0]
                      :OUTPUT ACCEPT [0:0]
                      
                      # ESTABLISHED
                      -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                      -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                      -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                      -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                      
                      # WHOLE INTERFACE IN AND OUT
                      -A INPUT -i lo -j ACCEPT
                      
                      # WHOLE PROTOCOL
                      -A INPUT -p icmp -j ACCEPT
                      
                      # WHOLE PORT
                      -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
                      
                      # HOST AND PORT
                      -A INPUT -i eth0 -p tcp -s <ip1> --dport 9100 -j ACCEPT
                      -A INPUT -i eth0 -p tcp -s <ip2> --dport 5565 -j ACCEPT
                      
                      
                      # REJECT ANYTHING ELSE
                      -A FORWARD -j REJECT --reject-with icmp-host-prohibited
                      -A INPUT -j REJECT --reject-with icmp-host-prohibited
                      COMMIT
                      

                      Mes collègues ont continué les tests.

                      En compilant un kernel 5.6.14 en partant du fichier config de RedHat et en laissant le reste par défaut : le pg_restore fonctionne.

                      En remettant le kernel d'origine + en désactivant ce qui suit le pg_restore failed toujours :

                      -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                      -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                      

                      Nous avons regardé à quoi ressemblaient les règles NFT sur le kernel d'origine et sur le nouveau (5.6.14) et il y a une différence.
                      On a donc essayé d'appliquer les même règles NFT sur le kernel d'origne : pg_restore failed toujours

                      Nous avons regardé à quoi ressemblaient les paramètres sysctl avec le nouveau kernel. Nous avons trouvé une différence qui aurait pu être intéressante :

                      net.ipv4.tcp_limit_output_bytes = 262144 --> net.ipv4.tcp_limit_output_bytes = 1048576
                      

                      Nous l'avons testé sur le kernel d'origine et le pg_restore failed toujours.

                      Notre prochain test va consister à prendre la dernière release disponible sur kernel.org pour le kernel 4.18 + le compiler + tester :)

                      • [^] # Re: le firewall de centOS

                        Posté par  . Évalué à 3.

                        Par contre je pense que c'est juste une sorte d'erreur d'affichage/d'interprétation car voici 100% des règles que l'on applique

                        Je pense que ça vient de la règle -A INPUT -i lo -j ACCEPT. Une bonne liste d'option pour iptables, c'est iptable -nvL, ça indique l'interface en plus. Donc, un point qui pourrait aider pour cibler le debug, c'est d'ajouter un -I INPUT -j ACCEPT pour valider que c'est bien conntrack qui pose problème.

                        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                        • [^] # Re: le firewall de centOS

                          Posté par  . Évalué à 1.

                          Il semble que cette piste (conntrack) soit la bonne :

                          • nous avons dégagé ces règles :
                          -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                          -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
                          
                          • nous avons remplacé par :
                          -A INPUT -j ACCEPT
                          

                          Et nous avons réussi un lot de pg_restore ;)

                          Nous allons analyser les paramètres sysctl liés à conntrack: ça j'y crois pas vu que l'on avait copié toutes les valeurs.

                          Et nous allons essayer un kernel 4.19.

                          Sauf si tu as une meilleure piste ?

                          Je te remercie :)

                          • [^] # Re: le firewall de centOS

                            Posté par  . Évalué à 3. Dernière modification le 09 juin 2020 à 13:48.

                            Sauf si tu as une meilleure piste ?

                            Personnellement, je ferrais un tcpdump pour voir à quel moment la connexion est fermée. Mais ça demande un peu de temps pour comprendre ce qui se passe quand on n'a pas l'habitude.

                            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                          • [^] # Re: le firewall de centOS

                            Posté par  . Évalué à 2.

                            Moi je dirais comme ca que c'est normal

                            si tu n'as pas de --state NEW, il ne peut pas ouvrir de nouveau port

                            et ton -A INPUT -j ACCEPT il force le fait d'accepter les NEW et les RELATED et les ESTABLISHED

                            • [^] # Re: le firewall de centOS

                              Posté par  . Évalué à 3.

                              Il ne fait que des connexions sortante, donc pas besoin de state new (ou seulement en output).

                              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                              • [^] # Re: le firewall de centOS

                                Posté par  . Évalué à 1.

                                En faites il y a eu une imcompréhension entre un collègue et moi à propos du test avec "-A INPUT -j ACCEPT" :
                                - 3 pg_restore sur 4 ont fonctionné
                                - 1 pg_restore sur 4 a échoué avec la même erreur

                                Du coup c'est pas vraiment un succès :(

                                • [^] # Re: le firewall de centOS

                                  Posté par  . Évalué à 3. Dernière modification le 10 juin 2020 à 10:27.

                                  Mais du coup, ça semble mettre de côté conntrack (ou en tout cas, ce n'est pas le seul problème).

                                  Du coup, je ferrais un tcpdump pour voir si une des deux parties envoit des SYN sans réponse ou un FIN/RST, ça permettra de comprendre plus facilement la source du problème.

                                  « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                                  • [^] # Re: le firewall de centOS

                                    Posté par  . Évalué à 1.

                                    Nous avons pas mal galéré avec le tcpdump car même en essayant de le cibler sur les dernières minutes il produit trop de logs et nous n'avions pas la place de stocker sur cette machine…

                                    Du coup on a continué de diguer sans.

                                    A cet instant T pour résumer ce qui fonctionne
                                    - kernel 4.18 d'origine + désactivation iptables
                                    - kernel 5.6 compilé par nos soins
                                    - kernel 4.19 compilé par nos soins

                                    Et la nous avons testé autre chose… : update en CentOS 8.2 (bon timing ; ça a été releasé il y a peu) : 4 pg_restore ont fonctionné
                                    Bon j'ai lu tout le changelog de RedHat et je ne vois rien qui puisse l'expliquer…

                                    Mais du coup nous avons lancé un gros run de 12 pg_restore pour nous amener jusqu'à lundi et voir ce que ça racconte ;)

                                    • [^] # Re: le firewall de centOS

                                      Posté par  . Évalué à 3.

                                      il produit trop de logs et nous n'avions pas la place de stocker sur cette machine…

                                      Dans ce cas, on peut se limiter aux headers tcp et donc un tcpdump -s 40 devrait suffire et limite la taille des logs.

                                      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                                      • [^] # Re: le firewall de centOS

                                        Posté par  . Évalué à 1.

                                        Bonjour,

                                        Désolé pour cette longue absence mais j'ai été pas mal occupé ces derniers temps.

                                        Alors désolé mais du coup nous n'avons pas réalisés le tcpdump pour l'instant : n'y voyez pas un message négatif du genre "il s'en moque de ce que l'on racconte".

                                        C'est juste qu'en parallèle on testait pas mal de trucs (cf. tout l'historique) et que nous sommes arrivés à un résultat positif en faisant la mise à jour CentOS 8.1 -> 8.2.

                                        Le rollback étant délicat, on préfère attendre de voir si le problème se reproduit pour jouer du tcpdump :) Pour l'instant nos tests ont été des succès mais attendrons le grand bain des refresh "naturels" (je crois que c'est ce week-end).

                                        • [^] # Re: le firewall de centOS

                                          Posté par  . Évalué à 3.

                                          Pas de soucis, je comprends bien. C'ếtait plus pour donner une idée si le problème se reproduit ou si quelqu'un d'autre tombe sur le thread.

                                          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                                          • [^] # Re: le firewall de centOS

                                            Posté par  . Évalué à 1.

                                            Je comprends la logique : d'ailleurs je déteste tomber sur un post dans lequel la personne ne réponds plus et où il n'y a pas la solution… :)

                                            Bien que nous n'ayons pas plus approfondi la piste du tcpdump que ça, je pense que de toute façon la solution serait passée par une mise à jour de quelque chose.

                                            Donc si quelqu'un a le même soucis, je pense que la solution c'était la mise à jour du kernel qui est venu avec CentOS 8.2 : il doit y avoir un patch dedans qui a réglé notre problème.

                                            En espérant que ça aidera :)

                                            Merci encore à tous pour l'aide apportée.

  • # Tcpdump ?

    Posté par  . Évalué à 2.

    Est-ce que vcus avez essayé de logguer le traffic avec tcpdump ? (en commençant au bout de 3h50 pour pas avoir un truc trop gros).
    Ça permettrait de voir si par hazard il n'y aurait des échanges bizarres entre les machines.

    • [^] # Re: Tcpdump ?

      Posté par  . Évalué à 1. Dernière modification le 03 juin 2020 à 08:27.

      Non on a pas essayé avec tcpdump.
      Par contre on a joué du strace et on a déjà eu ce genre de choses :

      recvfrom(6, 0x5172353, 5, 0, NULL, NULL) = -1 ECONNRESET (Connection reset by peer)
      sendto(6, "\25\3\3\0\32\272\362\307j\311"..., 31, MSG_NOSIGNAL, NULL, 0) = -1 EPIPE (Broken pipe)
      

      Nous pouvons effectivement essayer avec tcpdump mais je doute que l'on verra beaucoup de choses vu que nous sommes chiffrés en SSL. Nous verrons certainement une petite partie mais pas tout :)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.