Shell Scripting: วิธีที่เหมาะสมในการตรวจสอบการเชื่อมต่ออินเทอร์เน็ต?


26

ฉันพบสคริปต์ที่บอกว่าพวกเขาตรวจสอบการเชื่อมต่ออินเทอร์เน็ต บางคนตรวจสอบที่อยู่ IP หากอินเทอร์เฟซไม่ทำงาน แต่ไม่ได้ตรวจสอบการเชื่อมต่ออินเทอร์เน็ต ฉันพบบางอย่างที่ใช้ ping ดังนี้: if [ 'ping google.com -c 4 | grep time' != "" ]; thenแต่บางครั้งสิ่งนี้อาจไม่น่าเชื่อถือเนื่องจาก ping อาจแขวนด้วยเหตุผลบางอย่าง (เช่นกำลังรอ IO ค้างอยู่)

มีข้อเสนอแนะเกี่ยวกับวิธีที่เหมาะสม / น่าเชื่อถือในการตรวจสอบการเชื่อมต่ออินเทอร์เน็ตโดยใช้สคริปต์หรือไม่? ฉันต้องใช้แพ็คเกจบางอย่างหรือไม่?

มันจำเป็นต้องสามารถตรวจสอบเป็นระยะ ๆcronจากนั้นทำบางสิ่งบางอย่างเมื่อการเชื่อมต่อลดลงเช่นเรียกใช้ifup --force [interface]

คำตอบ:


29

ทดสอบการเชื่อมต่อ IPv4

หากเครือข่ายของคุณอนุญาตให้ส่ง Ping ได้ให้ลองส่ง Ping 8.8.8.8 (เซิร์ฟเวอร์ดำเนินการโดย 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

ทดสอบการเชื่อมต่อ IP และ DNS

หากคุณต้องการให้การทดสอบประสบความสำเร็จเมื่อ DNS ใช้งานได้เท่านั้นให้ใช้ชื่อโฮสต์

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

ทดสอบการเชื่อมต่อเว็บ

ไฟร์วอลล์บางตัวบล็อกการส่ง Ping บางแห่งมีไฟร์วอลล์ที่บล็อกทราฟฟิกทั้งหมดยกเว้นผ่านเว็บพร็อกซี หากคุณต้องการทดสอบการเชื่อมต่อเว็บคุณสามารถสร้างคำขอ 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

คุณอาจต้องการรวมการตรวจสอบความถูกต้องของการเชื่อมต่อทางกายภาพ (ชั้น OSI 1) ก่อนการตรวจสอบ OSI ชั้น 3 ใด ๆ โดยใช้ ethtool $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas-

คุณช่วยอธิบายจุดประสงค์ของการเพิ่มสิ่งนี้ได้ไหม>/dev/null
Amine Harbaoui

@AmineHarbaoui - >/dev/nullเปลี่ยนเส้นทางออกมาตรฐานเพื่อ/dev/nullที่อุปกรณ์ nullซึ่งพ้นจากมันเพราะมันไม่ได้เป็นที่ต้องการในกรณีนี้ (ทั้งหมดที่เราดูแลเกี่ยวกับค่าทางออกของคำสั่ง) แต่เอาต์พุตที่ใช้งานได้จะถูกนำมาจากechoบรรทัด
Adam Katz

27

ผมขอแนะนำให้กับการใช้pingเพื่อตรวจสอบการเชื่อมต่อ มีผู้ดูแลระบบเครือข่ายมากเกินไปที่ปิดใช้งานICMP (โปรโตคอลที่ใช้) เนื่องจากความกังวลเกี่ยวกับการโจมตีแบบping ที่เกิดจากเครือข่าย

แต่ฉันใช้การทดสอบอย่างรวดเร็วของเซิร์ฟเวอร์ที่เชื่อถือได้บนพอร์ตที่คุณคาดว่าจะเปิด:

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

สิ่งนี้ใช้ netcat ( nc) ในโหมดการสแกนพอร์ตการกระตุ้นอย่างรวดเร็ว ( -zเป็นโหมด zero-I / O [ใช้สำหรับการสแกน] ) ด้วยการหมดเวลาใช้งานอย่างรวดเร็ว ( -w 1รออย่างน้อยหนึ่งวินาที) ตรวจสอบ Google ในพอร์ต 443 (HTTPS)

ฉันใช้ HTTPS มากกว่า HTTP เป็นความพยายามในการป้องกันพอร์ทัลที่ถูกจับและพรอกซีที่โปร่งใสซึ่งสามารถตอบพอร์ต 80 (HTTP) สำหรับโฮสต์ใด ๆ สิ่งนี้มีโอกาสน้อยกว่าเมื่อใช้พอร์ต 443 เนื่องจากจะมีใบรับรองไม่ตรงกัน แต่ก็ยังคงเกิดขึ้น

หากคุณต้องการพิสูจน์ด้วยตัวคุณเองคุณจะต้องตรวจสอบความปลอดภัยของการเชื่อมต่อ:

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

สิ่งนี้จะตรวจสอบการเชื่อมต่อ (แทนที่จะรอให้ openssl หมดเวลา) จากนั้นสร้างการจับมือ SSL โดยป้อนระยะการตรวจสอบ มันจะออกจากเงียบ ๆ ("จริง") หากการยืนยันเป็น "ตกลง" หรือมีข้อผิดพลาดอื่น ("ผิดพลาด") จากนั้นเราจะรายงานการค้นพบ


5
ฉันเคารพ Gillies แต่นี่เป็นคำตอบที่ถูก
gwillie

3
เพิ่ม-dเช่นnc -dzw1ด้วยดังนั้นมันจึงไม่ฟัง STDIN และวางไว้ในสคริปต์อย่างไม่มีกำหนด และอาจใช้ 8.8.8.8 แทน google.com เพื่อบันทึกการค้นหา nc -dzw1 8.8.8.8 443
dezza

ฉันไม่แน่ใจเกี่ยวกับความน่าเชื่อถือของตัวแก้ไข DNS ที่ให้บริการ HTTPS เซิร์ฟเวอร์ google.com น่าเชื่อถือมากขึ้นสำหรับ HTTPS (เว้นแต่ว่าคุณอยู่ในประเทศจีน แต่มีแนวโน้มว่าจะถูกบล็อกทั้งคู่) ฉันไม่เคยต้องการ-dสคริปต์ของฉันบางทีอาจเป็นเพราะฉันไม่เคยใช้งานมาก่อน ที่ควรจะเพิ่มปลอดภัย
Adam Katz

1
@dezza - -w 1ยังคงมีค่าใช้จ่ายที่สองเมื่อไม่มีการเชื่อมต่อแม้ว่าบางทีคุณอาจncมีปัญหาคลุมเครือบางชนิด หากคุณมี nmap เวอร์ชันล่าสุดติดตั้งอยู่คุณสามารถทำได้ncat --send-only --recv-only -w 334msเพื่อลดเวลาที่ล้มเหลวลงเหลือหนึ่งในสามของnc(ฉันพบว่า 334ms เป็นเวลารอที่ดี)
Adam Katz

1
@dezza - ฉันไม่ทราบสาเหตุที่เกิดขึ้นกับคุณทั้งใน nmap และ ncat netcat (nc) สำหรับระบบ อาจมีสิ่งผิดปกติเกิดขึ้นในเครือข่ายของคุณหรือในระบบ BSD นั้น อย่าลังเลที่จะสร้างคำถาม unix.stackexchange ใหม่และรับมากกว่าแค่สายตาของฉันในปัญหานั้น หากคุณมีโปรดเชื่อมโยงในความคิดเห็นที่นี่และเชื่อมโยงหัวข้อนี้กับคำถามใหม่ของคุณ
Adam Katz

9

ฉันสร้างสคริปต์ที่ใช้หลายวิธีในการตรวจสอบการเชื่อมต่ออินเทอร์เน็ต (ping, nc และ curl ขอบคุณ Adam Katz, Gilles และ Archemar) ฉันหวังว่าบางคนพบว่ามีประโยชน์นี้ รู้สึกอิสระที่จะแก้ไขมันตามความชอบของคุณ / เพิ่มประสิทธิภาพ

ตรวจสอบเกตเวย์ DNS และการเชื่อมต่ออินเทอร์เน็ตของคุณ (โดยใช้ curl, nc และ ping) ใส่สิ่งนี้ลงในไฟล์จากนั้นทำให้สามารถเรียกใช้งานได้ (โดยปกติ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

เยี่ยมมาก! ขอขอบคุณ ! เราควรตั้งค่าเกตเวย์$GWเป็นอะไร
Ciprian Tomoiagă

@CiprianTomoiaga ไม่จำเป็นต้อง/sbin/ip route | awk '/default/ { print $3 }'รับที่อยู่เกตเวย์จากอินเทอร์เฟซหลัก (หวังว่า) หากคุณต้องการคุณอาจตั้งค่าที่อยู่ IP ของเกตเวย์ด้วยตนเอง
PNDA

ขอบคุณสำหรับสิ่งนี้! สิ่งที่ฉันพลาดคือตัวเลือกในการจัดเก็บการหยุดชะงักทางอินเทอร์เน็ตในไฟล์ txt และอีเมลอัตโนมัติไปยัง ISP ของฉัน
rhand

2

มีไอพีมากมายบนอินเทอร์เน็ตวิธีที่เบาคือการ ping บางอย่าง

 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

คำตอบที่สมบูรณ์มากขึ้นอาจทำให้หน้าใช้ wget

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

ที่ไหน

  • แยกเป็นโปรแกรมที่คุณเขียนเพื่อให้แน่ใจว่า google.txt ไม่ใช่รุ่น google.co.th (เก่าเกินไป)

1

ขอบคุณที่คุณมีส่วนร่วมจากผู้ใช้แต่ละคนและเว็บอื่น ๆ ฉันจัดการเพื่อให้สคริปต์นี้เสร็จสมบูรณ์ใน 3 วัน และฉันจะปล่อยให้ฟรีสำหรับการใช้งาน

สคริปต์นี้จะทำการต่ออายุที่อยู่ IP โดยอัตโนมัติเมื่อการเชื่อมต่อขาดหายไป

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


อะไรจะทำให้คำตอบนี้ดีขึ้น: (1) อธิบายว่าสคริปต์ทำงานอย่างไร (ดูเหมือนว่าผู้ใช้จะต้องแก้ไขสคริปต์หากส่วนต่อประสานเครือข่ายของเขาถูกเรียกว่าสิ่งอื่นที่ไม่ใช่eth0แต่ไม่ได้กล่าวถึง) (2) การใช้ภาษาอังกฤษ (3) การใส่ตัวแปรเชลล์ทั้งหมด (เช่น"$HOST", "$LINE1"และ"$LOG") ลงในเครื่องหมายคำพูดคู่ (4) ตั้งLINE2หรือไม่ใช้ก็ได้ (ฉันสงสัยว่าคุณสับสนLINE1 /  LINE2กับinet4 /  inet6.) … (ต่อ)
G-Man พูดว่า 'Reinstate Monica'

(ต่อ) ... (5) แสดงเวลาปัจจุบันจริง ๆ เมื่อคุณบอกว่าคุณกำลังแสดงเวลาปัจจุบันแทนที่จะจับเวลาเมื่อสคริปต์เริ่มต้นและแสดงตลอดเวลาของสคริปต์ (6) ฉันคิดว่ามีอย่างอื่น แต่ตอนนี้ฉันไม่เห็น
G-Man กล่าวว่า 'Reinstate Monica'

มันเป็นภาษาสเปนเพราะเป็นภาษาของฉัน แต่ฉันสามารถแก้ไขเป็นภาษาอังกฤษได้ $ HOST เป็นที่อยู่ที่ควรลอง $ LINE1 คือการเชื่อมต่ออินเทอร์เน็ตที่เชื่อมต่อโดยอะแดปเตอร์ eth0 $ LINE2 เป็นการเชื่อมต่ออินเทอร์เน็ตที่เชื่อมต่อโดยอะแดปเตอร์ eth1 ซึ่งเป็นทางเลือกหากคุณมี 2 สายอินเทอร์เน็ต แต่ขอแนะนำให้ปิดการใช้งานไว้ วันที่หากฉันยืนยันว่าเป็นวันและเวลาเดิมนับตั้งแต่ฉันเริ่มสคริปต์ฉันต้องแก้ไขปัญหานั้น สุดสัปดาห์นี้ฉันแก้ไขปัญหา
John Llewelyn

ตกลง G-Man ฉันทำการเปลี่ยนแปลงบางอย่างฉันยังต้องแก้ไขวันที่และปรับปรุงบางสิ่ง
John Llewelyn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.