#!/usr/bin/env bash 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 notif="pushover" 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 } dotenv 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="https://gotify.maboiteverte.fr" 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" ./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 \n" $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 up (status code: 200, 301, 302, 303, 307), then certificate information will be displayed." echo -e "If the site is down 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 Check the url passed as argument." echo -e " -h | --help Display this help." echo # echo some stuff here for the -a or --add-options exit 1 } : << 'COMMENTS' while [[ "$#" -gt 0 ]]; do case $1 in -h|--help) display_help; shift ;; *) echo "Unknown parameter passed: $1" ;; esac shift done COMMENTS 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=${OPTARG%=$file} 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 showcertif >/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") else # Chargement de la liste des urls depuis urls_list.txt while read -r line do [ ${line:0:1} != "#" ] && urls+=("$line") done < 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' urls_sorted=($(sort <<<"${urls[*]}")) unset IFS urls=() newArr=() while IFS= read -r -d '' x do urls+=("$x") done < <(printf "%s\0" "${urls_sorted[@]}" | sort -uz) 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 showcertif >/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 } : << 'COMMENTS2' COMMENTS2 i=1 array_names=() array_responses=() for url in "${!urls[@]}" do check_url "${urls[$url]}" "$i" ((i=i+1)) if [ "$i" -gt 13 ]; then break fi done # Affichage des serveurs qui ne répondent pas if [ -f "./urls_down_list_curl.txt" ]; 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\n" # On affiche uniquement les erreurs rencontrées for val in ${!array_responses[@]} do a="${array_responses[$val]}" status_error "$a" done echo "" if [ "$notif" == "gotify" ];then msg_md="$url_down" # MESSAGE="**A new version of Pi-hole is available:**\n\n $msg_md\n\n $infos\n\n Please run *pihole -up* on $host to update !" 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" #pushover -a "bash" -m "A new version of Pi-hole is available:
$msg_html
$infos_html
Please run pihole -up on $host to update" -p 2 -f 1 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" # MESSAGE="**A new version of Pi-hole is available:**\n\n $msg_md\n\n $infos\n\n Please run *pihole -up* on $host to update !" 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" #pushover -a "bash" -m "A new version of Pi-hole is available:
$msg_html
$infos_html
Please run pihole -up on $host to update" -p 2 -f 1 fi else echo -e "${green}\nNo certificat outdated !${reset}" fi # curl --write-out "%{json}" https://nextcloud.photos-nas.ovh | jq