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


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.