Shell Scripting: Richtige Methode zur Überprüfung der Internetverbindung?

26

Ich habe Skripte gefunden, die besagen, dass sie nach Internetverbindungen suchen. Einige überprüfen die IP-Adresse, wenn die Schnittstelle aktiv ist, jedoch nicht die Internetverbindung. Ich habe einige gefunden, die Ping wie folgt verwenden: if [ 'ping google.com -c 4 | grep time' != "" ]; thenManchmal kann dies jedoch unzuverlässig sein, da Ping selbst aus irgendeinem Grund hängen bleibt (z. B. wenn auf ein feststeckendes E / A gewartet wird).

Irgendwelche Vorschläge zur richtigen / zuverlässigen Überprüfung der Internetverbindung mithilfe von Skripten? Muss ich einige Pakete verwenden?

Es muss in der Lage sein, in regelmäßigen Abständen zu überprüfen cron, und dann etwas zu tun, wenn die Verbindung unterbrochen wirdifup --force [interface]

PNDA
quelle

Antworten:

29

Testen der IPv4-Konnektivität

Wenn Ihr Netzwerk Pings zulässt, versuchen Sie es mit Ping 8.8.8.8 (einem von Google betriebenen Server).

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

Testen der IP-Konnektivität und des DNS

Wenn der Test nur erfolgreich sein soll, wenn auch DNS funktioniert, verwenden Sie einen Hostnamen.

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

Testen der Webkonnektivität

Einige Firewalls blockieren Pings. Einige Orte haben eine Firewall, die den gesamten Datenverkehr blockiert, außer über einen Web-Proxy. Wenn Sie die Webkonnektivität testen möchten, können Sie eine HTTP-Anfrage stellen.

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 - hör auf böse zu sein'
quelle
Möglicherweise möchten Sie die Validierung einer physischen Verbindung (OSI-Schicht 1) einbeziehen, bevor Sie OSI-Schicht 3-Prüfungen mit ethtool durchführen. $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas
Können Sie den Zweck des Hinzufügens dieses bitte erklären>/dev/null
Amine Harbaoui
@AmineHarbaoui - Leitet >/dev/nulldie Standardausgabe an /dev/nulldas Null-Gerät um , das darüber verfügt, da dies in diesem Fall nicht erwünscht ist (alles, was uns interessiert, sind die Exit-Werte der Befehle). Stattdessen wird eine zutreffendere Ausgabe aus den echoZeilen entnommen .
Adam Katz
27

Ich empfehle gegen mit pingKonnektivität zu bestimmen. Es gibt zu viele Netzwerkadministratoren, die ICMP (das verwendete Protokoll) deaktivieren, weil sie sich Sorgen über Ping-Flood- Angriffe machen, die von ihren Netzwerken ausgehen.

Stattdessen benutze ich einen schnellen Test eines zuverlässigen Servers an einem Port, von dem Sie erwarten können, dass er offen ist:

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

Dies verwendet netcat ( nc) in seinem Port-Scan- Modus, einem schnellen Poke ( -zist der Null-E / A-Modus [zum Scannen verwendet] ) mit einem schnellen Timeout ( -w 1wartet höchstens eine Sekunde). Es überprüft Google auf Port 443 (HTTPS).

Ich habe HTTPS anstelle von HTTP verwendet, um mich vor unverlierbaren Portalen und transparenten Proxys zu schützen, die für jeden Host auf Port 80 (HTTP) antworten können. Dies ist weniger wahrscheinlich, wenn Port 443 verwendet wird, da ein Zertifikat nicht übereinstimmt, dies jedoch immer noch der Fall ist.

Wenn Sie sich dagegen behaupten möchten, müssen Sie die Sicherheit der Verbindung überprüfen:

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

Dies prüft auf eine Verbindung (anstatt auf eine Zeitüberschreitung von openssl zu warten) und führt dann den SSL-Handshake durch, wobei die Überprüfungsphase verschlüsselt wird. Es wird stillschweigend beendet ("true"), wenn die Überprüfung "OK" war, oder es wird mit einem Fehler beendet ("false"), und der Befund wird gemeldet.

Adam Katz
quelle
5
Ich respektiere Gillies, aber das ist die richtige Antwort.
Gwillie
3
füge -dzB nc -dzw1auch hinzu, damit es nicht auf STDIN lauscht und unbegrenzt in einem Skript hängt. und vielleicht verwenden Sie 8.8.8.8 anstelle von google.com, um eine Suche zu speichern. nc -dzw1 8.8.8.8 443
Dezza
Ich bin nicht sicher, wie zuverlässig der DNS-Resolver von Google bei der Bereitstellung von HTTPS ist. Der google.com-Server sollte für HTTPS zuverlässiger sein (es sei denn, Sie befinden sich in China, aber dann sind wahrscheinlich beide blockiert). Ich habe noch nie -din meinen Skripten gebraucht , vielleicht weil ich noch nie eine unbenutzte Pipeline hatte. Das sollte sicher sein, hinzuzufügen.
Adam Katz
1
@dezza - -w 1kostet immer noch eine Sekunde, wenn es keine Konnektivität gibt, obwohl Sie vielleicht ncirgendwo ein dunkles Problem haben. Wenn Sie eine aktuelle Version von nmap installiert haben, können Sie dies stattdessen tunncat --send-only --recv-only -w 334msnc Sie diese Ausfallzeit auf ein Drittel verkürzen (334 ms sind eine gute Wartezeit).
Adam Katz
1
@dezza - Ich weiß nicht, warum Ihnen das auf ncat und netcat (nc) von nmap für dieses System passiert. Möglicherweise passiert in Ihrem Netzwerk oder auf diesem BSD-System etwas Merkwürdiges. Fühlen Sie sich frei, eine neue unix.stackexchange-Frage zu erstellen und mehr als nur meine Augen auf dieses Problem zu richten. Wenn Sie dies tun, verlinken Sie es bitte in den Kommentaren hier und verlinken Sie diesen Thread mit Ihrer neuen Frage.
Adam Katz
9

Ich habe ein Skript erstellt, das mehrere Methoden zur Überprüfung der Internetverbindung verwendet (Ping, NC und Curl, dank Adam Katz, Gilles und Archemar). Ich hoffe, jemand findet das hilfreich. Fühlen Sie sich frei, es nach Ihren Wünschen zu bearbeiten / zu optimieren.

Überprüft Ihr Gateway, DNS und Ihre Internetverbindung (unter Verwendung von curl, nc und ping). Setze dies in eine Datei und mache es dann ausführbar (normalerweise 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
quelle
Nett ! Vielen Dank ! Worauf sollten wir das Gateway einstellen $GW?
Ciprian Tomoiagă
@ CiprianTomoiaga Keine Notwendigkeit, /sbin/ip route | awk '/default/ { print $3 }'bekommt die Gateway-Adresse von der (hoffentlich) primären Schnittstelle. Wenn Sie möchten, können Sie die Gateway-IP-Adresse selbst festlegen.
PNDA
Danke dafür! Was ich jedoch vermisse, ist die Möglichkeit, Internetstörungen in einer txt-Datei und einer automatisierten E-Mail an meinen ISP zu speichern.
rhand
2

Es gibt viele IPs im Internet. Ein leichter Ansatz ist es, einige von ihnen zu pingen

 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

Eine vollständigere Antwort könnte darin bestehen, dass Seiten verwendet werden wget

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

woher

  • parse ist ein Programm, das Sie schreiben, um sicherzustellen, dass google.txt keine (zu alte) zwischengespeicherte Version von google.com ist
Archemar
quelle
1

Dank Ihrer Beiträge von jedem Benutzer und anderen Websites konnte ich dieses Skript in 3 Tagen fertigstellen. und ich werde es für seine Verwendung frei lassen.

Dieses Skript automatisiert die Erneuerung der IP-Adresse, wenn die Verbindung unterbrochen wird.

#!/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
quelle
Was würde diese Antwort verbessern: (1) Erklären, wie das Skript funktioniert. (Es sieht so aus, als müsste der Benutzer das Skript bearbeiten, wenn seine Netzwerkschnittstelle anders heißt als eth0, dies wird jedoch nicht erwähnt.) (2) Verwenden von Englisch. (3) Setzen Sie alle Shell - Variablen (zB "$HOST", "$LINE1"und "$LOG") in doppelte Anführungszeichen. (4) Entweder einstellen LINE2oder nicht verwenden. (Ich vermute , dass Sie bekommen LINE1 /  LINE2verwechselt inet4 /  inet6.) ... (Fortsetzung)
G-Man sagt 'wieder einzusetzen Monica'
(Fortsetzung)… (5) Sie können die aktuelle Uhrzeit tatsächlich anzeigen, wenn Sie sagen, dass Sie die aktuelle Uhrzeit anzeigen, anstatt die Uhrzeit zu erfassen, zu der das Skript gestartet wird, und sie während der gesamten Lebensdauer des Skripts anzuzeigen. (6) Ich glaube, es gab noch etwas anderes, aber ich sehe es jetzt nicht.
G-Man sagt, dass Monica
Es ist auf Spanisch, weil es in meiner Sprache ist, aber ich kann es auf Englisch korrigieren. Der $ HOST ist die zu versuchende Adresse. $ LINE1 ist die Internetverbindung, die über den eth0-Adapter hergestellt wird. $ LINE2 ist die Internetverbindung, die vom eth1-Adapter optional verbunden wird, wenn Sie über 2 Internetleitungen verfügen. Es wird jedoch empfohlen, diese deaktiviert zu lassen. Wenn ich nachprüfe, dass das Datum und die Uhrzeit seit dem Start des Skripts identisch sind, muss ich das Problem beheben. Dieses Wochenende korrigiere ich das Problem.
John Llewelyn
Ok G-Man, ich habe einige Änderungen vorgenommen, ich muss noch das Datum korrigieren und einige Dinge verbessern.
John Llewelyn