Shell Scripting: Cara yang tepat untuk memeriksa konektivitas internet?

26

Saya menemukan skrip yang mengatakan mereka memeriksa konektivitas internet. Beberapa memeriksa alamat IP jika antarmuka sudah habis, tetapi tidak memeriksa konektivitas internet. Saya menemukan beberapa yang menggunakan ping seperti ini: if [ 'ping google.com -c 4 | grep time' != "" ]; thentetapi kadang-kadang ini mungkin tidak dapat diandalkan karena ping itu sendiri mungkin hang untuk beberapa alasan (misalnya menunggu beberapa IO macet).

Adakah saran tentang cara yang tepat / andal untuk memeriksa konektivitas internet menggunakan skrip? Apakah saya harus menggunakan beberapa paket?

Perlu untuk dapat memeriksa secara berkala dengan cronmisalnya, kemudian, lakukan sesuatu ketika koneksi turun seperti memanggilifup --force [interface]

PNDA
sumber

Jawaban:

29

Menguji konektivitas IPv4

Jika jaringan Anda mengizinkan ping, coba ping 8.8.8.8 (server yang dijalankan oleh 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

Menguji konektivitas IP dan DNS

Jika Anda hanya ingin tes berhasil ketika DNS juga berfungsi, gunakan nama host.

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

Menguji konektivitas web

Beberapa firewall memblokir ping. Beberapa tempat memiliki firewall yang memblokir semua lalu lintas kecuali melalui proxy web. Jika Anda ingin menguji konektivitas web, Anda dapat membuat permintaan 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 'SANGAT berhenti menjadi jahat'
sumber
Anda mungkin ingin memasukkan validasi koneksi fisik (OSI layer 1) sebelum pengecekan layer 3 OSI menggunakan ethtool; $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas-
Anda dapat menjelaskan tujuan menambahkan ini silahkan>/dev/null
Amine Harbaoui
@AmineHarbaoui - >/dev/nullmengarahkan output standar ke /dev/null, perangkat null , yang membuangnya karena tidak diinginkan dalam kasus ini (yang kami pedulikan hanyalah nilai keluar dari perintah). Sebagai gantinya, output yang lebih berlaku diambil dari echojalur.
Adam Katz
27

Saya sangat merekomendasikan untuk tidak menggunakan pingkonektivitas. Ada terlalu banyak admin jaringan yang menonaktifkan ICMP (protokol yang digunakannya) karena kekhawatiran tentang serangan banjir ping yang berasal dari jaringan mereka.

Sebagai gantinya, saya menggunakan tes cepat dari server yang andal pada port yang bisa Anda buka:

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

Ini menggunakan netcat ( nc) dalam mode pemindaian port -nya , tusukan cepat ( -zadalah mode nol-I / O [digunakan untuk memindai] ) dengan batas waktu cepat ( -w 1menunggu paling banyak satu detik). Ia memeriksa Google di port 443 (HTTPS).

Saya telah menggunakan HTTPS daripada HTTP sebagai upaya untuk melindungi dari portal captive dan proxy transparan yang dapat menjawab pada port 80 (HTTP) untuk host mana pun. Ini lebih kecil kemungkinannya ketika menggunakan port 443 karena akan ada ketidaksesuaian sertifikat, tetapi itu masih terjadi.

Jika Anda ingin membuktikan diri terhadap hal itu, Anda harus memvalidasi keamanan pada koneksi:

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

Ini memeriksa koneksi (daripada menunggu openssl untuk kehabisan waktu) dan kemudian membuat jabat tangan SSL, dengan mengetik pada fase verifikasi. Diam-diam keluar ("benar") jika verifikasi "OK" atau yang keluar dengan kesalahan ("salah"), maka kami melaporkan temuan tersebut.

Adam Katz
sumber
5
Namun saya menghargai Gillies, ini adalah jawaban yang tepat.
gwillie
3
tambahkan -dmisalnya nc -dzw1juga sehingga tidak mendengarkan STDIN dan menggantung tanpa batas dalam sebuah skrip. dan mungkin menggunakan 8.8.8.8 sebagai ganti google.com untuk menyimpan pencarian. nc -dzw1 8.8.8.8 443
dezza
Saya tidak yakin tentang seberapa dapat diandalkannya resolver DNS Google dalam melayani HTTPS. Server google.com seharusnya lebih andal untuk HTTPS (kecuali Anda berada di China, tetapi keduanya kemungkinan diblokir). Saya tidak pernah membutuhkan -ddalam skrip saya, mungkin karena saya tidak pernah memiliki saluran pipa yang tidak digunakan. Itu harus aman untuk ditambahkan.
Adam Katz
1
@dezza - -w 1masih memerlukan biaya satu detik ketika tidak ada konektivitas, meskipun mungkin Anda ncmemiliki semacam masalah yang tidak jelas di suatu tempat. Jika Anda memiliki versi terbaru dari nmap yang diinstal, Anda dapat melakukannya ncat --send-only --recv-only -w 334msuntuk memotong waktu kegagalan menjadi sepertiga dari nc(Saya telah menemukan bahwa 334ms adalah waktu tunggu yang baik).
Adam Katz
1
@dezza - Saya tidak tahu mengapa itu terjadi pada Anda di ncat dan netcat (nc) nmap untuk sistem itu. Mungkin ada sesuatu yang aneh terjadi di jaringan Anda atau pada sistem BSD itu. Jangan ragu untuk membuat pertanyaan unix.stackexchange baru dan dapatkan lebih dari sekadar mata saya tentang masalah itu. Jika ya, tautkan di komentar di sini dan tautkan utas ini ke pertanyaan baru Anda.
Adam Katz
9

Saya membuat skrip yang menggunakan banyak cara untuk memeriksa koneksi internet (ping, nc, dan curl, terima kasih kepada Adam Katz, Gilles, dan Archemar). Saya harap seseorang menemukan ini berguna. Anda bebas mengeditnya sesuai keinginan / mengoptimalkannya.

Periksa gateway, DNS, dan koneksi internet Anda (menggunakan curl, nc, dan ping). Masukkan ini ke dalam file kemudian buat itu dapat dieksekusi (Biasanya 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
sumber
Bagus! Terima kasih ! Untuk apa kita mengatur gateway $GW?
Ciprian Tomoiagă
@CiprianTomoiaga Tidak perlu, /sbin/ip route | awk '/default/ { print $3 }'dapatkan alamat gateway dari antarmuka utama (semoga). Jika ingin, Anda dapat mengatur sendiri alamat IP gateway.
PNDA
Terima kasih untuk ini! Apa yang saya lewatkan adalah pilihan untuk menyimpan gangguan internet dalam file txt dan email otomatis ke ISP saya.
ulangi
2

ada banyak IP di internet, pendekatan yang mudah adalah dengan melakukan ping beberapa diantaranya

 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

jawaban yang lebih lengkap mungkin menggunakan halaman wget

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

dimana

  • parse adalah program yang Anda tulis yang memastikan google.txt bukan versi cache yang terlalu lama dari google.com
Archemar
sumber
1

terima kasih atas kontribusi Anda dari setiap pengguna dan web lainnya, saya berhasil menyelesaikan skrip ini dalam 3 hari. dan saya akan membiarkannya gratis untuk penggunaannya.

skrip ini mengotomatiskan pembaruan alamat ip ketika koneksi terputus, ia melakukannya terus-menerus.

#!/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
sumber
Apa yang membuat jawaban ini lebih baik: (1) Menjelaskan cara kerja skrip. (Sepertinya pengguna harus mengedit skrip jika antarmuka jaringannya disebut selain eth0, tetapi ini tidak disebutkan.) (2) Menggunakan Bahasa Inggris. (3) Menempatkan semua variabel shell (misalnya "$HOST",, "$LINE1"dan "$LOG") ke dalam tanda kutip ganda. (4) Baik diatur LINE2atau tidak menggunakannya. (Saya curiga bahwa Anda LINE1 /  LINE2bingung dengan inet4 /  inet6.) ... (Lanjutan)
G-Man Mengatakan 'Reinstate Monica'
(Lanjutkan) ... (5) Sebenarnya menampilkan waktu saat ini ketika Anda mengatakan Anda menampilkan waktu saat ini, daripada menangkap waktu ketika skrip dimulai dan menampilkannya sepanjang masa pakai skrip. (6) Saya pikir ada sesuatu yang lain, tetapi saya tidak melihatnya sekarang.
G-Man Mengatakan 'Reinstate Monica'
Itu dalam bahasa Spanyol karena itu dalam bahasa saya, tetapi saya bisa memperbaikinya dalam bahasa Inggris. $ HOST adalah alamat untuk dicoba. $ LINE1 adalah koneksi Internet yang terhubung dengan adaptor eth0. $ LINE2 adalah koneksi Internet yang dihubungkan oleh adaptor eth1 secara opsional jika Anda memiliki 2 saluran Internet, tetapi Anda disarankan untuk menonaktifkannya. Tanggal, jika saya memverifikasi bahwa itu mempertahankan waktu dan tanggal yang sama sejak saya memulai skrip, saya harus memperbaiki masalah itu. Akhir pekan ini saya memperbaiki masalahnya.
John Llewelyn
Ok G-Man, saya membuat beberapa perubahan, saya masih perlu memperbaiki tanggal dan memperbaiki beberapa hal.
John Llewelyn