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


26

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

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

cron예를 들어 주기적으로 확인한 다음 연결이 끊어 질 때 무언가를 수행해야합니다.ifup --force [interface]

답변:


29

IPv4 연결 테스트

네트워크에서 핑을 허용하는 경우 8.8.8.8 (Google에서 실행하는 서버)을 핑 (ping) 해보십시오.

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

ethtool을 사용하여 OSI 계층 3을 확인하기 전에 물리적 연결 (OSI 계층 1)의 유효성 검사를 통합 할 수 있습니다. $ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
— jas-

이하시기 바랍니다 추가의 목적을 설명 할 수>/dev/null
— 아민 Harbaoui

@AmineHarbaoui은 - >/dev/null표준 출력 리디렉션 /dev/null1, 널 장치 그것의 처분하는이이 경우에 바람직하지 않기 때문에, (우리가 걱정하는 모든 명령의 종료 값입니다). 대신,보다 적합한 출력이 echo라인 에서 가져옵니다 .
— Adam Katz

27

내가보기 엔 추천 에 대해 사용하여 ping연결을 확인합니다. 네트워크 에서 시작된 플러드 공격 에 대한 우려로 인해 ICMP (사용하는 프로토콜) 를 비활성화하는 네트워크 관리자가 너무 많습니다 .

대신, 개방 된 포트에서 신뢰할 수있는 서버에 대한 빠른 테스트를 사용합니다.

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

이 용도 netcat을 ( nc그것의) 포트 스캔 모드는 짧은 포크는 ( -z인 [스캐닝 사용] 제로 I / O 모드 짧은 타임 아웃 ()와 -w 1대기 최대 하나 초). 포트 443 (HTTPS)에서 Google을 확인합니다.

모든 호스트에 대해 포트 80 (HTTP)에서 응답 할 수있는 캡 티브 포털 및 투명한 프록시 로부터 보호하기 위해 HTTP 대신 HTTPS를 사용했습니다 . 인증서 불일치가 발생하기 때문에 포트 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 핸드 셰이크를 만듭니다. 확인이 "OK"이거나 오류 ( "false")와 함께 종료되면 자동으로 종료 ( "true")되고 결과를보고합니다.


5
나는 Gillies를 존중하지만 이것이 정답입니다.
— gwillie

3
-d예를 들어 nc -dzw1STDIN을 듣지 않고 스크립트에 무한정 매달리지 않도록 추가하십시오 . google.com 대신 8.8.8.8을 사용하여 조회를 저장하십시오. nc -dzw1 8.8.8.8 443
— dezza

Google의 DNS 확인자가 HTTPS를 제공하는 데 얼마나 안정적인지 잘 모르겠습니다. google.com 서버는 HTTPS에 대해보다 안정적이어야합니다 (중국에 있지 않은 경우 둘 다 차단 될 수 있음). -d사용하지 않은 파이프 라인이 없기 때문에 스크립트에 필요 하지 않았습니다. 추가해도 안전합니다.
— Adam Katz

1
@dezza – -w 1연결이없는 경우에도 여전히 1 초의 비용이 듭니다.하지만 아마도 nc모호한 문제가있을 수 있습니다. 최신 버전의 nmap을 설치 한 경우 대신 ncat --send-only --recv-only -w 334ms실패 시간을 3 분의 1로 줄이십시오 nc(334ms가 좋은 대기 시간이라는 것을 알았습니다).
— Adam Katz

1
@dezza – 그 시스템에서 nmap의 ncat과 netcat (nc) 모두에서 왜 그런 일이 일어나는지 모르겠습니다. 네트워크 나 BSD 시스템에서 이상한 일이있을 수 있습니다. 새로운 unix.stackexchange 질문을 작성하고 그 문제에 대한 내 눈보다 더 많은 것을 얻으십시오. 그렇다면 여기에 의견으로 연결 하고이 스레드를 새 질문에 연결하십시오.
— Adam Katz

9

인터넷 연결을 확인하기 위해 여러 가지 방법을 사용하는 스크립트를 만들었습니다 (Adam Katz, Gilles 및 Archemar 덕분에 ping, nc 및 curl). 누군가가 이것을 유용하게 사용하기를 바랍니다. 원하는대로 편집하거나 최적화하십시오.

curl, nc 및 ping을 사용하여 게이트웨이, DNS 및 인터넷 연결을 확인합니다. 이것을 파일에 넣고 실행 가능하게 만드십시오 (보통 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

인터넷에는 많은 IP가 있으며, 가벼운 접근 방식은 그중 일부를 핑하는 것입니다.

 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.com의 캐시 된 버전이 아닌지 확인하는 프로그램입니다.

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-남자 '분석 재개 모니카'말한다

… (6) 다른 것이 있다고 생각하지만 지금은 볼 수 없습니다.
— G-Man, 'Reinstate Monica'라고

내 언어로되어 있기 때문에 스페인어로되어 있지만 영어로 수정할 수 있습니다. $ HOST는 시도 할 주소입니다. $ LINE1은 eth0 어댑터로 연결된 인터넷 연결입니다. $ LINE2는 2 개의 인터넷 회선이있는 경우 선택적으로 eth1 어댑터로 연결되는 인터넷 연결이지만 사용하지 않는 것이 좋습니다. 스크립트를 시작한 이후 날짜와 시간과 날짜가 동일하게 유지되는지 확인하면 해당 문제를 수정해야합니다. 이번 주말에 나는 문제를 해결했다.
— John Llewelyn

Ok G-Man, 나는 약간의 변화를가했지만 여전히 날짜를 수정하고 개선해야합니다.
— John Llewelyn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.