Skip to content

Instantly share code, notes, and snippets.

@xopr
Created March 20, 2022 15:06
Show Gist options
  • Save xopr/218f205d7f1d239f2edfbfc7203574a8 to your computer and use it in GitHub Desktop.
Save xopr/218f205d7f1d239f2edfbfc7203574a8 to your computer and use it in GitHub Desktop.
check a set of services: http(s), dns, srv, enum, vpn, radius, spacestate, voip
#!/usr/bin/env bash
# Cannot run anything useful without grep
if ( ! command -v grep &> /dev/null ); then
echo "Cannot continue without grep" >&2
exit 10
fi
ACKSPACE_NL_4="185.145.156.70"
ACKSPACE_NL_6="2a07:4840:0:1::54"
ACK_SPACE_4=$ACKSPACE_NL_4
ACK_SPACE_6=$ACKSPACE_NL_6
LISTS_ACKSPACE_NL_4="185.45.112.172"
LISTS_ACKSPACE_NL_6="2a02:e00:fff0:525::a"
VPN_ACKSPACE="185.45.112.226" #schijtdoos.allesiskapot.nl
SPACEPHONE_ORG_4="185.45.112.70"
SPACEPHONE_ORG_6="2a02:e00:fff0:43::3"
#SPACEFED_NET_4="82.197.218.208" # Original
#SPACEFED_NET_6="2001:470:7b66:0:5054:ff:fee7:58a6" # Original
SPACEFED_NET_4="185.45.112.70"
SPACEFED_NET_6="2a02:e00:fff0:43::3"
set_term_size() {
TERM_SIZE="$(stty size 2>/dev/null)" && [ "$TERM_SIZE" ] ||
TERM_SIZE='25 80'
}
trap set_term_size WINCH
set_term_size
# Column number to place the status message
RES_COL="$((${TERM_SIZE#* } - 10))"
# Command to move out to the configured column number
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
# Command to set the color to SUCCESS (Green)
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
# Command to set the color to FAILED (Red)
SETCOLOR_FAILURE="echo -en \\033[1;31m"
# Command to set the color to WARNING (Yellow)
SETCOLOR_NOTICE="echo -en \\033[1;33m"
# From https://misc.flogisoft.com/bash/tip_colors_and_formatting
# Command to set the color to WARNING (orange 208 or 214)
SETCOLOR_WARNING="echo -en \\033[38;5;214m"
# Command to set the color back to normal
SETCOLOR_NORMAL="echo -en \\033[0;39m"
# Function to print the SUCCESS status
echo_success() {
if [[ -z $1 ]]; then message=" OK "; else message="$1"; fi
$MOVE_TO_COL
echo -n "["
$SETCOLOR_SUCCESS
echo -n "$message"
$SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 0
}
# Function to print the FAILED status message
echo_failure() {
if [[ -z $1 ]]; then message="FAILED "; else message="$1"; fi
$MOVE_TO_COL
echo -n "["
$SETCOLOR_FAILURE
echo -n "$message"
$SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
# Function to print the N/A status message
echo_warning() {
if [[ -z $1 ]]; then message=" /!\\ "; else message="$1"; fi
$MOVE_TO_COL
echo -n "["
$SETCOLOR_WARNING
echo -n "$message"
$SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
# Function to print the N/A status message
echo_notice() {
if [[ -z $1 ]]; then message=" N/A "; else message="$1"; fi
$MOVE_TO_COL
echo -n "["
$SETCOLOR_NOTICE
echo -n "$message"
$SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
function reverse_dns()
{
# Some methods to do reverse dotted notation:
# echo $1 | rev | sed 's/[0-9]/&\./g'
# echo $1 | sed 'G;:a;s/^\(.\)\(.*\n\)/\2\1\./;ta;s/\n//'
# echo $1 | awk '{ for(i=length;i!=0;i--)x=x substr($0,i,1)".";}END{print x}'
if ( command -v sed &> /dev/null ); then
echo $1 | sed 'G;:a;s/^\(.\)\(.*\n\)/\2\1\./;ta;s/\n//'
elif ( command -v awk &> /dev/null ); then
echo $1 | awk '{ for(i=length;i!=0;i--)x=x substr($0,i,1)".";}END{print x}'
else
echo -e "\tneeds sed or awk"
echo_failure
echo
return 20
fi
}
function check_dns()
{
echo -ne "\tDNS: $1"
# TODO: nslookup alternative
if ( ! command -v dig &> /dev/null ); then
echo -e "\tneeds dig"
echo_failure
echo
return 20
fi
# NOTE: use grep instead of `head -1` to reduce potential dependencies
IP4=$(dig -tA +short $1 | grep -Eo '[0-9\.]{7,15}' | grep -m1 "")
IP6=$(dig -tAAAA +short $1 | grep -Eo '[0-9a-f\:]{3,39}' | grep -m1 "")
if [[ -z $IP4 && -z $IP6 ]]; then
echo_failure " N/A "
echo
return 10
elif [[ $IP4 == $2 && $IP6 == $3 ]]; then
echo_success
echo
return 0
elif [[ -z $IP4 ]]; then
echo_warning "NO IPv4"
echo
if [[ $IP6 != $3 ]]; then
echo_notice "WRONG 6"
echo
return 4
fi
return 3
elif [[ -z $IP6 ]]; then
echo_notice "NO IPv6"
echo
if [[ $IP4 != $2 ]]; then
echo_notice "WRONG 4"
echo
return 6
fi
return 2
else
echo -en "\t$IP"
echo_notice VARIANT
echo
return 1
fi
}
function check_web()
{
echo -ne "\tweb: $1"
# TODO: alternative wget -S http://ackspace.nl -O/dev/null
if ( ! command -v curl &> /dev/null ); then
echo -e "\tneeds curl"
echo_failure
echo
return 20
fi
# NOTE: use grep instead of `head -1` and `awk '/HTTP\// {print $2}'` to reduce potential dependencies
HTTP4=$(curl --connect-timeout 1 -I4 "http://$1" 2>/dev/null | grep -Pom1 "^HTTP\/[^\s]+\s+\K\d+")
HTTP4_SSL=$(curl --connect-timeout 1 -vI4 "https://$1" 2>&1)
HTTPS4=$(echo "$HTTP4_SSL" | grep -Pom1 "^HTTP\/[^\s]+\s+\K\d+")
HTTP4_CERT=$(echo "$HTTP4_SSL" | grep -Po "subject: CN=\K.*|expire date: \K.*")
HTTP4_301S=$(echo "$HTTP4_SSL" | grep -Po "Location: \K(https://)")
HTTP4_SELF=$(echo "$HTTP4_SSL" | grep -Po "self signed certificate")
HTTP6=$(curl --connect-timeout 1 -I6 "http://$1" 2>/dev/null | grep -Pom1 "^HTTP\/[^\s]+\s+\K\d+")
HTTP6_SSL=$(curl --connect-timeout 1 -vI6 "https://$1" 2>&1)
HTTPS6=$(echo "$HTTP6_SSL" | grep -Pom1 "^HTTP\/[^\s]+\s+\K\d+")
HTTP6_CERT=$(echo "$HTTP6_SSL" | grep -Po "subject: CN=\K.*|expire date: \K.*")
HTTP6_SELF=$(echo "$HTTP6_SSL" | grep -Po "self signed certificate")
if [[ -z $HTTP4 && -z $HTTP6 && -z $HTTP4_CERT && -z $HTTP6_CERT ]]; then
echo_failure "OFFLINE"
echo
return 10
elif [[ -z $HTTP4 && -z $HTTP6 ]]; then
echo_notice "ONLYSSL"
echo
return 2
elif [[ -z $HTTP6 && -z $HTTP6_CERT ]]; then
echo_notice "NO IPv6"
echo
return 3
elif [[ -z $HTTP4_CERT && -z $HTTP6_CERT ]]; then
if [[ -n $HTTP4_SELF && -n $HTTP6_SELF ]]; then
echo_notice "GEN-CRT"
echo
return 1
else
echo_failure "NO SSL"
echo
return 5
fi
elif [[ -z $HTTP4 && -z $HTTP4_CERT ]]; then
echo_failure "NO IPv4"
echo
return 6
elif [[ -z $HTTPS4 && -z $HTTPS6 ]]; then
# print cert date/remote
echo_notice "NO CERT"
echo
return 4
else
case "$HTTP4 $HTTPS4" in
"200 200")
echo_notice "UP "
echo
return 1
;;
"301 200")
# For now, assume 301 is a redirect to SSL
echo_success "UP->SSL"
echo
return 0
;;
"301 301")
# Make sure it's redirecting to https
if [[ -z $HTTP4_301S ]]; then
echo_warning "UP->301"
echo
return 1
else
echo_success "UP->301"
echo
return 0
fi
;;
"")
echo_failure " DOWN "
echo
return 10
;;
*)
echo_failure "BROKEN"
echo
return 10
;;
esac
fi
}
function check_vpn()
{
echo -ne "\tVPN: $1:$2"
if ( command -v hexdump &> /dev/null ); then
HD="hexdump"
elif ( command -v hd &> /dev/null ); then
HD="hd"
else
echo -e "\tneeds hexdump"
echo_failure
echo
return 20
fi
if ( command -v nc &> /dev/null ); then
NC="nc"
elif ( command -v netcat &> /dev/null ); then
NC="netcat"
else
echo -e "\tneeds netcat"
echo_failure
echo
return 20
fi
# Send a magic string and expect at least a null character back
VPN=$(echo -e "\x00\x0e\x38\xd0\xe1\x8e\x7a\x19\x33\xf1\x20\x00\x00\x00\x00\x00" | $NC -w 1 $1 $2 | $HD -v -e '/1 "%02X "' | grep " 00 ")
if [[ -z $VPN ]]; then
echo_failure
echo
return 10
else
echo_success
echo
return 0
fi
}
function check_radius()
{
echo -ne "\tRADIUS: $1"
if ( ! command -v radclient &> /dev/null ); then
echo -e "\tneeds freeradius-utils"
echo_failure
echo
return 20
fi
REPLY=$(echo "User-Name = test" | radclient -t 2.1 -r 1 $1 auth DUMMY_PASS 2>&1 | grep "Received Access-Reject")
if [[ -z $REPLY ]]; then
echo_failure
echo
return 10
else
echo_success
echo
return 0
fi
}
function check_spacestate()
{
echo -ne "\tSpaceAPI: $1"
# TODO: alternative wget -S http://ackspace.nl -O/dev/null
if ( ! command -v curl &> /dev/null ); then
echo -e "\tneeds curl"
echo_failure
echo
return 20
fi
REPLY=$(curl --connect-timeout 1 "https://$1" 2>/dev/null | grep -Po '"open"\s*:\s*\K([a-z]+)')
case "$REPLY" in
"true")
echo_success " OPEN "
echo
return 0
;;
"false")
echo_success "CLOSED "
echo
return 0
;;
"null")
echo_failure "OFFLINE"
echo
return 10
;;
"")
echo_failure " ERROR "
echo
return 10
;;
*)
echo_failure "BROKEN"
echo
return 10
;;
esac
}
function check_srv()
{
# See https://github.com/jacopodl/DNSTorch/blob/master/srv.txt
echo -ne "\tSRV: $1"
if ( command -v dig &> /dev/null ); then
TCP=$(dig -t srv _sip._tcp.$1 | grep -Po "^_sip.* \K(.*)")
UDP=$(dig -t srv _sip._udp.$1 | grep -Po "^_sip.* \K(.*)")
SSL=$(dig -t srv _sips._tcp.$1 | grep -Po "^_sip.* \K(.*)")
TLS=$(dig -t srv _sip._tls.$1 | grep -Po "^_sip.* \K(.*)")
elif ( command -v nslookup &> /dev/null ); then
TCP=$(nslookup -type=SRV _sip._tcp.$1 | grep -Po "^_sip.* \K(.*)")
UDP=$(nslookup -type=SRV _sip._udp.$1 | grep -Po "^_sip.* \K(.*)")
SSL=$(nslookup -type=SRV _sips._tcp.$1 | grep -Po "^_sip.* \K(.*)")
TLS=$(nslookup -type=SRV _sip._tls.$1 | grep -Po "^_sip.* \K(.*)")
elif ( command -v host &> /dev/null ); then
TCP=$(host -t SRV _sip._tcp.$1 | grep -Po "^_sip.* \K(.*)")
UDP=$(host -t SRV _sip._udp.$1 | grep -Po "^_sip.* \K(.*)")
SSL=$(host -t SRV _sips._tcp.$1 | grep -Po "^_sip.* \K(.*)")
TLS=$(host -t SRV _sip._tls.$1 | grep -Po "^_sip.* \K(.*)")
else
echo -e "\tneeds dig, nslookup or host"
echo_failure
echo
return 20
fi
# require udp, expect tcp, check ssl and tls
if [[ -n $TCP && -n $UDP ]]; then
if [[ -n $SSL && -n $TLS ]]; then
echo_success " FULL "
echo
return 0
elif [[ -n $SSL || -n $TLS ]]; then
echo_success "PARTIAL"
echo
return 0
else
echo_notice "NON-ENC"
echo
return 1
fi
elif [[ -n $UDP ]]; then
if [[ -z $SSL && -z $TLS ]]; then
echo_warning "MINIMAL"
echo
return 8
else
echo_warning "UDP+SEC"
echo
return 2
fi
elif [[ -n $UDP || -n $SSL || -n $TLS ]]; then
# TCP
if [[ -z $SSL && -z $TLS ]]; then
echo_warning "INVALID"
echo
return 8
fi
else
echo_failure "MISSING"
echo
return 10
fi
}
function check_enum()
{
echo -ne "\tENUM: $1"
# TODO: nslookup alternative
if ( ! command -v dig &> /dev/null ); then
echo -e "\tneeds dig"
echo_failure
echo
return 20
fi
NUMBER=$(reverse_dns $1)
# TODO: check if failed
REPLY=$(dig ${NUMBER}e164.spacephone.org -t NAPTR | grep "E2U+sip")
if [[ -z $REPLY ]]; then
echo_failure
echo
return 10
else
echo_success
echo
return 0
fi
}
function check_voip()
{
echo -ne "\tVoIP: $1"
if ( command -v nc &> /dev/null ); then
NC="nc"
elif ( command -v netcat &> /dev/null ); then
NC="netcat"
else
echo -e "\tneeds netcat"
echo_failure
echo
return 20
fi
CRLF='\r\n'
SIPMSG=""
SIPMSG=$SIPMSG"BYE sip:$1 SIP/2.0"$CRLF
SIPMSG=$SIPMSG"Via: SIP/2.0/TCP $1"$CRLF
SIPMSG=$SIPMSG"To: sip:$1;tag=x"$CRLF
SIPMSG=$SIPMSG"From: sip:555@nowhere"$CRLF
SIPMSG=$SIPMSG"Call-ID: 555@nowhere"$CRLF
SIPMSG=$SIPMSG"Cseq: 1 BYE"$CRLF
SIPMSG=$SIPMSG$CRLF
REPLY=$(echo -e $SIPMSG | $NC -w 1 -C $1 5060 | grep "Bad Request")
if [[ -z $REPLY ]]; then
echo_failure
echo
return 10
else
echo_success
echo
return 0
fi
}
function END()
{
return # dummy
}
# Blockcomment
: << END
END
echo
echo ACKspace
# Make sure the DNS resolves to expected IP addresses
check_dns ackspace.nl $ACKSPACE_NL_4 $ACKSPACE_NL_6
if [[ $? -ge 10 ]]; then ACK=true; fi
check_dns ack.space $ACKSPACE_NL_4 $ACKSPACE_NL_6
if [[ $? -ge 1 ]]; then ACK=true; fi
#check_dns ipv6.ackspace.nl $ACKSPACE_NL_4 $ACKSPACE_NL_6
# Check IPv4/IPv6 and HTTP/HTTPS including certificate validation
check_web ackspace.nl
if [[ $? -ge 10 ]]; then ACK=true; fi
check_web ack.space
if [[ $? -ge 10 ]]; then ACK=true; fi
#check_web ipv6.ackspace.nl
check_web lists.ackspace.nl
if [[ $? -ge 10 ]]; then ACK=true; fi
check_web server.ackspace.nl:2083
if [[ $? -ge 10 ]]; then ACK=true; fi
check_web server.ackspace.nl:2087
if [[ $? -ge 10 ]]; then ACK=true; fi
# Make sure the VPN responds
check_vpn schijtdoos.allesiskapot.nl 9001
if [[ $? -ge 10 ]]; then ACK=true; fi
# Verify response from RADIUS server
check_radius lists.ackspace.nl
if [[ $? -ge 10 ]]; then ACK=true; fi
# Lookup spacestate (to determine if the space is offline)
check_spacestate ackspace.nl/spaceAPI/
if [[ $? -ge 10 ]]; then ACK=true; fi
check_voip sip.ackspace.nl
if [[ $? -ge 10 ]]; then ACK=true; fi
check_srv ackspace.nl
if [[ $? -ge 10 ]]; then ACK=true; fi
echo
echo SpaceFED
check_dns spacefed.net $SPACEFED_NET_4 $SPACEFED_NET_6
if [[ $? -ge 10 ]]; then FED=true; fi
check_web spacefed.net
if [[ $? -ge 10 ]]; then FED=true; fi
#check_radius klimrek.nikhef.nl # can't check nlnode since our IP is not whitelisted
echo
echo SpacePhone
check_dns spacephone.org $SPACEPHONE_ORG_4 $SPACEPHONE_ORG_6
if [[ $? -ge 10 ]]; then PHONE=true; fi
check_web spacephone.org
if [[ $? -ge 10 ]]; then PHONE=true; fi
check_enum 31979922
if [[ $? -ge 10 ]]; then PHONE=true; fi
echo
echo "@xopr's"
check_web spacefed.glitchentertainment.nl
if [[ $? -ge 10 ]]; then XOPR=true; fi
check_web boshovenpop.prolly.nl
if [[ $? -ge 10 ]]; then XOPR=true; fi
check_vpn some_nas.dynu.net 1194
if [[ $? -ge 10 ]]; then XOPR=true; fi
check_voip 666.666.666.666
if [[ $? -ge 10 ]]; then XOPR=true; fi
#check_srv pauper.tel
#if [[ $? -ge 10 ]]; then XOPR=true; fi
#check_srv deillegaleshow.nl
#if [[ $? -ge 10 ]]; then XOPR=true; fi
#check_srv illegaleshow.stream
#if [[ $? -ge 10 ]]; then XOPR=true; fi
#check_srv spacephone.org
#if [[ $? -ge 10 ]]; then XOPR=true; fi
check_srv glitchentertainment.nl
if [[ $? -ge 10 ]]; then XOPR=true; fi
check_srv prolly.nl
if [[ $? -ge 10 ]]; then XOPR=true; fi
echo
echo "Summary:"
if [[ -z $ACK && -z $FED && -z $PHONE && -z $XOPR ]]; then
echo -e "\tAll ok"
else
if [[ -n $ACK ]]; then
echo -e "\tProblems at ACKspace"
fi
if [[ -n $FED ]]; then
echo -e "\tProblems at SpaceFED"
fi
if [[ -n $PHONE ]]; then
echo -e "\tProblems at SpacePhone"
fi
if [[ -n $XOPR ]]; then
echo -e "\tProblems at xopr's"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment