Shell Scripting: İnternet bağlantısını kontrol etmenin doğru yolu?


26

İnternet bağlantısını kontrol ettiklerini söyleyen komut dosyaları buldum. Bazıları ara yüz yukarı ise IP adresini kontrol eder, ancak internet bağlantısı olup olmadığını kontrol etmez. Bu gibi ping kullanan bazılarını buldum: if [ 'ping google.com -c 4 | grep time' != "" ]; thenama bazen bu ping'in bir nedenden dolayı asılabileceği için güvenilmez olabilir (örneğin, bazı sıkışmış IO'yu beklemek).

Senaryoları kullanarak internet bağlantısını kontrol etmek için uygun / güvenilir bir şekilde herhangi bir öneriniz var mı? Bazı paketleri kullanmak zorunda mıyım?

cronÖrneğin periyodik olarak kontrol edebilmeli, örneğin bağlantı çağrıldığında yapılan gibi bir şey yapmalıifup --force [interface]

Yanıtlar:


29

IPv4 bağlantısını test etme

Ağınız geçiş yapmasına izin veriyorsa, 8.8.8.8'e (Google tarafından işletilen bir sunucu) ping atmayı deneyin.

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

IP bağlantısını ve DNS'yi test etme

Testin yalnızca DNS çalışırken de başarılı olmasını istiyorsanız, bir ana bilgisayar adı kullanın.

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

Web bağlantısını test etme

Bazı güvenlik duvarları pingleri engeller. Bazı yerlerde web proxy'si dışındaki tüm trafiği engelleyen bir güvenlik duvarı vardır. Web bağlantısını test etmek istiyorsanız, bir HTTP isteği yapabilirsiniz.

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

Ethtool kullanarak herhangi bir OSI katman 3 kontrolünden önce fiziksel bir bağlantının (OSI katman 1) onayını dahil etmek isteyebilirsiniz; $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas

Bunu eklemek amacını açıklayabilir misiniz>/dev/null
Amine Harbaoui

@AmineHarbaoui - >/dev/nullstandart çıktıyı /dev/null, bu durumda istenmediği için boşa alan boş cihaza yönlendirir (tek umurumuz komutların çıkış değerleridir). Bunun yerine, echohatlardan daha uygulanabilir çıktılar alınır .
Adam Katz

27

Ben çok tavsiye karşı kullanarak pingbağlantısı belirlemek için. Ağlarından kaynaklanan ping seli saldırılarıyla ilgili endişeler nedeniyle ICMP'yi (kullandığı protokol) devre dışı bırakan çok fazla ağ yöneticisi var .

Bunun yerine, açık olmasını bekleyebileceğiniz bir bağlantı noktasında güvenilir bir sunucuyu hızlı bir şekilde test ediyorum:

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

Bu nc, port tarama modunda netcat ( ) işlevini kullanır ; hızlı bir zamanaşımı (hızlıca bir zaman aşımı -zsüresi olan hızlı bir dürtme ( sıfır-I / O modudur [tarama için kullanılır ) -w 1). Google'ı 443 numaralı bağlantı noktasından (HTTPS) kontrol eder.

Herhangi bir ana bilgisayar için 80 numaralı bağlantı noktasında (HTTP) yanıtlayabilecek esir portallara ve şeffaf proxy'lere karşı koruma sağlamak için HTTP yerine HTTPS kullandım . Bu, 443 numaralı bağlantı noktasını kullanırken daha az olasıdır, çünkü bir sertifika uyuşmazlığı olacaktır, ancak yine de gerçekleşmektedir.

Kendinizi buna karşı kanıtlamak istiyorsanız, bağlantıdaki güvenliği doğrulamanız gerekir:

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

Bu bir bağlantıyı denetler (openssl'nin zaman aşımına uğramasını beklemek yerine) ve doğrulama aşamasını girerek SSL anlaşmasını yapar. Doğrulama "Tamam" ise ya da bir hatayla ("yanlış") çıkarsa sessizce çıkar ("doğru"), sonra bulguyu bildiririz.


5
Gillies'a saygı duyuyorum ancak bu doğru cevap.
gwillie

3
eklemek -dmesela nc -dzw1o STDIN'den dinlemesi ve komut indefinetily askıda değil, aynı zamanda. ve belki bir arama kaydetmek için google.com yerine 8.8.8.8 kullanın. nc -dzw1 8.8.8.8 443
dezza,

Google’ın DNS çözümleyicisinin HTTPS’de ne kadar güvenilir olduğundan emin değilim. Google.com sunucusunun HTTPS için daha güvenilir olması gerekir (Çin'de değilseniz, ancak ikisi de engellenmiş olabilir). -dSenaryolarımda hiç ihtiyacım olmadı , belki de hiç kullanılmamış bir boru hattım olmadı. Eklemek güvenli olmalı.
Adam Katz

1
@dezza - -w 1belki bağlantıda bir problem olmadığı halde, bir bağlantı olmadığında bir saniyeye ncmal olur. Yüklü bir nmap sürümüne sahipseniz, bunun yerine ncat --send-only --recv-only -w 334msbu başarısızlık süresini üçte bir oranında kesmek için yapabilirsiniz nc(334ms'nin iyi bir bekleme süresi olduğunu buldum).
Adam Katz

1
@dezza - Nmap'ın ncat ve netcat (nc) 'sinde o sistem için neden böyle olduğunu bilmiyorum. Ağınızda veya bu BSD sisteminde garip bir şeyler olabilir. Yeni bir unix.stackexchange sorusu oluşturmaktan çekinmeyin ve bu sorundaki gözlerimden daha fazlasını elde edin. Bunu yaparsanız, lütfen buraya yorumlarda bağlayın ve bu konuyu yeni sorunuza bağlayın.
Adam Katz

9

İnternet bağlantısını kontrol etmek için çeşitli yöntemler kullanan bir senaryo hazırladım (ping, nc ve curl, Adam Katz, Gilles ve Archemar sayesinde). Umarım birileri bunu yararlı bulur. İsteğinize göre düzenlemek / optimize etmek için çekinmeyin.

Ağ geçidinizi, DNS ve internet bağlantınızı kontrol eder (curl, nc ve ping kullanarak). Bunu bir dosyaya koyun ve çalıştırılabilir hale getirin (Genellikle 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

Güzel ! Teşekkür ederim ! Ağ geçidini neye ayarlamalıyız $GW?
Ciprian Tomoiagă

@CiprianTomoiaga Gerek yok /sbin/ip route | awk '/default/ { print $3 }', (umarım) birincil arayüzden ağ geçidi adresini alır. İsterseniz, ağ geçidi IP adresini kendiniz belirleyebilirsiniz.
PNDA

Bunun için teşekkürler! Yine de özlediğim şey internet aksaklıklarını bir txt dosyasında ve otomatik e-postalarıma ISS’ime saklama seçeneği.
saat

2

İnternette birçok IP var, hafif bir yaklaşım bazılarına ping atmak

 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

daha eksiksiz bir cevap kullanarak sayfaları almak olabilir wget

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

nerede

  • ayrıştırma, google.txt dosyasının google.com'un (çok eski) önbelleğe alınmış bir sürümü olmadığından emin olduğunuz bir programdır.

1

Her bir kullanıcı ve diğer internetten yaptığınız katkılar sayesinde bu betiği 3 günde tamamlamayı başardım. ve kullanımı için boş bırakacağım.

Bu betik, bağlantı kaybolduğunda ip adresinin yenilenmesini otomatik hale getirir, bunu kalıcı olarak yapar.

#!/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


Bu cevabı daha iyi ne yapabilirdi: (1) Senaryonun nasıl çalıştığını açıklamak. (Ağ arayüzünden başka bir şey çağrılırsa, kullanıcının betiği düzenlemek zorunda olduğu görülmektedir eth0, ancak bu belirtilmemiştir.) (2) İngilizce'yi kullanma. (3) Tüm kabuk değişkenlerini (örneğin "$HOST", "$LINE1"ve "$LOG") çift tırnak içine alın. (4) Ya ayarlayın LINE2ya da kullanmayın. (Elindeki şüpheli LINE1 /  LINE2karıştırılmaması inet4 / '  inet6.) ... (devamı)
G-Man 'eski durumuna Monica' Diyor

(Devam ediyor)… (5) Aslında, betiğin başladığı zamanı yakalamak ve betiğin kullanım ömrü boyunca görüntülemek yerine, geçerli saati görüntülediğinizi söylerken mevcut saati görüntüler. (6) Başka bir şey olduğunu düşünüyorum ama şimdi göremiyorum.
G-Man 'Monica'yı Yeniden Girin'

İspanyolca, çünkü benim dilimde, ancak İngilizce olarak düzeltebiliyorum. $ HOST denenecek adres. $ LINE1, eth0 adaptörüyle bağlanan İnternet bağlantısıdır. $ LINE2, 2 İnternet hattınız varsa, isteğe bağlı olarak eth1 adaptörüyle bağlanan İnternet bağlantısıdır, ancak devre dışı bırakmanız önerilir. Tarih, komut dosyasını başlattığımdan beri aynı saat ve tarihi koruduğunu doğrularsam, bu sorunu düzeltmeliyim. Bu haftasonu sorunu düzeltirim.
John Llewelyn

Tamam G-Man, bazı değişiklikler yaptım, hala tarihi düzeltmem ve bazı şeyleri geliştirmem gerekiyor.
John Llewelyn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.