Script Shell: un bon moyen de vérifier la connectivité Internet?

26

J'ai trouvé des scripts qui disent qu'ils vérifient la connectivité Internet. Certains vérifient l'adresse IP si l'interface est en place MAIS elle ne vérifie pas la connectivité Internet. J'en ai trouvé qui utilisent ping comme ceci: if [ 'ping google.com -c 4 | grep time' != "" ]; thenmais parfois cela peut ne pas être fiable car le ping lui-même peut se bloquer pour une raison quelconque (par exemple, en attendant des E / S bloquées).

Avez-vous des suggestions sur la manière appropriée / fiable de vérifier la connectivité Internet à l'aide de scripts? Dois-je utiliser des packages?

Il doit être en mesure de vérifier périodiquement avec cronpar exemple, puis, faire quelque chose lorsque la connexion tombe en panne comme invoquerifup --force [interface]

PNDA
la source

Réponses:

29

Test de la connectivité IPv4

Si votre réseau laisse passer les pings, essayez de faire un ping sur 8.8.8.8 (un serveur géré par Google).

if ping -q -c 1 -W 1 8.8.8.8 >/dev/null; then
  echo "IPv4 is up"
else
  echo "IPv4 is down"
fi

Test de la connectivité IP et du DNS

Si vous souhaitez que le test réussisse uniquement lorsque DNS fonctionne également, utilisez un nom d'hôte.

if ping -q -c 1 -W 1 google.com >/dev/null; then
  echo "The network is up"
else
  echo "The network is down"
fi

Test de la connectivité Web

Certains pare-feu bloquent les pings. Certains endroits ont un pare-feu qui bloque tout le trafic, sauf via un proxy Web. Si vous souhaitez tester la connectivité Web, vous pouvez effectuer une demande HTTP.

case "$(curl -s --max-time 2 -I http://google.com | sed 's/^[^ ]*  *\([0-9]\).*/\1/; 1q')" in
  [23]) echo "HTTP connectivity is up";;
  5) echo "The web proxy won't let us through";;
  *) echo "The network is down or very slow";;
esac
Gilles 'SO- arrête d'être méchant'
la source
Vous souhaiterez peut-être incorporer la validation d'une connexion physique (couche OSI 1) avant toute vérification de la couche 3 OSI utilisant ethtool; $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas-
Pouvez-vous expliquer le but de l'ajout s'il vous plaît>/dev/null
Amine Harbaoui
@AmineHarbaoui - >/dev/nullredirige la sortie standard vers /dev/null, le périphérique nul , qui en dispose car il n'est pas souhaité dans ce cas (tout ce qui nous intéresse est les valeurs de sortie des commandes). Au lieu de cela, une sortie plus applicable est tirée des echolignes.
Adam Katz
27

Je recommande fortement de ne pas l' utiliser pingpour déterminer la connectivité. Il y a trop d'administrateurs de réseau qui désactivent ICMP (le protocole qu'il utilise) en raison des inquiétudes liées aux attaques par inondation ping provenant de leurs réseaux.

Au lieu de cela, j'utilise un test rapide d'un serveur fiable sur un port que vous pouvez vous attendre à ouvrir:

if nc -zw1 google.com 443; then
  echo "we have connectivity"
fi

Cela utilise netcat ( nc) dans son mode de balayage de port , un coup rapide ( -zest le mode zéro E / S [utilisé pour le balayage] ) avec un délai d'attente rapide ( -w 1attend au plus une seconde). Il vérifie Google sur le port 443 (HTTPS).

J'ai utilisé HTTPS plutôt que HTTP pour me protéger contre les portails captifs et les proxys transparents qui peuvent répondre sur le port 80 (HTTP) pour tout hôte. Cela est moins probable lors de l'utilisation du port 443 car il y aurait une incompatibilité de certificat, mais cela se produit toujours.

Si vous souhaitez vous protéger contre cela, vous devrez valider la sécurité de la connexion:

test=google.com
if nc -zw1 $test 443 && echo |openssl s_client -connect $test:443 2>&1 |awk '
  handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 }
  $1 $2 == "SSLhandshake" { handshake = 1 }'
then
  echo "we have connectivity"
fi

Cela vérifie une connexion (plutôt que d'attendre qu'opssl expire), puis effectue la négociation SSL, en tapant sur la phase de vérification. Il se ferme silencieusement ("vrai") si la vérification était "OK" ou bien se termine avec une erreur ("faux"), alors nous rapportons la constatation.

Adam Katz
la source
5
Je respecte Gillies mais c'est la bonne réponse.
gwillie
3
ajoutez -dpar exemple nc -dzw1aussi pour qu'il n'écoute pas STDIN et se bloque indéfiniment dans un script. et peut-être utiliser 8.8.8.8 au lieu de google.com pour enregistrer une recherche. nc -dzw1 8.8.8.8 443
dezza
Je ne suis pas sûr de la fiabilité du résolveur DNS de Google pour servir HTTPS. Le serveur google.com devrait être plus fiable pour HTTPS (sauf si vous êtes en Chine, mais les deux sont probablement bloqués). Je n'en ai jamais eu besoin -ddans mes scripts, peut-être parce que je n'ai jamais eu de pipeline inutilisé. Cela devrait être sûr d'ajouter.
Adam Katz
1
@dezza - -w 1coûte toujours une seconde lorsqu'il n'y a pas de connectivité, bien que vous ncayez peut-être une sorte de problème obscur quelque part. Si vous avez une version récente de nmap installée, vous pouvez à la place faire ncat --send-only --recv-only -w 334mspour réduire ce temps d'échec à un tiers nc(j'ai trouvé que 334 ms est un bon temps d'attente).
Adam Katz
1
@dezza - Je ne sais pas pourquoi cela vous arrive à la fois sur ncat et netcat (nc) de nmap pour ce système. Il se peut qu'il se passe quelque chose d'étrange dans votre réseau ou sur ce système BSD. N'hésitez pas à créer une nouvelle question unix.stackexchange et à avoir plus que mes yeux sur ce problème. Si vous le faites, veuillez le lier dans les commentaires ici et lier ce fil à votre nouvelle question.
Adam Katz
9

J'ai fait un script qui utilise plusieurs façons de vérifier la connexion Internet (ping, nc et curl, grâce à Adam Katz, Gilles et Archemar). J'espère que quelqu'un trouve cela utile. N'hésitez pas à le modifier à votre guise / à l'optimiser.

Vérifie votre passerelle, DNS et connexion Internet (en utilisant curl, nc et ping). Mettez-le dans un fichier puis rendez-le exécutable (généralement sudo chmod +x filename)

#!/bin/bash

GW=`/sbin/ip route | awk '/default/ { print $3 }'`
checkdns=`cat /etc/resolv.conf | awk '/nameserver/ {print $2}' | awk 'NR == 1 {print; exit}'`
checkdomain=google.com

#some functions

function portscan
{
  tput setaf 6; echo "Starting port scan of $checkdomain port 80"; tput sgr0;
  if nc -zw1 $checkdomain  80; then
    tput setaf 2; echo "Port scan good, $checkdomain port 80 available"; tput sgr0;
  else
    echo "Port scan of $checkdomain port 80 failed."
  fi
}

function pingnet
{
  #Google has the most reliable host name. Feel free to change it.
  tput setaf 6; echo "Pinging $checkdomain to check for internet connection." && echo; tput sgr0;
  ping $checkdomain -c 4

  if [ $? -eq 0 ]
    then
      tput setaf 2; echo && echo "$checkdomain pingable. Internet connection is most probably available."&& echo ; tput sgr0;
      #Insert any command you like here
    else
      echo && echo "Could not establish internet connection. Something may be wrong here." >&2
      #Insert any command you like here
#      exit 1
  fi
}

function pingdns
{
  #Grab first DNS server from /etc/resolv.conf
  tput setaf 6; echo "Pinging first DNS server in resolv.conf ($checkdns) to check name resolution" && echo; tput sgr0;
  ping $checkdns -c 4
    if [ $? -eq 0 ]
    then
      tput setaf 6; echo && echo "$checkdns pingable. Proceeding with domain check."; tput sgr0;
      #Insert any command you like here
    else
      echo && echo "Could not establish internet connection to DNS. Something may be wrong here." >&2
      #Insert any command you like here
#     exit 1
  fi
}

function httpreq
{
  tput setaf 6; echo && echo "Checking for HTTP Connectivity"; tput sgr0;
  case "$(curl -s --max-time 2 -I $checkdomain | sed 's/^[^ ]*  *\([0-9]\).*/\1/; 1q')" in
  [23]) tput setaf 2; echo "HTTP connectivity is up"; tput sgr0;;
  5) echo "The web proxy won't let us through";exit 1;;
  *)echo "Something is wrong with HTTP connections. Go check it."; exit 1;;
  esac
#  exit 0
}


#Ping gateway first to verify connectivity with LAN
tput setaf 6; echo "Pinging gateway ($GW) to check for LAN connectivity" && echo; tput sgr0;
if [ "$GW" = "" ]; then
    tput setaf 1;echo "There is no gateway. Probably disconnected..."; tput sgr0;
#    exit 1
fi

ping $GW -c 4

if [ $? -eq 0 ]
then
  tput setaf 6; echo && echo "LAN Gateway pingable. Proceeding with internet connectivity check."; tput sgr0;
  pingdns
  pingnet
  portscan
  httpreq
  exit 0
else
  echo && echo "Something is wrong with LAN (Gateway unreachable)"
  pingdns
  pingnet
  portscan
  httpreq

  #Insert any command you like here
#  exit 1
fi
PNDA
la source
Agréable ! Je vous remercie ! À quoi devons-nous définir la passerelle $GW?
Ciprian Tomoiagă
@CiprianTomoiaga Pas besoin, /sbin/ip route | awk '/default/ { print $3 }'obtient l'adresse de la passerelle depuis l'interface (espérons-le) principale. Si vous le souhaitez, vous pouvez définir vous-même l'adresse IP de la passerelle.
PNDA
Merci pour cela! Ce qui me manque cependant, c'est la possibilité de stocker les perturbations Internet dans un fichier txt et un e-mail automatisé à mon FAI.
puis
2

il existe de nombreuses adresses IP sur Internet, une approche légère consiste à cingler certains d'entre eux

 if ping -c 4 google.com ; then OK ; else KO ; fi
 if ping -c 4 facebook.com ; then OK ; else KO ; fi
 if ping -c 4 nsa.gov ; then OK ; else KO ; fi # <- this one might not reply

une réponse plus complète pourrait être d'obtenir des pages en utilisant wget

 wget google.com -o google.txt
 if parse google.txt ; then OK ; else KO ; fi

  • l'analyse est un programme que vous écrivez qui garantit que google.txt n'est pas une version (trop ancienne) mise en cache de google.com
Archemar
la source
1

grâce à vos contributions de chaque utilisateur et autre web, j'ai réussi à terminer ce script en 3 jours. et je le laisserai libre pour son utilisation.

ce script automatise le renouvellement de l'adresse IP lorsque la connexion est perdue, il le fait de manière persistante.

#!/bin/bash

# Autor: John Llewelyn
# FB: fb.com/johnwilliam.llewelyn
# Twitter: twitter.com/JWLLEWELYN
# TLF: +584-1491-011-15
# Its use is free.
# Description: Connection Monitor for ADSL modem.
# Requirements:
# Copy this code or save to /home/administrator/ConnectionMonitor.sh
# It requires the installed packages fping beep and cron
# Comment the blacklist pcspkr snd-pcsp in /etc/modprobe.d/blacklist.conf
# Give execute permissions: chmod +x /home/administrator/ConnectionMonitor.sh
# Add this line in crontab -e with root user
# @reboot sleep 120 && /home/administrator/MonitorDeConexion.sh

#################################################################################
# SETTINGS
TEST="8.8.8.8"       # TEST PING
ADAPTER1="enp4s0"    # EXTERNAL ETHERNET ADAPTER

# Report
LOGFILE=/home/administrator/Documentos/ReportInternet.log

# Messages
MESSAGE1="Restoring Connectivity..."
MESSAGE2="Wait a moment please..."
MESSAGE3="No Internet connectivity."
MESSAGE4="Yes, there is Internet connectivity."
#################################################################################

# Time and Date
TODAY=$(date "+%r %d-%m-%Y")

# Show IP Public Address
IPv4ExternalAddr1=$(ip addr list $ADAPTER1 |grep "inet " |cut -d' ' -f6|cut -d/ -f1)
IPv6ExternalAddr1=$(ip addr list $ADAPTER1 |grep "inet6 " |cut -d' ' -f6|cut -d/ -f1)

# Alarm
alarm() {
    beep -f 1500 -l 200;beep -f 1550 -l 200;beep -f 1500 -l 200;beep -f 1550 -l 200;beep -f 1500 -l 200;beep -f 1550 -l 200;beep -f 1500 -l 200;beep -f 1550$
}

# Restoring Connectivity
resolve() {
    clear
    echo "$MESSAGE1"
    sudo ifconfig $ADAPTER1 up;sudo dhclient -r $ADAPTER1;sleep 5;sudo dhclient $ADAPTER1
    echo "$MESSAGE2"
    sleep 120
}

# Execution of work
while true; do
    if [[ "$(fping -I $ADAPTER1 $TEST | grep 'unreachable' )" != "" ]]; then
        alarm
        clear
        echo "================================================================================" >> ${LOGFILE}
        echo "$MESSAGE3 - $TODAY"                                                               >> ${LOGFILE}
        echo "$MESSAGE3 - $TODAY"
        echo "================================================================================" >> ${LOGFILE}
        sleep 10
        resolve
    else
        clear
        echo "================================================================================"   >> ${LOGFILE}
        echo "$MESSAGE4 - $TODAY - IPv4 Addr: $IPv4ExternalAddr1 - IPv6 Addr: $IPv6ExternalAddr1" >> ${LOGFILE}
        echo "$MESSAGE4 - $TODAY - IPv4 Addr: $IPv4ExternalAddr1 - IPv6 Addr: $IPv6ExternalAddr1"
        echo "================================================================================"   >> ${LOGFILE}
        sleep 120
    fi
done

pastebin: https://pastebin.com/wfSkpgKA

John Llewelyn
la source
Ce qui améliorerait cette réponse: (1) Expliquer comment fonctionne le script. (Il semble que l'utilisateur doive éditer le script si son interface réseau s'appelle autre chose que eth0, mais cela n'est pas mentionné.) (2) Utiliser l'anglais. (3) Mettre toutes les variables du shell (par exemple "$HOST", "$LINE1"et "$LOG") entre guillemets. (4) Réglez LINE2ou ne l'utilisez pas. (Je pense que vous avez LINE1 /  LINE2confondre avec inet4 /  inet6.) ... (suite)
G-Man dit 'Réintégrer Monica'
(Suite)… (5) Afficher en fait l'heure actuelle lorsque vous dites que vous affichez l'heure actuelle, plutôt que de capturer l'heure au démarrage du script et de l'afficher pendant toute la durée de vie du script. (6) Je pense qu'il y avait autre chose, mais je ne le vois pas maintenant.
G-Man dit `` Réinstalle Monica ''
C'est en espagnol parce que c'est dans ma langue, mais je peux le corriger en anglais. $ HOST est l'adresse à essayer. $ LINE1 est la connexion Internet connectée par l'adaptateur eth0. $ LINE2 est la connexion Internet qui est éventuellement connectée par l'adaptateur eth1 si vous avez 2 lignes Internet, mais il est recommandé de la laisser désactivée. La date, si je vérifie qu'elle conserve la même heure et la même date depuis le démarrage du script, je dois corriger ce problème. Ce week-end, je corrige le problème.
John Llewelyn
Ok G-Man, j'ai fait quelques changements, j'ai encore besoin de corriger la date et d'améliorer certaines choses.
John Llewelyn