쉘 스크립트:인터넷 연결을 확인하는 올바른 방법은 무엇입니까?

쉘 스크립트:인터넷 연결을 확인하는 올바른 방법은 무엇입니까?

인터넷 연결을 확인한다는 스크립트를 발견했습니다. 일부는 인터페이스가 작동 중이면 IP 주소를 확인하지만 인터넷 연결은 확인하지 않습니다. 나는 다음과 같은 핑을 사용하는 것을 발견했습니다. if [ 'ping google.com -c 4 | grep time' != "" ]; then그러나 때때로 핑 자체가 어떤 이유로(예: IO가 멈추는 것을 기다리는 등) 중단될 수 있기 때문에 이것은 신뢰할 수 없을 수 있습니다.

스크립트를 사용하여 인터넷 연결을 확인하는 정확하고 안정적인 방법에 대한 제안 사항이 있습니까? 사용해야 하는 패키지가 있나요?

cron예를 들어, 주기적으로 확인한 후 연결이 끊어지면 전화를 거는 등의 작업을 수행 할 수 있어야 합니다.ifup --force [interface]

답변1

나는 강력히 추천한다반대하다연결을 결정하는 데 사용됩니다 ping. 너무 많은 네트워크 관리자가 비활성화되었습니다.ICMP(사용하는 프로토콜) 우려로 인해핑 홍수네트워크에서 공격을 받습니다.

대신, 열려 있을 것으로 예상되는 포트에서 안정적인 서버를 사용하여 빠른 테스트를 수행했습니다.

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

nc이것은 netcat()을 사용합니다.포트 스캔모드, 빠른 찌르기( -zZero I/O 모드[스캔용])에는 빠른 시간 제한이 있습니다( -w 1최대 1초까지 기다리지만 Apple OS X 사용자는 이 기능을 사용해야 할 수도 있음 -G 1). 포트 443(HTTPS)에서 Google을 확인합니다.

방지하기 위해 HTTP 대신 HTTPS를 사용합니다.포로 포털그리고투명 프록시모든 호스트에 대해 포트 80(HTTP)에서 응답할 수 있습니다. 인증서 불일치로 인해 포트 443을 사용할 때 이런 일이 발생할 가능성은 적지만 여전히 발생할 수 있습니다.

이를 증명하려면 연결의 보안을 확인해야 합니다.

test=google.com
if nc -zw1 $test 443 && echo |openssl s_client -connect $test:443 2>&1 |awk '
  $1 == "SSL" && $2 == "handshake" { handshake = 1 }
  handshake && $1 == "Verification:" { ok = $2; exit }
  END { exit ok != "OK" }'
then
  echo "we have connectivity"
fi

이는 연결을 확인한 다음(openssl 시간 초과를 기다리는 대신) 확인 단계에 중점을 두고 SSL 핸드셰이크를 수행합니다. 유효성 검사가 "OK"이면 자동으로 종료되고("true"), 그렇지 않으면 오류("false")와 함께 종료되며 결과가 보고됩니다.

opensslawk 코드는 출력을 한 줄씩 분석합니다.

  1. 줄의 첫 번째 단어가 "SSL"이고 두 번째 단어가 "Verification"인 경우 다음 handshake으로 설정됩니다.1
  2. handshake설정하고 줄의 첫 번째 단어가 "verification"인 경우
    두 번째 단어(검증 상태)를 저장 ok하고 읽기를 중지합니다.
  3. 0유효성 검사 상태가 true인 경우 (true) 값으로 종료하고 OK, 그렇지 않으면 1(false) 값으로 종료합니다. 쉘 종료 코드가 다음과 반대이므로 여기서 사용합니다
    .!=

(awk에 대한 한 가지 이상한 점: exit줄을 읽는 동안 실행하면 줄 읽기가 중지되고 END실제로 실행할 수 있는 조건이 입력됩니다 exit.)

답변2

IPv4 연결 테스트

네트워크에서 핑을 허용하는 경우 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

네트워크 연결 테스트

일부 방화벽은 핑을 차단합니다. 일부 장소에는 네트워크 프록시를 제외한 모든 트래픽을 차단하는 방화벽이 있습니다. 웹 연결을 테스트하려면 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

답변3

나는 여러 가지 방법을 사용하여 인터넷 연결을 확인하는 스크립트를 만들었습니다(Adam Katz, Gilles 및 Archemar 덕분에 ping, nc 및 컬). 누군가가 이것이 유용하다고 생각하기를 바랍니다. 원하는 대로 자유롭게 편집/최적화하세요.

게이트웨이, 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

답변4

모든 사용자와 다른 사이트의 기여 덕분에 나는 이 스크립트를 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

붙여넣기 상자:https://pastebin.com/wfSkpgKA

관련 정보