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


26

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

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

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

回答:


29

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

ethtoolを使用したOSIレイヤー3チェックの前に、物理接続(OSIレイヤー1)の検証を組み込むことができます。$ ethtool <dev> | awk '$0 ~ /link detected/{print $3}'
jas-

これを追加する目的を説明してください>/dev/null
アミンHarbaoui

@AmineHarbaoui – >/dev/null標準出力をnullデバイスにリダイレクトします。null デバイスは、この場合は望ましくないため/dev/null、破棄します(重要なのはコマンドの終了値のみです)。代わりに、より適切な出力が行から取得されます。echo
アダムカッツ

27

接続の決定に使用しないことを強くお勧めpingます。ネットワークから発信されるpingフラッド攻撃の心配のために、ICMP(使用するプロトコル)を無効にするネットワーク管理者が多すぎます。

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

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

この用途のnetcatを(ncその中に)ポートスキャンモードでは、迅速なポークは(-zある[スキャニングに使用】ゼロI / Oモードクイックタイムアウト(と)-w 1を待つ最大で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を尊重しますが、これは正しい答えです。
グウィリー

3
-dたとえばnc -dzw1、STDINをリッスンせず、スクリプト内で無制限にハングアップしないように追加します。google.comの代わりに8.8.8.8を使用してルックアップを保存することもできます。nc -dzw1 8.8.8.8 443
デザ

GoogleのDNSリゾルバーがHTTPSをどの程度信頼できるかはわかりません。google.comサーバーは、HTTPSに対してより信頼性が高いはずです(中国にいる場合を除き、両方がブロックされる可能性が高い)。-dおそらく、未使用のパイプラインを使用したことがないため、スクリプトに必要なことはありません。追加しても安全です。
アダム・カッツ

1
@dezza – -w 1接続がない場合でも1秒かかりますncが、おそらく何らかの問題があります。nmapの最新バージョンがインストールされている場合は、代わりにncat --send-only --recv-only -w 334msその失敗時間を3分のnc1に短縮することができます(334ミリ秒が適切な待機時間であることがわかりました)。
アダムカッツ

1
@dezza –そのシステムのnmapのncatとnetcat(nc)の両方でそれが起こっている理由がわかりません。ネットワークまたはそのBSDシステムで何か奇妙なことが起こっている可能性があります。新しいunix.stackexchangeの質問を自由に作成して、その問題に目を向けてください。もしそうなら、ここのコメントにリンクして、このスレッドをあなたの新しい質問にリンクしてください。
アダム・カッツ

9

複数の方法を使用してインターネット接続をチェックするスクリプトを作成しました(Adam Katz、Gilles、Archemarのおかげで、ping、nc、curl)。誰かがこれが役に立つことを願っています。お好みに合わせて自由に編集/最適化してください。

ゲートウェイ、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

いいね!ありがとうございました !ゲートウェイ$GWを何に設定する必要がありますか?
Ciprianトモイアガ

@CiprianTomoiaga必要はありません/sbin/ip route | awk '/default/ { print $3 }'。(できれば)プライマリインターフェイスからゲートウェイアドレスを取得します。必要に応じて、ゲートウェイIPアドレスを自分で設定できます。
PNDA

これをありがとう!私が見逃しているのは、インターネットの中断をtxtファイルとISPへの自動メールに保存するオプションです。
rhand

2

インターネットには多くの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のキャッシュバージョンではないことを確認するために作成するプログラムです

1

各ユーザーおよび他の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

pastebin:https : //pastebin.com/wfSkpgKA


この答えをより良くするものは何ですか:(1)スクリプトがどのように機能するかを説明する。(ネットワークインターフェイスの名前が以外の場合、ユーザーはスクリプトを編集する必要がありますがeth0、これは言及されていません。)(2)英語の使用。(3)すべてのシェル変数(例えば、パット"$HOST""$LINE1"および"$LOG"二重引用符に)を。(4)設定するLINE2か、使用しないでください。(私はあなたが得たと思われるLINE1 /  LINE2と混同inet4 /  inet6。)...(続き)
G-マンが「回復モニカ言う

(続き)…(5)スクリプトの開始時刻をキャプチャして、スクリプトの有効期間全体を表示するのではなく、現在時刻を表示していると言ったときに実際に現在時刻を表示します。(6)他に何かあったと思うが、今は見えない。
G-Manが「Reinstate Monica」と言う

私の言語なのでスペイン語ですが、英語で修正できます。$ HOSTは試すアドレスです。$ LINE1は、eth0アダプターによって接続されるインターネット接続です。$ LINE2は、インターネット回線が2本ある場合にオプションでeth1アダプターによって接続されるインターネット接続ですが、無効のままにしておくことをお勧めします。日付。スクリプトを開始してから同じ時刻と日付を維持していることを確認したら、その問題を修正する必要があります。今週の週末に問題を修正します。
ジョンLlewelyn

OK、G-Man、私はいくつかの変更を加えましたが、まだ日付を修正し、いくつかのことを改善する必要があります。
ジョンLlewelyn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.