Merge branch '2.9dev' into generate_html

Conflicts:
	testssl.sh
This commit is contained in:
David Cooper 2017-02-13 09:14:22 -05:00
commit e953c737d1
2 changed files with 167 additions and 57 deletions

View File

@ -36,14 +36,13 @@ and more documentation") or https://github.com/drwetter/testssl.sh/wiki/Usage-Do
#### Compatibility #### Compatibility
testssl.sh is working on every Linux/BSD distribution out of the box with testssl.sh is working on every Linux/BSD distribution out of the box. In 2.9dev most
some limitations of disabled features from the openssl client -- some of the limitations of disabled features from the openssl client are gone due to bash-socket-based
workarounds are done with bash-socket-based checks. It also works on other checks. testssl.sh also works on otherunixoid system out of the box, supposed they have
unixoid system out of the box, supposed they have `/bin/bash` and standard `/bin/bash` and standard tools like sed and awk installed. System V needs to have GNU versions
tools like sed and awk installed. MacOS X and Windows (using MSYS2 or of grep and sed installed. MacOS X and Windows (using MSYS2 or cygwin) work too. OpenSSL
cygwin) work too. OpenSSL version >= 1 is a must. OpenSSL version >= 1.0.2 version >= 1 is a must. OpenSSL version >= 1.0.2 is needed for better LOGJAM checks and to
is needed for better LOGJAM checks and to display bit strengths for key display bit strengths for key exchanges.
exchanges.
Update notification here or @ [twitter](https://twitter.com/drwetter). Update notification here or @ [twitter](https://twitter.com/drwetter).
@ -56,6 +55,11 @@ Update notification here or @ [twitter](https://twitter.com/drwetter).
* testing 359 default ciphers (``testssl.sh -e``) with a mixture of sockets and openssl. Same speed as with openssl only but addtional ciphers such as post-quantum ciphers, new CHAHA20/POLY1305, CamelliaGCM etc. * testing 359 default ciphers (``testssl.sh -e``) with a mixture of sockets and openssl. Same speed as with openssl only but addtional ciphers such as post-quantum ciphers, new CHAHA20/POLY1305, CamelliaGCM etc.
* finding more TLS extensions via sockets * finding more TLS extensions via sockets
* TLS Supported Groups Registry (RFC 7919), key shares extension * TLS Supported Groups Registry (RFC 7919), key shares extension
* using bash sockets where ever possible
* LUCKY13 and SWEET32 checks
* LOGJAM: now checking also for known DH parameters
* Check for CAA RR
* better formatting of output
#### Features planned in 2.9dev #### Features planned in 2.9dev

View File

@ -1079,6 +1079,65 @@ out_row_aligned() {
done done
} }
# prints text over multiple lines, trying to make no line longer than $max_width.
# Each line is indented with $spaces and each word in $text is printed using
# $print_function.
out_row_aligned_max_width() {
local text="$1"
local spaces="$2"
local -i max_width="$3"
local print_function="$4"
local -i i len cut_point
local cr=$'\n'
local line entry first=true last=false
max_width=$max_width-1 # at the moment we align to terminal width. This makes sure we don't wrap too late
max_width=$max_width-${#spaces}
len=${#text}
while true; do
i=$max_width
if [[ $i -ge $len ]]; then
i=$len
else
while true; do
[[ "${text:i:1}" == " " ]] && break
[[ $i -eq 0 ]] && break
i=$i-1
done
if [[ $i -eq 0 ]]; then
i=$max_width+1
while true; do
[[ "${text:i:1}" == " " ]] && break
[[ $i -eq $len ]] && break
i+=1
done
fi
fi
if [[ $i -eq $len ]]; then
line="$text"
if ! "$first"; then
out "${cr}${spaces}"
fi
last=true
else
line="${text:0:i}"
if ! "$first"; then
out "${cr}${spaces}"
fi
len=$len-$i-1
i=$i+1
text="${text:i:len}"
first=false
[[ $len -eq 0 ]] && last=true
fi
while read entry; do
$print_function "$entry" ; out " "
done <<< "$(tr ' ' '\n' <<< "$line")"
"$last" && break
done
return 0
}
is_number() { is_number() {
[[ "$1" =~ ^[1-9][0-9]*$ ]] && \ [[ "$1" =~ ^[1-9][0-9]*$ ]] && \
return 0 || \ return 0 || \
@ -4758,6 +4817,44 @@ pr_ecdh_quality() {
fi fi
} }
pr_ecdh_curve_quality() {
curve="$1"
local -i bits=0
case "$curve" in
"sect163k1") bits=163 ;;
"sect163r1") bits=162 ;;
"sect163r2") bits=163 ;;
"sect193r1") bits=193 ;;
"sect193r2") bits=193 ;;
"sect233k1") bits=232 ;;
"sect233r1") bits=233 ;;
"sect239k1") bits=238 ;;
"sect283k1") bits=281 ;;
"sect283r1") bits=282 ;;
"sect409k1") bits=407 ;;
"sect409r1") bits=409 ;;
"sect571k1") bits=570 ;;
"sect571r1") bits=570 ;;
"secp160k1") bits=161 ;;
"secp160r1") bits=161 ;;
"secp160r2") bits=161 ;;
"secp192k1") bits=192 ;;
"prime192v1") bits=192 ;;
"secp224k1") bits=225 ;;
"secp224r1") bits=224 ;;
"secp256k1") bits=256 ;;
"prime256v1") bits=256 ;;
"secp384r1") bits=384 ;;
"secp521r1") bits=521 ;;
"brainpoolP256r1") bits=256 ;;
"brainpoolP384r1") bits=384 ;;
"brainpoolP512r1") bits=512 ;;
"X25519") bits=253 ;;
"X448") bits=448 ;;
esac
pr_ecdh_quality "$bits" "$curve"
}
# arg1: file with input for grepping the bit length for ECDH/DHE # arg1: file with input for grepping the bit length for ECDH/DHE
# arg2: whether to print warning "old fart" or not (empty: no) # arg2: whether to print warning "old fart" or not (empty: no)
@ -5356,7 +5453,7 @@ cipher_pref_check() {
if [[ -n "$order" ]]; then if [[ -n "$order" ]]; then
outln outln
out "$(printf " %-10s" "$proto: ")" out "$(printf " %-10s" "$proto: ")"
out "$order" out_row_aligned_max_width "$order" " " $TERM_WIDTH out
fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order"
fi fi
done done
@ -5370,7 +5467,7 @@ cipher_pref_check() {
order="" order=""
$OPENSSL s_client $BUGS -nextprotoneg "$p" -connect $NODEIP:$PORT $SNI </dev/null 2>>$ERRFILE >$TMPFILE $OPENSSL s_client $BUGS -nextprotoneg "$p" -connect $NODEIP:$PORT $SNI </dev/null 2>>$ERRFILE >$TMPFILE
cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE)
out "$(printf " %-10s %s " "$p:" "$cipher")" out "$(printf " %-10s " "$p:")"
tested_cipher="-"$cipher tested_cipher="-"$cipher
order="$cipher" order="$cipher"
if ! "$FAST"; then if ! "$FAST"; then
@ -5378,11 +5475,11 @@ cipher_pref_check() {
$OPENSSL s_client -cipher "ALL:$tested_cipher" $BUGS -nextprotoneg "$p" -connect $NODEIP:$PORT $SNI </dev/null 2>>$ERRFILE >$TMPFILE $OPENSSL s_client -cipher "ALL:$tested_cipher" $BUGS -nextprotoneg "$p" -connect $NODEIP:$PORT $SNI </dev/null 2>>$ERRFILE >$TMPFILE
sclient_connect_successful $? $TMPFILE || break sclient_connect_successful $? $TMPFILE || break
cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE)
out "$cipher "
tested_cipher="$tested_cipher:-$cipher" tested_cipher="$tested_cipher:-$cipher"
order+=" $cipher" order+=" $cipher"
done done
fi fi
out_row_aligned_max_width "$order" " " $TERM_WIDTH out
outln outln
[[ -n $order ]] && fileout "order_spdy_$p" "INFO" "Default cipher order for SPDY protocol $p: $order" [[ -n $order ]] && fileout "order_spdy_$p" "INFO" "Default cipher order for SPDY protocol $p: $order"
done done
@ -5949,7 +6046,7 @@ certificate_info() {
local ocsp_response_status=$6 local ocsp_response_status=$6
local sni_used=$7 local sni_used=$7
local cert_sig_algo cert_sig_hash_algo cert_key_algo local cert_sig_algo cert_sig_hash_algo cert_key_algo
local expire days2expire secs2warn ocsp_uri crl startdate enddate issuer_CN issuer_C issuer_O issuer sans san cn local expire days2expire secs2warn ocsp_uri crl startdate enddate issuer_CN issuer_C issuer_O issuer sans san all_san="" cn
local issuer_DC issuerfinding cn_nosni="" local issuer_DC issuerfinding cn_nosni=""
local cert_fingerprint_sha1 cert_fingerprint_sha2 cert_fingerprint_serial local cert_fingerprint_sha1 cert_fingerprint_sha2 cert_fingerprint_serial
local policy_oid local policy_oid
@ -6229,10 +6326,10 @@ certificate_info() {
out "$indent"; pr_bold " subjectAltName (SAN) " out "$indent"; pr_bold " subjectAltName (SAN) "
if [[ -n "$sans" ]]; then if [[ -n "$sans" ]]; then
while read san; do while read san; do
[[ -n "$san" ]] && pr_italic "$san" [[ -n "$san" ]] && all_san+="$san "
out " "
done <<< "$sans" done <<< "$sans"
fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $sans" out_row_aligned_max_width "$all_san" "$indent " $TERM_WIDTH pr_italic
fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $all_san"
else else
out "-- " out "-- "
fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : --" fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : --"
@ -6503,7 +6600,7 @@ certificate_info() {
caa="$(get_caa_rr_record $NODE)" caa="$(get_caa_rr_record $NODE)"
if [[ -n "$caa" ]]; then if [[ -n "$caa" ]]; then
pr_done_good "OK"; out " (" ; pr_italic "$caa"; out ")" pr_done_good "OK"; out " (" ; pr_italic "$caa"; out ")"
fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : offered" fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : \"$caa\" "
else else
pr_svrty_low "--" pr_svrty_low "--"
fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered" fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered"
@ -6666,7 +6763,7 @@ run_server_defaults() {
fileout "tls_extensions" "INFO" "TLS server extensions (std): (none)" fileout "tls_extensions" "INFO" "TLS server extensions (std): (none)"
else else
#FIXME: we rather want to have the chance to print each ext in italcs or another format. Atm is a string of quoted strings -- that needs to be fixed at the root #FIXME: we rather want to have the chance to print each ext in italcs or another format. Atm is a string of quoted strings -- that needs to be fixed at the root
outln "$TLS_EXTENSIONS" out_row_aligned_max_width "$TLS_EXTENSIONS" " " $TERM_WIDTH out; outln
fileout "tls_extensions" "INFO" "TLS server extensions (std): $TLS_EXTENSIONS" fileout "tls_extensions" "INFO" "TLS server extensions (std): $TLS_EXTENSIONS"
fi fi
@ -6714,9 +6811,9 @@ run_pfs() {
local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448")
local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04") local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04")
local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192")
local -a supported_curve bits local -a supported_curve
local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high
local pfs_ciphers curves_offered="" curves_offered_text="" curves_to_test temp local pfs_ciphers curves_offered="" curves_to_test temp
local len1 len2 curve_found local len1 len2 curve_found
local has_dh_bits="$HAS_DH_BITS" local has_dh_bits="$HAS_DH_BITS"
local using_sockets=true local using_sockets=true
@ -6868,7 +6965,6 @@ run_pfs() {
pfs_cipher="${rfc_ciph[i]}" pfs_cipher="${rfc_ciph[i]}"
fi fi
pfs_ciphers+="$pfs_cipher " pfs_ciphers+="$pfs_cipher "
! "$WIDE" && out "$pfs_cipher "
if [[ "${ciph[i]}" == "ECDHE-"* ]] || ( "$using_sockets" && [[ "${rfc_ciph[i]}" == "TLS_ECDHE_"* ]] ); then if [[ "${ciph[i]}" == "ECDHE-"* ]] || ( "$using_sockets" && [[ "${rfc_ciph[i]}" == "TLS_ECDHE_"* ]] ); then
ecdhe_offered=true ecdhe_offered=true
@ -6892,10 +6988,9 @@ run_pfs() {
outln "${sigalg[i]}" outln "${sigalg[i]}"
fi fi
done done
! "$WIDE" && out_row_aligned_max_width "$pfs_ciphers" " " $TERM_WIDTH out
debugme echo $pfs_offered debugme echo $pfs_offered
"$WIDE" || outln "$WIDE" || outln
fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers"
fi fi
@ -6942,9 +7037,6 @@ run_pfs() {
done done
[[ $i -eq $high ]] && break [[ $i -eq $high ]] && break
supported_curve[i]=true supported_curve[i]=true
bits[i]=$(awk -F',' '{ print $3 }' <<< $temp)
grep -q bits <<< ${bits[i]} || bits[i]=$(awk -F',' '{ print $2 }' <<< $temp)
bits[i]=$(tr -d ' bits' <<< ${bits[i]})
done done
done done
fi fi
@ -6968,9 +7060,6 @@ run_pfs() {
done done
[[ $i -eq $nr_curves ]] && break [[ $i -eq $nr_curves ]] && break
supported_curve[i]=true supported_curve[i]=true
bits[i]=$(awk -F',' '{ print $3 }' <<< $temp)
grep -q bits <<< ${bits[i]} || bits[i]=$(awk -F',' '{ print $2 }' <<< $temp)
bits[i]=$(tr -d ' bits' <<< ${bits[i]})
done done
fi fi
if "$ecdhe_offered"; then if "$ecdhe_offered"; then
@ -6980,9 +7069,8 @@ run_pfs() {
if [[ -n "$curves_offered" ]]; then if [[ -n "$curves_offered" ]]; then
"$WIDE" && outln "$WIDE" && outln
pr_bold " Elliptic curves offered: " pr_bold " Elliptic curves offered: "
for (( i=0; i < nr_curves; i++ )); do out_row_aligned_max_width "$curves_offered" " " $TERM_WIDTH pr_ecdh_curve_quality
"${supported_curve[i]}" && pr_ecdh_quality "${bits[i]}" "${curves_ossl[i]} " outln
done
fileout "ecdhe_curves" "INFO" "Elliptic curves offered $curves_offered" fileout "ecdhe_curves" "INFO" "Elliptic curves offered $curves_offered"
fi fi
fi fi
@ -10521,17 +10609,13 @@ run_beast(){
if ! "$WIDE"; then if ! "$WIDE"; then
if [[ -n "$detected_cbc_ciphers" ]]; then if [[ -n "$detected_cbc_ciphers" ]]; then
detected_cbc_ciphers=$(echo "$detected_cbc_ciphers" | \
sed -e "s/ /\\${cr} ${spaces}/12" \
-e "s/ /\\${cr} ${spaces}/9" \
-e "s/ /\\${cr} ${spaces}/6" \
-e "s/ /\\${cr} ${spaces}/3")
fileout "cbc_$proto" "MEDIUM" "BEAST: CBC ciphers for $(toupper $proto): $detected_cbc_ciphers" "$cve" "$cwe" "$hint" fileout "cbc_$proto" "MEDIUM" "BEAST: CBC ciphers for $(toupper $proto): $detected_cbc_ciphers" "$cve" "$cwe" "$hint"
! "$first" && out "$spaces" ! "$first" && out "$spaces"
out "$(toupper $proto):" out "$(toupper $proto):"
[[ -n "$higher_proto_supported" ]] && \ [[ -n "$higher_proto_supported" ]] && \
pr_svrty_lowln "$detected_cbc_ciphers" || \ out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH pr_svrty_low || \
pr_svrty_mediumln "$detected_cbc_ciphers" out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH pr_svrty_medium
outln
detected_cbc_ciphers="" # empty for next round detected_cbc_ciphers="" # empty for next round
first=false first=false
else else
@ -10857,11 +10941,10 @@ run_rc4() {
fi fi
fi fi
outln "${sigalg[i]}" outln "${sigalg[i]}"
elif "${ciphers_found[i]}"; then
pr_svrty_high "${ciph[i]} "
fi fi
"${ciphers_found[i]}" && rc4_detected+="${ciph[i]} " "${ciphers_found[i]}" && rc4_detected+="${ciph[i]} "
done done
! "$WIDE" && out_row_aligned_max_width "$rc4_detected" " " $TERM_WIDTH pr_svrty_high
outln outln
"$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)" "$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)"
fileout "rc4" "HIGH" "RC4: VULNERABLE, Detected ciphers: $rc4_detected" "$cve" "$cwe" "$hint" fileout "rc4" "HIGH" "RC4: VULNERABLE, Detected ciphers: $rc4_detected" "$cve" "$cwe" "$hint"
@ -11722,41 +11805,64 @@ get_aaaa_record() {
# RFC6844: DNS Certification Authority Authorization (CAA) Resource Record # RFC6844: DNS Certification Authority Authorization (CAA) Resource Record
# arg1: domain to check for # arg1: domain to check for
get_caa_rr_record() { get_caa_rr_record() {
local caa="" local raw_caa=""
local caa_flag
local -i len_caa_property
local caa_property_name
local caa_property_value
local saved_openssl_conf="$OPENSSL_CONF" local saved_openssl_conf="$OPENSSL_CONF"
# if there's a type257 record there are two output formats here, mostly depending on age of distribution
# rougly that's the difference between text and binary format
# 1) 'google.com has CAA record 0 issue "symantec.com"'
# 2) 'google.com has TYPE257 record \# 19 0005697373756573796D616E7465632E636F6D'
# for dig +short the output always starts with '0 issue [..]' or '\# 19 [..]' so we normalize thereto to keep caa_flag, caa_property
# caa_property then has key/value pairs, see https://tools.ietf.org/html/rfc6844#section-3
OPENSSL_CONF="" OPENSSL_CONF=""
if which dig &> /dev/null; then if which dig &> /dev/null; then
caa="$(dig $1 type257 +short | awk '{ print $3 }')" raw_caa="$(dig $1 type257 +short)"
# empty if no CAA record # empty if no CAA record
elif which host &> /dev/null; then elif which host &> /dev/null; then
caa="$(host -t type257 $1)" raw_caa="$(host -t type257 $1)"
if grep -wq issue <<< "$caa" && grep -wvq "has no CAA" <<< "$caa"; then if egrep -wvq "has no CAA|has no TYPE257" <<< "$raw_caa"; then
caa="$(awk '/issue/ { print $NF }' <<< "$caa")" raw_caa="$(sed -e 's/^.*has CAA record //' -e 's/^.*has TYPE257 record //' <<< "$raw_caa")"
fi fi
elif which nslookup &> /dev/null; then elif which nslookup &> /dev/null; then
caa="$(nslookup -type=type257 $1)" raw_caa="$(nslookup -type=type257 $1 | grep -w rdata_257)"
if grep -wq issue <<< "$caa" && grep -wvq "No answer" <<< "$caa"; then if [[ -n "$raw_caa" ]]; then
caa="$(awk '/issue/ { print $NF }' <<< "$caa")" raw_caa="$(sed 's/^.*rdata_257 = //' <<< "$raw_caa")"
fi fi
else else
return 1 return 1
# No dig, host, or nslookup --> complaint was elsewhere already and except for one which has drill only we don't get here # No dig, host, or nslookup --> complaint was elsewhere already and except for one which has drill only we don't get here
fi fi
OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134
debugme echo $raw_caa
# try to convert old return values # '# 19' for google.com is the tag length probably --> we use this also to identify the binary format
if [[ "$caa" =~ ^[A-F0-9]+$ ]]; then if [[ "$raw_caa" =~ \#\ [0-9][0-9]\ [A-F0-9]+$ ]]; then
caa=${caa:4:100} # ignore the first 4 bytes raw_caa=$(awk '{ print $NF }' <<< $raw_caa) # caa_length would be awk '{ print $(NF-1) }' but we don't need it
caa=$(hex2ascii "$caa" | sed 's/^issue//g') if [[ "${raw_caa:0:2}" == "00" ]]; then # probably the flag
caa_flag="0"
len_caa_property=${raw_caa:2:2} # implicit type casting, for google we have 05 here as a string
len_caa_property=$((len_caa_property*2)) # =>word! Now get name from 4th and value from 4th+len position...
caa_property_name=$(hex2ascii ${raw_caa:4:$len_caa_property})
caa_property_value=$(hex2ascii ${raw_caa:$((4+len_caa_property)):100})
else
outln "please report unknown CAA flag $caa_flag @ $NODE"
fi
elif grep -q '"' <<< $raw_caa; then
raw_caa=${raw_caa//\"/} # strip " first. Now we should have flag, name, value
caa_flag=$(awk '{ print $1 }' <<< $raw_caa)
caa_property_name=$(awk '{ print $2 }' <<< $raw_caa)
caa_property_value=$(awk '{ print $3 }' <<< $raw_caa)
else else
caa=${caa//\"/} # strip " # no caa record
return 1
fi fi
echo "$caa" echo "$caa_property_name: $caa_property_value"
# to do: # to do:
# 1: check old binaries whether they support this record at all
# done (2: check whether hexstring is returned and deal with it)
# 3: check more than domainname, see https://tools.ietf.org/html/rfc6844#section-3
# 4: check whether $1 is a CNAME and take this # 4: check whether $1 is a CNAME and take this
# 5: query with drill # 5: query with drill
return 0 return 0