web-dev-qa-db-ja.com

シェルスクリプト:インターネット接続を確認する適切な方法?

インターネット接続をチェックするというスクリプトを見つけました。一部は、インターフェースがアップしている場合にIPアドレスをチェックしますが、インターネット接続をチェックしません。 if [ 'ping google.com -c 4 | grep time' != "" ]; thenのようにpingを使用するものを見つけましたが、ping自体が何らかの理由(たとえば、スタックしたIOを待機している)でハングする可能性があるため、これは信頼できない場合があります。

スクリプトを使用してインターネット接続を確認する適切な/信頼できる方法に関する提案はありますか?一部のパッケージを使用する必要がありますか?

たとえば、cronを使用して定期的にチェックできる必要があります。次に、接続がダウンしたときに、invoke ifup --force [interface]のように何かを行います。

26
PNDA

IPv4接続のテスト

ネットワークがpingを通過できる場合は、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

Web接続のテスト

一部のファイアウォールはpingをブロックします。一部の場所には、Webプロキシ経由を除くすべてのトラフィックをブロックするファイアウォールがあります。 Web接続をテストする場合は、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

againstに対してpingを使用して接続を決定することを強くお勧めします。 [ping Flood ネットワークからの攻撃を心配しているため、 [〜#〜] icmp [〜#〜] (使用するプロトコル)を無効にするネットワーク管理者が多すぎる。

代わりに、信頼できるサーバーのクイックテストを使用して、ポートが開いていると予想できます。

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

これは、その ポートスキャン モードでネットキャット(nc)を使用し、クイックポーク(-zゼロI/Oモード[スキャンに使用])でクイックタイムアウト(-w 1は最大で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 '
  handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 }
  $1 $2 == "SSLhandshake" { handshake = 1 }'
then
  echo "we have connectivity"
fi

これにより、(opensslがタイムアウトするのを待つのではなく)接続がチェックされ、SSLハンドシェイクが行われ、検証フェーズでキーイングが行われます。検証が「OK」の場合はサイレントで終了し(「true」)、エラーで終了すると(「false」)、その結果を報告します。

28
Adam Katz

複数の方法でインターネット接続をチェックするスクリプトを作成しました(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
9
PNDA

インターネットには多くのIPがあり、簡単なアプローチはそれらのいくつかに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

どこ

  • parseは、google.txtが(古すぎる)キャッシュバージョンのgoogle.comではないことを確認するために作成するプログラムです
2
Archemar

各ユーザーと他のWebからの寄稿のおかげで、このスクリプトを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

1
John Llewelyn

@PNDAは、ethtoolからデータを取得することを提案しました。しかし、私はgrepにパイプして、bash以外の人々がより速く理解できるより単純なawkコマンドを使用することを好みます。 2つの間の時間差はごくわずかです。

使用:buntu Bionic 18.04

ネットワークインターフェイスの検出:

root@srv:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope Host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope Host 
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:1e:67:96:a3:97 brd ff:ff:ff:ff:ff:ff
    inet 10.0.1.101/8 brd 10.255.255.255 scope global eno1
       valid_lft forever preferred_lft forever
    inet6 fe80::21e:67ff:fe96:a397/64 scope link 
       valid_lft forever preferred_lft forever
3: rename3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:1e:67:96:a3:96 brd ff:ff:ff:ff:ff:ff

ethtoolの出力:

root@srv:~# ethtool eno1
Settings for eno1:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Supported pause frame use: No
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Full 
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: 1000Mb/s
        Duplex: Full
        Port: Twisted Pair
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        MDI-X: on (auto)
        Supports Wake-on: pumbg
        Wake-on: g
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes

コマンドの例:

ethtool eno1 | grep "ink detected" | awk '{print $3}'

自分の冒険を選択してください:

ethtool {{network adapter}} | grep "ink detected" | awk '{print $3}'

出力:

リンクがある場合:

root@srv:~# ethtool eno1 | grep "ink detected" | awk '{print $3}'
yes

リンクがない場合:

root@srv:~# ethtool rename3 | grep "ink detected" | awk '{print $3}'
no
0
BradChesney79