Skip to content

Instantly share code, notes, and snippets.

@asifbacchus
Last active June 19, 2019 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asifbacchus/9fd63abd6328c309d0981910b042d50e to your computer and use it in GitHub Desktop.
Save asifbacchus/9fd63abd6328c309d0981910b042d50e to your computer and use it in GitHub Desktop.
Query local or remote SSH server for fingerprint and generate SSHFP DNS records
#!/bin/sh
#
# Scan specified server and output BIND9 formatted SSHFP DNS records
# for all supported algorithms (RSA, DSA, ECDSA, ED25519) with both
# SHA-1 and SHA-2 hashes
#
### text formatting codes
bold=$(tput bold)
cyan=$(tput bold)$(tput setaf 6)
err=$(tput bold)$(tput setaf 1)
magenta=$(tput bold)$(tput setaf 5)
norm=$(tput sgr0)
yellow=$(tput bold)$(tput setaf 3)
# trap
trap cleanup 1 2 3 6
### functions
# cleanup
cleanup () {
rm -f "${TMPFILE}"
printf "\n${yellow}...Exiting now${norm}\n\n"
}
# script help
scriptHelp () {
printf "\n"
fmt --width="$( tput cols )" << ENDTEXT
This script scans a target system (or local system) and gets the SSH fingerprints of that system based on the 'host key' certificates it presents. It then formats those fingerprints into SSHFP records you can add to your DNS server so that clients can automatically check and confirm those fingerprints
ENDTEXT
printf "\n${cyan}Usage: ${norm}${bold}%s ${yellow}[options]${norm}\n" "$0"
printf "\n${cyan}Options:${norm}\n"
printf "With no options, script will query ${magenta}%s${norm} on " \
"$( uname -n )"
printf "SSH default ${magenta}port 22${norm}.\n\n"
printf "${yellow}-h, --host, --hostname, -a, --address${norm}\n"
printf "hostname or IP address of remote machine you want to scan\n\n"
printf "${yellow}-p, --port${norm}\n"
printf "port on which to connect during scanning - useful if SSH is\n"
printf "listening on a non-standard port\n\n"
printf "${yellow}-?, --help${norm}\n"
printf "display this help screen\n\n"
}
### end of functions
### default variables
protocols="rsa
dsa
ecdsa
ed25519"
port=22
hostname="$( uname -n )"
TMPFILE="$( mktemp )"
### process start up parameters
while [ $# -gt 0 ]; do
case "$1" in
-/?|--help)
# display help
scriptHelp
exit 0
;;
-h|--host|--hostname|-a|--address)
# remote machine to scan
hostname="$2"
shift
;;
-p|--port)
# scan on specified port
port="$2"
shift
;;
*)
# invalid entry
printf "${err}\nUnknown option: %s\n" "$1"
printf "${cyan}Use '--help' for valid options.${norm}\n\n"
exit 1
;;
esac
shift
done
### iterate over protocols and display SSHFP records
printf "\nScanning ${cyan}%s${norm}:\n" "$hostname"
while read -r proto; do
ssh-keyscan -t "$proto" -p "$port" "$hostname" > "$TMPFILE" 2>/dev/null
[ ! -s "$TMPFILE" ] && continue
sed -ri 's/^[^ ]+ //' "$TMPFILE"
sshfp="$( ssh-keygen -r "$hostname" -f "$TMPFILE" )"
printf "\n${bold}%s\n${norm}" "$sshfp"
done <<EOF
$protocols
EOF
### explanatory text
printf "\n${cyan}Reference:\n${norm}"
printf "First number is the ${magenta}algorithm type${norm}:\n"
printf "\t1\tRSA\n"
printf "\t2\tDSA\n"
printf "\t3\tECDSA\n"
printf "\t4\tED25519\n"
printf "\nSecond number is the ${magenta}hash type${norm}:\n"
printf "\t1\tSHA-1\n"
printf "\t2\tSHA-2\n"
printf "\n${magenta}Note: Best practices are using using either RSA or ED25519 "
printf "and SHA-2 only!${norm}\n"
### cleanup and exit
cleanup
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment