Shell Scripting: Cách thích hợp để kiểm tra kết nối internet?


26

Tôi tìm thấy các kịch bản nói rằng họ kiểm tra kết nối internet. Một số kiểm tra địa chỉ IP nếu giao diện bật lên NHƯNG nó không kiểm tra kết nối internet. Tôi đã tìm thấy một số sử dụng ping như thế này: if [ 'ping google.com -c 4 | grep time' != "" ]; thennhưng đôi khi điều này có thể không đáng tin cậy vì bản thân ping có thể bị treo vì một số lý do (ví dụ như chờ đợi một số IO bị mắc kẹt).

Bất kỳ đề xuất về cách thích hợp / đáng tin cậy để kiểm tra kết nối internet bằng cách sử dụng các tập lệnh? Tôi có phải sử dụng một số gói?

Nó cần phải có khả năng kiểm tra định kỳ với cronví dụ, sau đó, làm một cái gì đó khi kết nối bị mất như gọiifup --force [interface]

Câu trả lời:


29

Kiểm tra kết nối IPv4

Nếu mạng của bạn cho phép ping qua, hãy thử ping 8.8.8.8 (một máy chủ được điều hành bởi 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

Kiểm tra kết nối IP và DNS

Nếu bạn chỉ muốn thử nghiệm thành công khi DNS cũng hoạt động, hãy sử dụng tên máy chủ.

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

Kiểm tra kết nối web

Một số tường lửa chặn ping. Một số nơi có tường lửa chặn tất cả lưu lượng truy cập ngoại trừ thông qua proxy web. Nếu bạn muốn kiểm tra kết nối web, bạn có thể thực hiện yêu cầu 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

Bạn có thể muốn kết hợp xác thực kết nối vật lý (lớp OSI 1) trước bất kỳ kiểm tra lớp 3 OSI nào bằng ethtool; $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas-

Bạn có thể giải thích mục đích của việc thêm này không>/dev/null
Amine Harbaoui

@AmineHarbaoui - >/dev/nullchuyển hướng đầu ra tiêu chuẩn sang /dev/null, thiết bị null , loại bỏ nó vì nó không mong muốn trong trường hợp này (tất cả những gì chúng tôi quan tâm là giá trị thoát của các lệnh). Thay vào đó, đầu ra áp dụng nhiều hơn được lấy từ các echodòng.
Adam Katz

27

Tôi rất khuyến khích không sử dụng pingđể xác định kết nối. Có quá nhiều quản trị viên mạng vô hiệu hóa ICMP (giao thức mà nó sử dụng) do lo lắng về các cuộc tấn công lũ ping bắt nguồn từ mạng của họ.

Thay vào đó, tôi sử dụng một bài kiểm tra nhanh về một máy chủ đáng tin cậy trên một cổng mà bạn có thể mong đợi được mở:

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

Cái này sử dụng netcat ( nc) trong chế độ quét cổng của nó , poke nhanh ( -zchế độ zero-I / O [được sử dụng để quét] ) với thời gian chờ nhanh ( -w 1chờ tối đa một giây). Nó kiểm tra Google trên cổng 443 (HTTPS).

Tôi đã sử dụng HTTPS thay vì HTTP như một nỗ lực để bảo vệ chống lại các cổng bị giam giữcác proxy minh bạch có thể trả lời trên cổng 80 (HTTP) cho bất kỳ máy chủ nào. Điều này ít có khả năng khi sử dụng cổng 443 vì sẽ có sự không phù hợp với chứng chỉ, nhưng nó vẫn xảy ra.

Nếu bạn muốn chứng minh bản thân trước điều đó, bạn sẽ cần xác thực bảo mật trên kết nối:

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

Việc này kiểm tra một kết nối (thay vì chờ thời gian mở ra) và sau đó thực hiện bắt tay SSL, nhập vào giai đoạn xác minh. Nó âm thầm thoát ("đúng") nếu xác minh là "OK" hoặc nếu không có lỗi ("sai"), thì chúng tôi báo cáo kết quả tìm kiếm.


5
Tôi tôn trọng Gillies tuy nhiên đây là câu trả lời đúng.
gwillie

3
thêm -dví dụ nc -dzw1để nó không nghe STDIN và treo vô định trong tập lệnh. và có thể sử dụng 8.8.8.8 thay vì google.com để lưu tra cứu. nc -dzw1 8.8.8.8 443
dezza

Tôi không chắc chắn về độ phân giải DNS đáng tin cậy của Google khi phục vụ HTTPS. Máy chủ google.com đáng tin cậy hơn cho HTTPS (trừ khi bạn ở Trung Quốc, nhưng sau đó cả hai đều có khả năng bị chặn). Tôi chưa bao giờ cần -dđến kịch bản của mình, có lẽ vì tôi chưa bao giờ có một đường ống chưa sử dụng. Điều đó nên được an toàn để thêm.
Adam Katz

1
@dezza - -w 1vẫn tốn một giây khi không có kết nối, mặc dù có lẽ bạn nccó một số vấn đề mơ hồ ở đâu đó. Nếu bạn đã cài đặt phiên bản nmap gần đây, thay vào đó, bạn có thể thực hiện ncat --send-only --recv-only -w 334msđể giảm thời gian thất bại đó xuống còn một phần ba nc(tôi thấy rằng 334ms là thời gian chờ tốt).
Adam Katz

1
@dezza - Tôi không biết tại sao điều đó lại xảy ra với bạn trên cả ncat và netcat (nc) của nmap cho hệ thống đó. Có thể có điều gì đó kỳ lạ xảy ra trong mạng của bạn hoặc trên hệ thống BSD đó. Hãy thoải mái tạo một câu hỏi unix.stackexchange mới và nhận được nhiều hơn chỉ là đôi mắt của tôi về vấn đề đó. Nếu bạn làm như vậy, xin vui lòng liên kết nó trong các ý kiến ​​ở đây và liên kết chủ đề này với câu hỏi mới của bạn.
Adam Katz

9

Tôi đã tạo một tập lệnh sử dụng nhiều cách để kiểm tra kết nối internet (ping, nc và curl, nhờ Adam Katz, Gilles và Archemar). Tôi hi vọng ai đó thấy nó hữu ích. Hãy thoải mái chỉnh sửa nó theo ý thích / tối ưu hóa nó.

Kiểm tra cổng, DNS và kết nối internet của bạn (sử dụng curl, nc và ping). Đặt nó trong một tập tin sau đó làm cho nó thực thi (Thông thường 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

Tốt đẹp ! Cảm ơn bạn ! Chúng ta nên đặt cổng $GWvào cái gì?
Ciprian Tomoiagă

@CiprianTomoiaga Không cần, /sbin/ip route | awk '/default/ { print $3 }'lấy địa chỉ cổng từ giao diện chính (hy vọng). Nếu bạn muốn, bạn có thể tự đặt địa chỉ IP cổng.
PNDA

Cảm ơn vì điều đó! Điều tôi bỏ lỡ là tùy chọn lưu trữ sự gián đoạn internet trong tệp txt và email tự động đến ISP của tôi.
rhand

2

Có rất nhiều IP trên internet, một cách tiếp cận nhẹ nhàng là ping một vài trong số chúng

 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

một câu trả lời đầy đủ hơn có thể nhận được các trang bằng cách sử dụng wget

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

Ở đâu

  • parse là một chương trình bạn viết để đảm bảo google.txt không phải là một phiên bản được lưu trữ (quá cũ) của google.com

1

nhờ đóng góp của bạn từ mỗi người dùng và web khác, tôi đã quản lý để hoàn thành tập lệnh này trong 3 ngày. và tôi sẽ để nó miễn phí cho việc sử dụng nó.

tập lệnh này tự động gia hạn địa chỉ IP khi mất kết nối, nó liên tục như vậy.

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


Điều gì sẽ làm cho câu trả lời này tốt hơn: (1) Giải thích cách hoạt động của tập lệnh. (Có vẻ như người dùng phải chỉnh sửa tập lệnh nếu giao diện mạng của anh ta được gọi là bất kỳ thứ gì khác eth0, nhưng điều này không được đề cập.) (2) Sử dụng tiếng Anh. (3) Đặt tất cả các biến shell (ví dụ "$HOST", "$LINE1""$LOG") vào dấu ngoặc kép. (4) Hoặc là đặt LINE2hoặc không sử dụng nó. (Tôi nghi ngờ rằng bạn có LINE1 /  LINE2nhầm lẫn với inet4 /  inet6.) Quang (Tiếp)
G-Man nói 'Tái lập lại' '

. (6) Tôi nghĩ rằng có một cái gì đó khác, nhưng tôi không nhìn thấy nó bây giờ.
G-Man nói 'Phục hồi Monica'

Nó là tiếng Tây Ban Nha vì nó là ngôn ngữ của tôi, nhưng tôi có thể sửa nó bằng tiếng Anh. $ HOST là địa chỉ để thử. $ LINE1 là kết nối Internet được kết nối bằng bộ điều hợp eth0. $ LINE2 là kết nối Internet được kết nối tùy chọn bởi bộ điều hợp eth1 nếu bạn có 2 đường truyền Internet, nhưng bạn nên tắt nó đi. Ngày, nếu tôi xác minh rằng nó duy trì cùng thời gian và ngày kể từ khi tôi bắt đầu tập lệnh, tôi phải sửa vấn đề đó. Cuối tuần này tôi sửa bài toán.
John Llewelyn

Ok G-Man, tôi đã thực hiện một số thay đổi, tôi vẫn cần sửa ngày và cải thiện một số thứ.
John Llewelyn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.