Astuce : un petit script pour alterner entre vos deux stacks DNS-DoT et DNS-DoH

l’Almanet doLys Gnu/Linux – Open Source – Entreprises Forums L’almanet doLys Open Source Astuce : un petit script pour alterner entre vos deux stacks DNS-DoT et DNS-DoH

  • This topic is empty.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Articles
  • #12841
    nam1962nam1962
    Keymaster

      Basculer facilement entre DoT, DoH, et Fallback DNS avec un script Linux

      Si, comme moi, vous souhaitez disposer de plusieurs configurations DNS sécurisées et souveraines tout en limitant la censure, voici un outil pratique pour basculer facilement entre les méthodes DoT, DoH, et un mode Fallback en cas de panne.

      Rappel : DoT vs DoH vs Fallback

      • DNS over TLS (DoT) : Utilise le chiffrement TLS sur un port dédié (853). Plus facile à identifier sur le réseau, mais offre une bonne sécurité avec validation DNSSEC.
      • DNS over HTTPS (DoH) : Masque les requêtes DNS dans le trafic HTTPS normal (port 443). Idéal pour contourner les blocages DNS et la censure, car quasi indiscernable du trafic web habituel.
      • Fallback DNS : En cas de panne de votre DNS local (Pi-hole, Unbound, ou DNSCrypt), bascule vers des serveurs DNS publics fiables pour maintenir la connectivité.

      Prérequis

      • Docker et Docker Compose installés (pour les stacks DoT et DoH).
      • yad pour l’interface graphique (optionnel) : sudo apt install yad
      • Dossiers Docker configurés :
        • DoT : ~/docker/dns-dot (avec Unbound et Pi-hole).
        • DoH : ~/docker/dns-doh (avec DNSCrypt-Proxy et Pi-hole).

      1. Script en ligne de commande

      Créez le script dans votre répertoire bin :

      
      mkdir -p ~/bin
      nano ~/bin/switch-dns
      

      Contenu du script :

      
      #!/bin/bash
      set -euo pipefail
      
      # Déterminer le dossier personnel de l'utilisateur réel
      USER_HOME="$HOME"
      if [[ -z "$USER_HOME" || "$USER_HOME" == "/root" ]]; then
          USER_HOME="$(getent passwd "$(whoami)" | cut -d: -f6)"
      fi
      DNS_PIHOLE_IP="127.0.0.1"
      DOT_DIR="$USER_HOME/docker/dns-dot"
      DOH_DIR="$USER_HOME/docker/dns-doh"
      LOGFILE="$USER_HOME/dns-check.log"
      FALLBACK_DNS1="94.140.14.14"  # AdGuard DNS
      FALLBACK_DNS2="45.90.28.0"    # NextDNS
      
      # Fonction pour activer le fallback DNS
      enable_fallback() {
          echo "[dns-fallback] $(date): DNS local indisponible, fallback activé" >> "$LOGFILE"
          echo -e "nameserver $FALLBACK_DNS1\nnameserver $FALLBACK_DNS2" | sudo tee /etc/resolv.conf > /dev/null
      }
      
      # Vérifier la disponibilité du DNS local
      check_local_dns() {
          dig +time=3 +tries=1 whoami.akamai.net @$DNS_PIHOLE_IP > /dev/null 2>&1
      }
      
      # Afficher l'état actuel si aucun argument
      if [[ $# -eq 0 ]]; then
          DOCKER_STATE=$(docker ps --format '{{.Names}}' 2>/dev/null || echo "Aucun conteneur actif")
          echo "[switch-dns] $(date): DOCKER_STATE='$DOCKER_STATE'" >> "$LOGFILE"
          if echo "$DOCKER_STATE" | grep -q pihole; then
              if echo "$DOCKER_STATE" | grep -q unbound; then
                  echo "[switch-dns] $(date): Détection Unbound (DoT)" >> "$LOGFILE"
                  echo "Stack active : Unbound (DoT)"
              elif echo "$DOCKER_STATE" | grep -q dnscrypt; then
                  echo "[switch-dns] $(date): Détection DNSCrypt-Proxy (DoH)" >> "$LOGFILE"
                  echo "Stack active : DNSCrypt-Proxy (DoH)"
              else
                  echo "[switch-dns] $(date): Pi-hole actif mais réseau inconnu" >> "$LOGFILE"
                  echo "Aucune stack DNS actuellement active"
              fi
          else
              echo "[switch-dns] $(date): Aucun conteneur Pi-hole actif" >> "$LOGFILE"
              echo "Aucune stack DNS actuellement active"
          fi
          exit 0
      fi
      
      # Vérifier l'argument
      if [[ "$1" == "fallback" ]]; then
          sudo -v
          # Ajuster USER_HOME après sudo
          if [[ -n "${SUDO_USER:-}" ]]; then
              USER_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
              DOT_DIR="$USER_HOME/docker/dns-dot"
              DOH_DIR="$USER_HOME/docker/dns-doh"
          fi
          # Arrêter les stacks
          echo "Arrêt des stacks DNS..."
          if [ -d "$DOT_DIR" ]; then
              cd "$DOT_DIR" && docker-compose down
          fi
          if [ -d "$DOH_DIR" ]; then
              cd "$DOH_DIR" && docker-compose down
          fi
          # Activer Fallback
          enable_fallback
          echo "DNS de secours activés."
          exit 0
      elif [[ "$1" != "dns-dot" && "$1" != "dns-doh" ]]; then
          echo "Usage: switch-dns [dns-dot|dns-doh|fallback]"
          exit 1
      fi
      
      sudo -v
      
      # Après sudo, ajuster USER_HOME
      if [[ -n "${SUDO_USER:-}" ]]; then
          USER_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
          DOT_DIR="$USER_HOME/docker/dns-dot"
          DOH_DIR="$USER_HOME/docker/dns-doh"
          LOGFILE="$USER_HOME/dns-check.log"
      fi
      
      # Activer le fallback avant le basculement si le DNS local est déjà down
      if ! check_local_dns; then
          enable_fallback
      fi
      
      # Basculement
      if [[ "$1" == "dns-doh" ]]; then
          echo "Arrêt de dns-dot..."
          if [ -d "$DOT_DIR" ]; then
              cd "$DOT_DIR" && docker-compose down
          else
              echo "Dossier dns-dot introuvable: $DOT_DIR, mais on continue..."
          fi
          echo "Démarrage de dns-doh..."
          cd "$DOH_DIR" || { echo "Dossier introuvable: $DOH_DIR"; exit 1; }
          docker-compose up -d
      else
          echo "Arrêt de dns-doh..."
          if [ -d "$DOH_DIR" ]; then
              cd "$DOH_DIR" && docker-compose down
          else
              echo "Dossier dns-doh introuvable: $DOH_DIR, mais on continue..."
          fi
          echo "Démarrage de dns-dot..."
          cd "$DOT_DIR" || { echo "Dossier introuvable: $DOT_DIR"; exit 1; }
          docker-compose up -d
      fi
      
      # Attendre que la nouvelle stack soit opérationnelle (max 10s)
      echo "Vérification de la nouvelle stack..."
      for i in {1..10}; do
          if check_local_dns; then
              echo "Redirection DNS locale → Pi-hole"
              echo "nameserver $DNS_PIHOLE_IP" | sudo tee /etc/resolv.conf > /dev/null
              echo "Stack '$1' activée."
              exit 0
          fi
          sleep 1
      done
      
      # Si la stack n'est pas opérationnelle, activer le fallback
      echo "Échec du démarrage de la stack '$1', activation du fallback..."
      enable_fallback
      echo "Stack '$1' démarrée, mais DNS local non fonctionnel. Fallback activé."
      exit 1
      

      Rendez le script exécutable :

      
      chmod +x ~/bin/switch-dns
      

      2. Interface graphique (optionnel)

      Pour plus de confort, nous pouvons créer une interface graphique avec yad :

      Étape 1 : Script pour la demande de mot de passe

      
      nano ~/bin/yad-askpass.sh
      

      Contenu :

      
      #!/bin/bash
      yad --entry --title="Authentification requise" \
      --text="Veuillez entrer votre mot de passe pour continuer :" \
      --hide-text --center
      

      Étape 2 : Script pour l’interface graphique

      
      nano ~/bin/dns-switcher-gui.sh
      

      Contenu :

      
      #!/bin/bash
      export SUDO_ASKPASS="$HOME/bin/yad-askpass.sh"
      SWITCH_SCRIPT="$HOME/bin/switch-dns"
      RESOLV_CONF="/etc/resolv.conf"
      FALLBACK_DNS1="94.140.14.14"  # AdGuard DNS
      FALLBACK_DNS2="45.90.28.0"    # NextDNS
      LOCAL_DNS="127.0.0.1"
      LOGFILE="$HOME/dns-switcher-gui.log"
      
      # Vérifier que le script de bascule existe
      if [ ! -x "$SWITCH_SCRIPT" ]; then
          yad --error --title="DNS Switcher" --text="Script de basculement introuvable à : $SWITCH_SCRIPT"
          exit 1
      fi
      
      # Vérifier si le DNS local répond
      check_local_dns() {
          dig +time=3 +tries=1 whoami.akamai.net @$LOCAL_DNS >/dev/null 2>&1
      }
      
      # Vérifier les conteneurs Docker
      DOCKER_STATE=$(docker ps --format '{{.Names}}' 2>/dev/null || echo "Aucun conteneur actif")
      FALLBACK_ACTIVE=$(grep -qE "^nameserver\s+($FALLBACK_DNS1|$FALLBACK_DNS2)" "$RESOLV_CONF" && echo "true" || echo "false")
      LOCAL_DNS_ACTIVE=$(grep -qE "^nameserver\s+$LOCAL_DNS" "$RESOLV_CONF" && check_local_dns && echo "true" || echo "false")
      
      # Déterminer l'état
      if [ "$LOCAL_DNS_ACTIVE" = "true" ] && echo "$DOCKER_STATE" | grep -q pihole; then
          if echo "$DOCKER_STATE" | grep -q unbound; then
              CURRENT_MODE="dns-dot"
              DISPLAY_STATE="Stack active : Unbound (DoT)"
              DOT_CHECKED="TRUE"
              DOH_CHECKED="FALSE"
              FALLBACK_CHECKED="FALSE"
          elif echo "$DOCKER_STATE" | grep -q dnscrypt; then
              CURRENT_MODE="dns-doh"
              DISPLAY_STATE="Stack active : DNSCrypt-Proxy (DoH)"
              DOT_CHECKED="FALSE"
              DOH_CHECKED="TRUE"
              FALLBACK_CHECKED="FALSE"
          else
              CURRENT_MODE="aucune"
              DISPLAY_STATE="Aucune stack DNS active"
              DOT_CHECKED="TRUE"
              DOH_CHECKED="FALSE"
              FALLBACK_CHECKED="FALSE"
          fi
      elif [ "$FALLBACK_ACTIVE" = "true" ]; then
          CURRENT_MODE="fallback"
          DISPLAY_STATE="DNS de secours actifs (Fallback)"
          DOT_CHECKED="FALSE"
          DOH_CHECKED="FALSE"
          FALLBACK_CHECKED="TRUE"
      else
          CURRENT_MODE="aucune"
          DISPLAY_STATE="Aucune stack DNS active"
          DOT_CHECKED="TRUE"
          DOH_CHECKED="FALSE"
          FALLBACK_CHECKED="FALSE"
      fi
      
      # Débogage : enregistrer l'état
      echo "[dns-switcher-gui] $(date): CURRENT_MODE='$CURRENT_MODE', DISPLAY_STATE='$DISPLAY_STATE'" >> "$LOGFILE"
      
      # Affichage du menu avec l'état actuel
      CHOICE=$(yad --width=550 --height=300 --center --title="DNS Switcher" \
          --text="Configuration DNS\n\nÉtat actuel : $DISPLAY_STATE\n\nSélectionnez une stack ou les DNS de secours :" \
          --list --radiolist --no-headers \
          --column="Sélection" --column="Type" --column="Description" \
          "$DOT_CHECKED" "dns-dot" "Unbound - Sécurité maximale, DNSSEC" \
          "$DOH_CHECKED" "dns-doh" "DNSCrypt - Anti-censure" \
          "$FALLBACK_CHECKED" "fallback" "Fallback - DNS de secours AdGuard/NextDNS")
      
      # Vérifier si l'utilisateur a annulé
      [ $? -ne 0 ] && exit 0
      
      # Extraire le choix sélectionné
      CHOICE_VALUE=$(echo "$CHOICE" | cut -d'|' -f2)
      
      # Exécuter le choix
      RESULT=$(sudo -A "$SWITCH_SCRIPT" "$CHOICE_VALUE" 2>&1)
      EXIT_CODE=$?
      if [ $EXIT_CODE -eq 0 ]; then
          yad --info --title="DNS Switcher" --text="DNS configuré avec succès : $CHOICE_VALUE"
      else
          yad --error --title="DNS Switcher" --text="Erreur lors du basculement vers $CHOICE_VALUE :\n$RESULT"
      fi
      

      Étape 3 : Rendez les scripts exécutables

      
      chmod +x ~/bin/yad-askpass.sh
      chmod +x ~/bin/dns-switcher-gui.sh
      

      Étape 4 : Créez un raccourci dans le menu d’applications

      
      mkdir -p ~/.local/share/applications
      nano ~/.local/share/applications/dns-switcher.desktop
      

      Contenu :

      
      [Desktop Entry]
      Version=1.0
      Type=Application
      Name=DNS Switcher
      Comment=Basculer entre configurations DNS (DoH/DoT/Fallback)
      Exec=/home/VOTRE_UTILISATEUR/bin/dns-switcher-gui.sh
      Icon=network-server
      Terminal=false
      Categories=Network;System;
      Keywords=DNS;network;privacy;security;
      

      Remplacez VOTRE_UTILISATEUR par votre nom d’utilisateur (par exemple, sum).

      3. Utilisation

      En ligne de commande

      
      # Pour activer DNS over TLS (Unbound)
      ~/bin/switch-dns dns-dot
      
      # Pour activer DNS over HTTPS (DNSCrypt-Proxy)
      ~/bin/switch-dns dns-doh
      
      # Pour activer le mode Fallback (AdGuard/NextDNS)
      ~/bin/switch-dns fallback
      
      # Pour vérifier la configuration active
      ~/bin/switch-dns
      

      Avec l’interface graphique

      Lancez « DNS Switcher » depuis votre menu d’applications, sélectionnez la configuration souhaitée (DoT, DoH, ou Fallback), et entrez votre mot de passe lorsque demandé.

      4. Bonus : Script de vérification automatique (Fallback)

      Pour éviter de perdre la connectivité en cas de panne DNS locale, ajoutez ce script à votre crontab :

      
      nano ~/bin/dns-fallback-check.sh
      

      Contenu :

      
      #!/bin/bash
      # Fichier de log
      LOGFILE="$HOME/dns-check.log"
      
      # Configuration DNS
      LOCAL_DNS="127.0.0.1"
      FALLBACK_DNS1="94.140.14.14"  # AdGuard DNS
      FALLBACK_DNS2="45.90.28.0"    # NextDNS
      
      # Test du DNS local
      if ! dig +time=3 +tries=1 debian.org @$LOCAL_DNS > /dev/null 2>&1; then
          echo "[dns-fallback] $(date): DNS local indisponible, fallback activé" >> "$LOGFILE"
          echo -e "nameserver $FALLBACK_DNS1\nnameserver $FALLBACK_DNS2" | sudo tee /etc/resolv.conf > /dev/null
      else
          # Vérifier si on est en mode Fallback et si le DNS local est revenu
          if ! grep -q "$LOCAL_DNS" /etc/resolv.conf; then
              echo "[dns-fallback] $(date): DNS local restauré" >> "$LOGFILE"
              echo -e "nameserver $LOCAL_DNS" | sudo tee /etc/resolv.conf > /dev/null
          fi
      fi
      

      Rendez le script exécutable :

      
      chmod +x ~/bin/dns-fallback-check.sh
      

      Ajoutez-le à votre crontab (exécuté toutes les 5 minutes) :

      
      crontab -e
      

      Ajoutez cette ligne :

      
      */5 * * * * ~/bin/dns-fallback-check.sh
      

      Conclusion

      Ce système complet vous donne un contrôle total sur vos résolutions DNS, tout en assurant une haute disponibilité et une protection contre la censure. Discret et efficace, comme tout bon outil Linux !

      Un jeune site que j'aime bien, la ferrari du T-shirt ...bio en plus : GoudronBlanc

    Affichage de 1 message (sur 1 au total)
    • Vous devez être connecté pour répondre à ce sujet.