インターネット接続をチェックするというスクリプトを見つけました。一部は、インターフェースがアップしている場合にIPアドレスをチェックしますが、インターネット接続をチェックしません。 if [ 'ping google.com -c 4 | grep time' != "" ]; then
のようにpingを使用するものを見つけましたが、ping自体が何らかの理由(たとえば、スタックしたIOを待機している)でハングする可能性があるため、これは信頼できない場合があります。
スクリプトを使用してインターネット接続を確認する適切な/信頼できる方法に関する提案はありますか?一部のパッケージを使用する必要がありますか?
たとえば、cron
を使用して定期的にチェックできる必要があります。次に、接続がダウンしたときに、invoke ifup --force [interface]
のように何かを行います。
ネットワークが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
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
一部のファイアウォールは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」)、その結果を報告します。
複数の方法でインターネット接続をチェックするスクリプトを作成しました(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
インターネットには多くの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
どこ
各ユーザーと他の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
@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