369 lines
10 KiB
Bash
Executable File
369 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Check SSL certificates and http codes for key domains
|
|
#
|
|
# Run: ./url_check.sh
|
|
|
|
VERSION="v1.0"
|
|
|
|
italic="\033[3m"
|
|
underline="\033[4m"
|
|
ita_under="\033[3;4m"
|
|
bgd="\033[1;4;31m"
|
|
red="\033[0;31m"
|
|
bold="\033[1m"
|
|
bold_ita="\033[1;3m"
|
|
box="\033[1;41m"
|
|
redbold="\033[1;31m"
|
|
redbox="\033[1;41m"
|
|
green="\033[0;32m"
|
|
greenbold="\033[1;32m"
|
|
reset="\033[0m"
|
|
|
|
|
|
cat < /dev/null > /dev/tcp/1.1.1.1/53
|
|
if [[ $? -ne 0 ]]; then
|
|
echo -e "\n${red}No Internet connection !${reset}"
|
|
echo -e "Exit !"
|
|
exit 1
|
|
fi
|
|
|
|
url=
|
|
urls=()
|
|
port=443
|
|
# Days left before notification
|
|
nday=15
|
|
# Choose the notification (pushover or gotify)
|
|
notif="pushover"
|
|
x=0
|
|
|
|
not_required_domains="$HOME/Documents/Scripts/pihole/sync_pihole_lan.sh"
|
|
|
|
|
|
dotenv () {
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
[ -f "$HOME/.env" ] && . "$HOME/.env" || echo -e "${red}\nNo .env file found ! Could'nt get update from Github or send notification.'.${reset}"
|
|
set +a
|
|
#
|
|
# Gotify: $GOTIFY_SERVER (server url), $GOTIFY_BASH (token)
|
|
# Pushover: $USER_KEY$ (user) $BASH_APP (token)
|
|
}
|
|
|
|
dotenv
|
|
|
|
### Variables for self updating
|
|
ScriptArgs=( "$@" )
|
|
ScriptPath="$(readlink -f "$0")"
|
|
ScriptWorkDir="$(dirname "$ScriptPath")"
|
|
|
|
|
|
send_gotify_notification() {
|
|
# Enabled HSTS & created default WebSocket records in the DSM 7.2 reverse proxy window and it solved itself.
|
|
|
|
now=$(date +"%d-%m-%Y %T")
|
|
gotify_server="$GOTIFY_SERVER"
|
|
gotify_token="$GOTIFY_BASH"
|
|
TITLE="$1"
|
|
MESSAGE="$2"
|
|
PRIORITY=8
|
|
URL="$gotify_server/message?token=$gotify_token&?format=markdown"
|
|
|
|
echo -e "Sending notification to $gotify_server ..."
|
|
# -S, --show-error Show error even when -s is used
|
|
# -s, --silent Silent mode
|
|
# -v Verbose
|
|
|
|
curl -s -S --output /dev/null --data '{"message": "'"${MESSAGE}"'", "title": "'"${TITLE}"'", "priority":'"${PRIORITY}"', "extras": {"client::display": {"contentType": "text/markdown"}}}' -H 'Content-Type: application/json' "$URL"
|
|
|
|
[ $? -eq 0 ] && echo -e "${greenbold}Gotify notification sent successfully !${reset}" || echo -e "${redbold}error sending Gotify notification !${reset}"
|
|
}
|
|
|
|
send_pushover_notification() {
|
|
echo -e "Sending Pushover notification ..."
|
|
curl -S -s -o /dev/null -F "token=$BASH_APP" \
|
|
-F "user=$USER_KEY" \
|
|
-F "title=$1" \
|
|
-F priority=2 \
|
|
-F html=1 \
|
|
-F retry=60 \
|
|
-F expire=86400 \
|
|
-F "message=$2" https://api.pushover.net/1/messages.json
|
|
|
|
[ $? -eq 0 ] && echo -e "${greenbold}Pushover notification sent successfully !${reset}" || echo -e "${redbold}error sending Pushover notification !${reset}"
|
|
}
|
|
|
|
status_error() {
|
|
info_code=$(grep "$1" "$ScriptWorkDir/status.txt")
|
|
status_code=$(echo "$info_code" | awk -F";" '{print $1}')
|
|
status_title=$(echo "$info_code" | awk -F";" '{print $2}')
|
|
status_url=$(echo "$info_code" | awk -F";" '{print $3}')
|
|
printf "%-3s %-25s %-95s" $status_code "$status_title" "$status_url"
|
|
}
|
|
|
|
display_help() {
|
|
# taken from https://stackoverflow.com/users/4307337/vincent-stans
|
|
echo "Usage: $0 " >&2
|
|
echo
|
|
echo -e "${bold}urls_check.sh${reset} will read a list of urls in ${underline}urls_list.txt${reset} file, then return the status code for each url."
|
|
echo -e "If the site is ${green}up${reset} (status code: 200, 301, 302, 303, 307), then certificate information will be displayed."
|
|
echo -e "If the site is ${red}down${reset} or the certificate is outdated, a Pushover (or Gotify) notification will be sent."
|
|
echo -e "${underline}status.txt${reset} give description and a link to Mozilla for each status code."
|
|
echo -e "${bold}showcert${reset} is required to check certificate ${italic}(pip install showcert)${reset}. If not, ${bold}openssl${reset} will be used."
|
|
echo
|
|
echo -e "${bold}Options:${reset}"
|
|
echo -e " -u <url> | --url <url> Check the url passed as argument."
|
|
echo -e " -h | --help Display this help."
|
|
echo
|
|
echo -e "${bold}urls_list.txt${reset}"
|
|
echo -e "https://subdomain1.domain.com"
|
|
echo -e "#https://subdomain2.domain.com"
|
|
echo -e "https://www.domain2.com"
|
|
echo -e "${italic}Add a # to ignore url${reset}"
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
|
|
optspec=":u:h-:"
|
|
while getopts "$optspec" opt
|
|
do
|
|
case $opt in
|
|
-) case "${OPTARG}" in
|
|
help) display_help;;
|
|
url)
|
|
url="${!OPTIND}"; OPTIND=$(( OPTIND + 1 ))
|
|
;;
|
|
url=*)
|
|
url=${OPTARG#*=}
|
|
opt="$(printf "%s\n" "${OPTARG}" | cut -d'=' -f1 )" ; url="$(printf "%s\n" "${OPTARG}" | cut -d'=' -f2-)"
|
|
;;
|
|
*)
|
|
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" = ":" ]; then
|
|
echo "Unknown option --${OPTARG}" >&2
|
|
fi
|
|
exit 3
|
|
;;
|
|
esac;;
|
|
u) url="${OPTARG}";;
|
|
h)
|
|
display_help
|
|
;;
|
|
*)
|
|
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then
|
|
echo "Non-option argument: '-${OPTARG}'" >&2
|
|
fi
|
|
exit 4
|
|
;;
|
|
esac
|
|
done
|
|
shift "$((OPTIND-1))"
|
|
|
|
|
|
command -v showcert >/dev/null 2>&1 || { echo -e "${bold}showcert${reset} is not installed ${italic}(pip install showcert)${reset}. ${bold}openssl${reset} will be used.\n" >&2; }
|
|
|
|
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]+'
|
|
if [[ $url =~ $regex ]]; then
|
|
# L'URL passé en argument est checkée
|
|
|
|
urls+=("$url")
|
|
x=1
|
|
else
|
|
# Chargement de la liste des urls depuis urls_list.txt
|
|
|
|
while read -r line
|
|
do
|
|
[ ${line:0:1} != "#" ] && urls+=("$line")
|
|
done < "$ScriptWorkDir/urls_list.txt"
|
|
|
|
# Ajout des domaines non-requis
|
|
|
|
if [ -f "$not_required_domains" ]; then
|
|
a=$(grep 'not_required=' $not_required_domains)
|
|
|
|
b=$(echo "$a" | awk -F"=" '{split($2, arr, "[()]"); print arr[2]}' | sed 's/\"//g')
|
|
not_required=(${b})
|
|
|
|
for val in "${!not_required[@]}"
|
|
do
|
|
z="https://${not_required[$val]}.photos-nas.ovh"
|
|
urls+=("${z}")
|
|
done
|
|
|
|
else
|
|
echo "file $not_required_domains not find !"
|
|
echo "Domain like drive.photos-nas.ovh won't be checked.'"
|
|
fi
|
|
|
|
# Tri du tableau d'urls
|
|
|
|
IFS=$'\n' sorted=($(sort <<<"${urls[*]}"))
|
|
unset IFS
|
|
|
|
fi
|
|
|
|
|
|
# On efface la liste des urls down
|
|
|
|
[ -f "./urls_down_list_curl.txt" ] && rm "./urls_down_list_curl.txt"
|
|
[ -f "./certificats_outdated.txt" ] && rm "./certificats_outdated.txt"
|
|
|
|
|
|
check_url() {
|
|
website=$(echo "$1" | awk -F "\/\/" '{print $2}')
|
|
response=$(curl --connect-timeout 10 --max-time 10 --retry 3 --retry-delay 0 --retry-max-time 30 --write-out '%{http_code}' --silent --output /dev/null "$1")
|
|
|
|
if [ $(grep -w "200\|301\|302\|303\|307" <<< "$response") ];then
|
|
echo -e "${greenbold}$2. $website is up${reset} ($response)"
|
|
|
|
# Si le serveur répond correctement, on affiche la validité du certificat
|
|
info_certif "$1"
|
|
|
|
else
|
|
echo -e "${redbold}$2. $1 is down${reset} ($response)"
|
|
echo "$1 is down ($response)" >> urls_down_list_curl.txt
|
|
|
|
# Affichage et description de l'erreur
|
|
status_error "$response"
|
|
echo -e "\n"
|
|
|
|
# Tableau des non-réponses uniques
|
|
if [[ " ${array_responses[*]} " != *"$response"* ]]; then
|
|
array_responses+=("$response")
|
|
fi
|
|
|
|
fi
|
|
}
|
|
|
|
info_certif() {
|
|
|
|
domain=$(echo "$1" | grep -Eo '^http[s]?://[^/]+' | cut -c 9- )
|
|
|
|
if command -v showcert >/dev/null 2>&1; then
|
|
|
|
cert=$(showcert "$domain")
|
|
|
|
ip=$(echo "$cert" | grep IP | awk -F": " '{print $2}')
|
|
names=$(echo "$cert" | grep Names | awk -F": " '{print $2}')
|
|
issuer=$(echo "$cert" | grep Issuer | awk -F": " '{print $2}')
|
|
start=$(echo "$cert" | grep Before | awk -F": " '{print $2}')
|
|
end=$(echo "$cert" | grep notAfter | awk -F": " '{print $2}')
|
|
left=$(echo "$end" | awk -F" " '{split($3, arr, "[()]"); print arr[2]}')
|
|
subject=""
|
|
else
|
|
cert=`echo |
|
|
openssl s_client -connect $domain:$port 2>/dev/null |
|
|
openssl x509 -issuer -subject -dates -noout`
|
|
|
|
issuer=$(echo "$cert" | grep issuer | awk -F"issuer=" '{print $2}')
|
|
subject=$(echo "$cert" | grep subject | awk -F"subject=" '{print $2}')
|
|
start=$(echo "$cert" | grep Before | awk -F"=" '{print $2}')
|
|
end=$(echo "$cert" | grep notAfter | awk -F"=" '{print $2}')
|
|
timestamp_current=$(date +"%s")
|
|
timestamp_end=$(date --date="$end" +"%s")
|
|
left=$(($((timestamp_end - timestamp_current))/(60*60*24)))
|
|
end="$end ($left days left)"
|
|
names=""
|
|
|
|
ip=$(dig +short $host)
|
|
fi
|
|
|
|
[ $left -lt $nday ] && echo -e "${red}"
|
|
if [ -n "$names" ]; then
|
|
echo -e "Names: $names"
|
|
elif [ -n "$subject" ]; then
|
|
echo -e "Subject: $subject"
|
|
fi
|
|
echo -e "Issuer: $issuer"
|
|
echo -e "Date début: $start"
|
|
echo -e "Date fin: $end\n"
|
|
[ $left -lt $nday ] && echo -e "${reset}"
|
|
|
|
if [ $left -lt $nday ]; then
|
|
echo "certif outdated..."
|
|
if [[ " ${array_names[*]} " != *"$names"* ]]; then
|
|
array_names+=("$names")
|
|
|
|
#echo "Domain: $domain" >> certificats_outdated.txt
|
|
echo "Names: $names" >> certificats_outdated.txt
|
|
echo "Issuer: $issuer" >> certificats_outdated.txt
|
|
echo "Date début: $start" >> certificats_outdated.txt
|
|
echo "Date fin: $end" >> certificats_outdated.txt
|
|
echo "" >> certificats_outdated.txt
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
i=1
|
|
array_names=()
|
|
array_responses=()
|
|
|
|
for url in "${!urls[@]}"
|
|
do
|
|
check_url "${urls[$url]}" "$i"
|
|
((i=i+1))
|
|
|
|
: << 'COMMENTS2'
|
|
if [ "$i" -gt 13 ]; then
|
|
break
|
|
fi
|
|
COMMENTS2
|
|
|
|
done
|
|
|
|
|
|
# Affichage des serveurs qui ne répondent pas
|
|
|
|
if [ -f "./urls_down_list_curl.txt" ]; then
|
|
if [ "$x" -ne 1 ]; then
|
|
echo -e "\n${redbold}Url down: ${reset}"
|
|
|
|
cp "./urls_down_list_curl.txt" urls_down_list_curl.bak
|
|
url_down=$(cat "./urls_down_list_curl.txt")
|
|
echo -e "$url_down"
|
|
|
|
# On affiche uniquement les erreurs rencontrées
|
|
for val in ${!array_responses[@]}
|
|
do
|
|
a="${array_responses[$val]}"
|
|
status_error "$a"
|
|
done
|
|
echo -e "\n"
|
|
fi
|
|
|
|
if [ "$notif" == "gotify" ];then
|
|
msg_md="$url_down"
|
|
send_gotify_notification "Several url are down !" "$msg_md"
|
|
elif [ "$notif" == "pushover" ];then
|
|
msg_html="$url_down"
|
|
send_pushover_notification "Several url are down !" "$msg_html"
|
|
fi
|
|
|
|
else
|
|
echo -e "${green}\nNo url is down !${reset}"
|
|
fi
|
|
|
|
|
|
# Liste des certificat pas à jour
|
|
|
|
if [ -f "./certificats_outdated.txt" ]; then
|
|
echo -e "\n${redbold}Certificat outdated: ${reset}"
|
|
|
|
certif_outdated=$(cat "./certificats_outdated.txt")
|
|
echo -e "$certif_outdated\n"
|
|
|
|
if [ "$notif" == "gotify" ];then
|
|
msg_md="$certif_outdated"
|
|
send_gotify_notification "Several certificats are outdated !" "$msg_md"
|
|
elif [ "$notif" == "pushover" ];then
|
|
msg_html="$certif_outdated"
|
|
send_pushover_notification "Several certificats are outdated !" "$msg_html"
|
|
fi
|
|
|
|
else
|
|
echo -e "${green}\nNo certificat outdated !${reset}"
|
|
fi
|
|
|