#!/usr/bin/env bash # Usage: ./chkh [hostname | -h | --help | -?] [known_hosts] # or # bash [hostname | -h | --help | -?] [known_hosts] # Examples: ~$ ./chkh (localhost in own known_hosts) # ~$ bash chkh (localhost in own known_hosts) # ~# ./chkh www.ncfi.no (www.ncfi.no in own [roots] known_hosts) # ~# bash chkh www.ncfi.no (www.ncfi.no in own [roots] known_hosts) # ~$ sudo ./chkh www.ncfi.no /home/user/.ssh/known_hosts # ~$ sudo bash chkh www.ncfi.no /home/user/.ssh/known_hosts # Description: Search for hashed known_hosts like "ssh-keygen -F hostname" # Author: Patrick Neumann (patrick@neumannsland.de) # Version: 1.0 # Date: 09.01.2020 # License: GPL3 # Warranty: This program is distributed WITHOUT ANY WARRANTY # config: readonly DEFAULT_H="localhost" readonly DEFAULT_K="${HOME}/.ssh/known_hosts" # display help: if [ "${1}" = "-h" -o "${1}" = "--help" -o "${1}" = "-?" ] ; then echo "Usage: ${0} [hostname | -h | --help | -?] [known_hosts]" echo " Default hostname: ${DEFAULT_H}" echo " Default known_host: ${DEFAULT_K}" exit 0 fi # set and check hostname: if [ -n "${1}" ] ; then readonly HOSTNAME="${1}" else readonly HOSTNAME="${DEFAULT_H}" fi if ! echo "${HOSTNAME}" | grep -E "^[[:alnum:]]+.*" 2>&1 > /dev/null ; then echo "Please specify a valid hostname!" exit 1 fi # set and check known_hosts: if [ -n "${2}" ] ; then readonly KNOWN_HOSTS="${2}" else readonly KNOWN_HOSTS="${DEFAULT_K}" fi [ -f "${KNOWN_HOSTS}" ] || { echo "file not found!" ;exit 2; } # walk through known_hosts... while IFS= read -r line do # the "second" field (the file is starting with the separator!) # is the salt in base64: SALT="$( echo "${line}" \ | cut -d "|" -f 3 \ | base64 --decode \ | xxd -p )" # the "third" field is the "hmaced" hash: SHA1="$( echo -n "${HOSTNAME}" \ | openssl dgst -sha1 -mac HMAC -macopt hexkey:"${SALT}" \ | cut -d " " -f 2 \ | xxd -r -p \ | base64 )" # grep to get the hole line: grep -F "${SHA1}" "${KNOWN_HOSTS}" done < "${KNOWN_HOSTS}" exit 0