diff --git a/ChangeLog b/ChangeLog index 7993c0c..c529479 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-11-30 Matteo Corti + + * check_ssl_cert: Added QUIC support + 2023-11-21 Matteo Corti * check_ssl_cert (main): Support for LibreSSL and IP addresses diff --git a/NEWS.md b/NEWS.md index dc4ed53..bcc8ba3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # News + * QUIC support * OpenSSL 3.2.0 Support * 2023-11-23 Version 2.77.0 * Added support for MQTTS diff --git a/README.md b/README.md index a9134ec..96fcb3a 100644 --- a/README.md +++ b/README.md @@ -200,10 +200,10 @@ Options: integers, 2 otherwise -P,--protocol protocol Use the specific protocol: dns, ftp, ftps, http, https (default), - h2 (HTTP/2), imap, imaps, irc, ircs, ldap, - ldaps, mqtts, mysql, pop3, pop3s, - postgres, sieve, smtp, smtps, tds, xmpp, - xmpp-server. + h2 (HTTP/2), h3 (HTTP/3), imap, imaps, + irc, ircs, ldap, ldaps, mqtts, mysql, + pop3, pop3s, postgres, sieve, smtp, smtps, + tds, xmpp, xmpp-server. ftp, imap, irc, ldap, pop3, postgres, sieve, smtp: switch to TLS using StartTLS --password source Password source for a local certificate, @@ -213,6 +213,7 @@ Options: --proxy proxy Set http_proxy and the s_client -proxy option --python-bin path Path of the python binary to be used + --quic Use QUIC -q,--quiet Do not produce any output -r,--rootcert path Root certificate or directory to be used for certificate validation diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index dfcc495..c9d522d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1 +1,2 @@ -OpenSSL 3.2.0 Support +* QUIC support +* OpenSSL 3.2.0 support diff --git a/check_ssl_cert b/check_ssl_cert index 970d02f..9f0160a 100755 --- a/check_ssl_cert +++ b/check_ssl_cert @@ -178,7 +178,7 @@ fetch_http_headers() { # -L (--location): follow redirects # -k (--insecure): ignore TLS problems (we want to check the headers anyway) # -o (--output): discard the output (we are only interested in the HTTP headers) - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_RESOLVE} ${CURL_PROXY_ARGUMENT} ${INETPROTO} -k -s -D- -A '${HTTP_USER_AGENT}' -o /dev/null -L https://${HOST}${path}" "${CACHED_HEADERS}" + exec_with_timeout "${CURL_BIN} ${CURL_QUIC} ${CURL_PROXY} ${CURL_RESOLVE} ${CURL_PROXY_ARGUMENT} ${INETPROTO} -k -s -D- -A '${HTTP_USER_AGENT}' -o /dev/null -L https://${HOST}${path}" "${CACHED_HEADERS}" RET=$? if [ "${RET}" -ne 0 ]; then @@ -463,10 +463,10 @@ usage() { echo " integers, 2 otherwise" echo " -P,--protocol protocol Use the specific protocol:" echo " dns, ftp, ftps, http, https (default)," - echo " h2 (HTTP/2), imap, imaps, irc, ircs, ldap," - echo " ldaps, mqtts, mysql, pop3, pop3s," - echo " postgres, sieve, smtp, smtps, tds, xmpp," - echo " xmpp-server." + echo " h2 (HTTP/2), h3 (HTTP/3), imap, imaps," + echo " irc, ircs, ldap, ldaps, mqtts, mysql," + echo " pop3, pop3s, postgres, sieve, smtp, smtps," + echo " tds, xmpp, xmpp-server." echo " ftp, imap, irc, ldap, pop3, postgres," echo " sieve, smtp: switch to TLS using StartTLS" echo " --password source Password source for a local certificate," @@ -477,6 +477,7 @@ usage() { echo " option" echo " --python-bin path Path of the python binary to be used" # Delimiter at 78 chars ############################################################ + echo " --quic Use QUIC" echo " -q,--quiet Do not produce any output" # Delimiter at 78 chars ############################################################ echo " -r,--rootcert path Root certificate or directory to be used" @@ -1904,9 +1905,9 @@ check_crl() { TIMEOUT_REASON="fetching CRL" if [ -n "${HTTP_USER_AGENT}" ]; then - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${CRL_URI}\\\" > ${CRL_TMP}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${CRL_URI}\\\" > ${CRL_TMP}" else - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --location \\\"${CRL_URI}\\\" > ${CRL_TMP}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --location \\\"${CRL_URI}\\\" > ${CRL_TMP}" fi unset TIMEOUT_REASON @@ -2033,9 +2034,9 @@ check_ocsp() { TIMEOUT_REASON="OCSP: fetching issuer ${ELEMENT_ISSUER_URI}" if [ -n "${HTTP_USER_AGENT}" ]; then - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${ELEMENT_ISSUER_URI}\\\" > ${ISSUER_CERT_TMP}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${ELEMENT_ISSUER_URI}\\\" > ${ISSUER_CERT_TMP}" else - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --location \\\"${ELEMENT_ISSUER_URI}\\\" > ${ISSUER_CERT_TMP}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --location \\\"${ELEMENT_ISSUER_URI}\\\" > ${ISSUER_CERT_TMP}" fi unset TIMEOUT_REASON @@ -2590,7 +2591,11 @@ fetch_certificate() { fi # Check if a protocol was specified (if not HTTP switch to TLS) - if [ -n "${PROTOCOL}" ] && [ "${PROTOCOL}" != 'http' ] && [ "${PROTOCOL}" != 'https' ] && [ "${PROTOCOL}" != 'h2' ]; then + if [ -n "${PROTOCOL}" ] && + [ "${PROTOCOL}" != 'http' ] && + [ "${PROTOCOL}" != 'https' ] && + [ "${PROTOCOL}" != 'h2' ] && + [ "${PROTOCOL}" != 'h3' ]; then case "${PROTOCOL}" in pop3 | ftp) @@ -2787,9 +2792,11 @@ fetch_certificate() { if [ "${PROTOCOL}" = 'h2' ]; then ALPN="-alpn h2" + elif [ "${PROTOCOL}" = 'h3' ]; then + ALPN="-alpn h3" fi - exec_with_timeout "printf '${HTTP_REQUEST}' | ${OPENSSL} s_client ${SECURITY_LEVEL} ${INETPROTO} ${CLIENT} ${CLIENTPASS} -crlf ${ALPN} -connect ${HOST_ADDR}:${PORT} ${SERVERNAME} ${SCLIENT_PROXY} ${SCLIENT_PROXY_ARGUMENT} -showcerts -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} ${STATUS} ${DANE} ${RENEGOTIATION} 2> ${ERROR} 1> ${CERT}" + exec_with_timeout "printf '${HTTP_REQUEST}' | ${OPENSSL} s_client ${QUIC} ${SECURITY_LEVEL} ${INETPROTO} ${CLIENT} ${CLIENTPASS} -crlf ${ALPN} -connect ${HOST_ADDR}:${PORT} ${SERVERNAME} ${SCLIENT_PROXY} ${SCLIENT_PROXY_ARGUMENT} -showcerts -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} ${STATUS} ${DANE} ${RENEGOTIATION} 2> ${ERROR} 1> ${CERT}" RET=$? fi @@ -2877,6 +2884,10 @@ fetch_certificate() { prepend_critical_message 'Self signed certificate' fi + elif ascii_grep 'quic_do_handshake' "${ERROR}"; then + + prepend_critical_message 'QUIC not supported' + elif ascii_grep 'dh[ ]key[ ]too[ ]small' "${ERROR}"; then prepend_critical_message 'DH with a key too small' @@ -3008,6 +3019,10 @@ fetch_certificate() { if ! "${GREP_BIN}" -q -F 'ALPN protocol: h2' "${CERT}"; then prepend_critical_message 'The server does not support HTTP/2' fi + elif [ "${PROTOCOL}" = 'h3' ]; then + if ! "${GREP_BIN}" -q -F 'ALPN protocol: h3' "${CERT}"; then + prepend_critical_message 'The server does not support HTTP/3' + fi fi fi @@ -3325,6 +3340,10 @@ parse_command_line_options() { PROMETHEUS=1 shift ;; + --quic) + QUIC='-quic' + shift + ;; -q | --quiet) QUIET=1 shift @@ -4221,7 +4240,7 @@ main() { http) PORT=80 ;; - https | h2) + https | h2 | h3) PORT=443 ;; mqtts) @@ -4378,6 +4397,26 @@ main() { check_required_prog "${OPENSSL}" OPENSSL=${PROG} + if [ -n "${QUIC}" ] ; then + + require_s_client_option '-quic' + + # QUIC requires HTTP/2 + if [ -n "${PROTOCOL}" ] && [ "${PROTOCOL}" != 'h3' ]; then + critical 'QUIC only works with HTTP/2' + else + verboselog '--quic specified enabling HTTP/3' + PROTOCOL='h3' + fi + + # check if curl supports HTTP/3 + if curl --help all | grep -q -- --http3 ; then + debuglog 'curl supports HTTP/3' + CURL_QUIC='--http3' + fi + + fi + ############################################################################## # custom grep if [ -z "${GREP_BIN}" ]; then @@ -4618,7 +4657,7 @@ main() { DNS_OVER_HTTP=${TEMPFILE} TIMEOUT_REASON="Resolving over HTTP with ${RESOLVE_OVER_HTTP}" - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' -H 'Content-Type: application/dns-json' https://${RESOLVE_OVER_HTTP}/resolve?name=${HOST}\\&type=A" "${DNS_OVER_HTTP}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' -H 'Content-Type: application/dns-json' https://${RESOLVE_OVER_HTTP}/resolve?name=${HOST}\\&type=A" "${DNS_OVER_HTTP}" if [ "${DEBUG}" -ge 1 ]; then jq < "${DNS_OVER_HTTP}" | sed 's/^/[DBG] /' 1>&2 @@ -4888,9 +4927,9 @@ main() { TIMEOUT_REASON="fetching certificate file" if [ -n "${HTTP_USER_AGENT}" ]; then - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${FILE_URI}\\\" > ${FILE}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --user-agent '${HTTP_USER_AGENT}' --location \\\"${FILE_URI}\\\" > ${FILE}" else - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent --location \\\"${FILE_URI}\\\" > ${FILE}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent --location \\\"${FILE_URI}\\\" > ${FILE}" fi unset TIMEOUT_REASON @@ -5366,7 +5405,7 @@ main() { # Check if curl is needed and if it supports the -4 and -6 options if [ -z "${CURL_BIN}" ]; then if [ -n "${SSL_LAB_CRIT_ASSESSMENT}" ] || [ -n "${OCSP}" ]; then - if ! "${CURL_BIN}" --manual | "${GREP_BIN}" -F -q -- -6 && [ -n "${INETPROTO}" ]; then + if ! "${CURL_BIN}" --help all | "${GREP_BIN}" -F -q -- -6 && [ -n "${INETPROTO}" ]; then unknown "curl does not support the ${INETPROTO} option" fi fi @@ -6640,13 +6679,13 @@ ${WARNING}" debuglog "http_proxy = ${http_proxy}" debuglog "HTTPS_PROXY = ${HTTPS_PROXY}" - debuglog "executing ${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent \"https://api.ssllabs.com/api/v2/analyze?host=${HOST_NAME}${IGNORE_SSL_LABS_CACHE}\"" + debuglog "executing ${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent \"https://api.ssllabs.com/api/v2/analyze?host=${HOST_NAME}${IGNORE_SSL_LABS_CACHE}\"" if [ -n "${SNI}" ]; then - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent \\\"https://api.ssllabs.com/api/v2/analyze?host=${SNI}${IGNORE_SSL_LABS_CACHE}\\\" > ${JSON}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent \\\"https://api.ssllabs.com/api/v2/analyze?host=${SNI}${IGNORE_SSL_LABS_CACHE}\\\" > ${JSON}" CURL_RETURN_CODE=$? else - exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${INETPROTO} --silent \\\"https://api.ssllabs.com/api/v2/analyze?host=${HOST_NAME}${IGNORE_SSL_LABS_CACHE}\\\" > ${JSON}" + exec_with_timeout "${CURL_BIN} ${CURL_PROXY} ${CURL_PROXY_ARGUMENT} ${CURL_QUIC} ${INETPROTO} --silent \\\"https://api.ssllabs.com/api/v2/analyze?host=${HOST_NAME}${IGNORE_SSL_LABS_CACHE}\\\" > ${JSON}" CURL_RETURN_CODE=$? fi diff --git a/check_ssl_cert.1 b/check_ssl_cert.1 index 5b93c9c..4cbf344 100644 --- a/check_ssl_cert.1 +++ b/check_ssl_cert.1 @@ -330,7 +330,7 @@ TCP port (default 443) Number of decimal places for durations: defaults to 0 if critical or warning are integers, 2 otherwise .TP .BR "-P,--protocol" " protocol" -Use the specific protocol: dns, ftp, ftps, http, https (default), h2 (HTTP/2), imap, imaps, irc, ircs, ldap, ldaps, mqtts, mysql, pop3, pop3s, postgres, sieve, smtp, smtps, tds, xmpp, xmpp-server, ftp, imap, irc, ldap, pop3, postgres, sieve, smtp: switch to TLS using StartTLS. +Use the specific protocol: dns, ftp, ftps, http, https (default), h2 (HTTP/2), h3 (HTTP/3), imap, imaps, irc, ircs, ldap, ldaps, mqtts, mysql, pop3, pop3s, postgres, sieve, smtp, smtps, tds, xmpp, xmpp-server, ftp, imap, irc, ldap, pop3, postgres, sieve, smtp: switch to TLS using StartTLS. .BR These protocols switch to TLS using StartTLS: ftp, imap, irc, ldap, mysql, pop3, smtp. .TP @@ -349,6 +349,9 @@ Set http_proxy and the s_client -proxy option .BR " --python-bin" " path" Path of the python binary to be used .TP +.BR " --quic" +Use QUIC +.TP .BR "-q,--quiet" Do not produce any output .TP diff --git a/check_ssl_cert.completion b/check_ssl_cert.completion index dd729f1..e120ab0 100644 --- a/check_ssl_cert.completion +++ b/check_ssl_cert.completion @@ -14,7 +14,7 @@ _check_ssl_cert() { # only the autocompletion with long options is implemented: long options are more readable and quick to enter since we are # using autocompletion. # - opts="--file --host --noauth --all --all-local --allow-empty-san --clientcert --configuration --critical --check-chain --check-ciphers --check-ciphers-warnings --check-http-headers --check-ssl-labs --check-ssl-labs-warn --clientpass --crl --curl-bin --user-agent --custom-http-header --dane --date --debug-cert --debug-file --debug-headers --debug-time --default-format --dig-bin --do-not-resolve --dtls --dtls1 --dtls1_2 --ecdsa --element --file-bin --fingerprint --first-element-only --force-dconv-date --force-perl-date --format --grep-bin --http-headers-path --http-use-get --ignore-altnames --jks-alias --ignore-connection-problems --ignore-exp --ignore-http-headers --ignore-host-cn --ignore-incomplete-chain --ignore-maximum-validity --ignore-ocsp --ignore-ocsp-errors --ignore-ocsp-timeout --ignore-sct --ignore-sig-alg --ignore-ssl-labs-cache --ignore-tls-renegotiation --inetproto protocol --info --init-host-cache --issuer-cert-cache --long-output --match --maximum-validity --nmap-bin --no-perf --no-proxy --no-proxy-curl --no-proxy-s_client --no-ssl2 --no-ssl3 --no-tls1 --no-tls1_1 --no-tls1_2 --no-tls1_3 --not-issued-by --not-valid-longer-than --ocsp-critical --ocsp-warning --openssl --password --path --precision --prometheus --proxy --require-client-cert --require-dnssec --require-http-header --require-no-http-header --require-no-ssl2 --require-no-ssl3 --require-no-tls1 --require-no-tls1_1 --require-ocsp-stapling --require-purpose --require-purpose-critical --resolve --resolve-over-http --rootcert-dir --rootcert-file --rsa --serial --security-level --skip-element --sni --ssl2 --ssl3 --temp --terse --tls1 --tls1_1 --tls1_2 --tls1_3 --xmpphost -4 -6 --clientkey --protocol --version --debug --email --help --issuer --cn --org --port port --rootcert --quiet --selfsigned --timeout --url --verbose --warning --python-bin" + opts="--file --host --noauth --all --all-local --allow-empty-san --clientcert --configuration --critical --check-chain --check-ciphers --check-ciphers-warnings --check-http-headers --check-ssl-labs --check-ssl-labs-warn --clientpass --crl --curl-bin --user-agent --custom-http-header --dane --date --debug-cert --debug-file --debug-headers --debug-time --default-format --dig-bin --do-not-resolve --dtls --dtls1 --dtls1_2 --ecdsa --element --file-bin --fingerprint --first-element-only --force-dconv-date --force-perl-date --format --grep-bin --http-headers-path --http-use-get --ignore-altnames --jks-alias --ignore-connection-problems --ignore-exp --ignore-http-headers --ignore-host-cn --ignore-incomplete-chain --ignore-maximum-validity --ignore-ocsp --ignore-ocsp-errors --ignore-ocsp-timeout --ignore-sct --ignore-sig-alg --ignore-ssl-labs-cache --ignore-tls-renegotiation --inetproto protocol --info --init-host-cache --issuer-cert-cache --long-output --match --maximum-validity --nmap-bin --no-perf --no-proxy --no-proxy-curl --no-proxy-s_client --no-ssl2 --no-ssl3 --no-tls1 --no-tls1_1 --no-tls1_2 --no-tls1_3 --not-issued-by --not-valid-longer-than --ocsp-critical --ocsp-warning --openssl --password --path --precision --prometheus --proxy --require-client-cert --require-dnssec --require-http-header --require-no-http-header --require-no-ssl2 --require-no-ssl3 --require-no-tls1 --require-no-tls1_1 --require-ocsp-stapling --require-purpose --require-purpose-critical --resolve --resolve-over-http --rootcert-dir --rootcert-file --rsa --serial --security-level --skip-element --sni --ssl2 --ssl3 --temp --terse --tls1 --tls1_1 --tls1_2 --tls1_3 --xmpphost -4 -6 --clientkey --protocol --version --debug --email --help --issuer --cn --org --port port --rootcert --quic --quiet --selfsigned --timeout --url --verbose --warning --python-bin" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]]; then # shellcheck disable=2207 diff --git a/check_ssl_cert_icinga2.conf b/check_ssl_cert_icinga2.conf index 374034b..0c48da2 100644 --- a/check_ssl_cert_icinga2.conf +++ b/check_ssl_cert_icinga2.conf @@ -504,7 +504,12 @@ object CheckCommand "ssl_cert_extended" { description = "Path of the python binary to be used" } - "--quiet" = { + "--quic" = { + set_if = "$ssl_cert_extended_quic$" + description = "Use QUIC" + } + + "--quiet" = { set_if = "$ssl_cert_extended_quiet$" description = "Do not produce any output" } diff --git a/test/derlink.cer b/test/derlink.cer deleted file mode 120000 index 0b093ea..0000000 --- a/test/derlink.cer +++ /dev/null @@ -1 +0,0 @@ -der.cer \ No newline at end of file diff --git a/test/derlink.cer b/test/derlink.cer new file mode 100644 index 0000000..b4812cd Binary files /dev/null and b/test/derlink.cer differ diff --git a/test/integration_tests.sh b/test/integration_tests.sh index 4ed6cd6..c24d08b 100755 --- a/test/integration_tests.sh +++ b/test/integration_tests.sh @@ -1698,6 +1698,26 @@ testMQTTS() { assertEquals "wrong exit code" "${NAGIOS_OK}" "${EXIT_CODE}" } +testQUIC() { + + if [ -n "${http_proxy}" ] ; then + + echo "Skipping: no proxy support for QUIC" + + elif "${OPENSSL}" s_client -help 2>&1 | grep -q -- -quic ; then + + # shellcheck disable=SC2086 + ${SCRIPT} ${TEST_DEBUG} --host www.google.com --quic + EXIT_CODE=$? + assertEquals "wrong exit code" "${NAGIOS_OK}" "${EXIT_CODE}" + + else + + echo "Skipping: OpenSSL does not support QUIC" + + fi +} + testDNS() { # shellcheck disable=SC2086 diff --git a/utils/help.txt b/utils/help.txt index 9f4e3d1..0da79ed 100644 --- a/utils/help.txt +++ b/utils/help.txt @@ -190,6 +190,7 @@ --tls1_3;Force TLS version 1.3 --user-agent string;User agent that shall be used for HTTPS --user-agent string;connections +--quic;Use QUIC --xmpphost name;Specify the host for the 'to' attribute --xmpphost name;of the stream element -4;Force IPv4 @@ -204,10 +205,12 @@ -L,--check-ssl-labs grade;https://www.ssllabs.com/about/terms.html) -P,--protocol protocol;Use the specific protocol: -P,--protocol protocol;dns, ftp, ftps, http, https (default), --P,--protocol protocol;h2 (HTTP/2), imap, imaps, irc, ircs, ldap, --P,--protocol protocol;ldaps, mqtts, mysql, pop3, pop3s, --P,--protocol protocol;postgres, sieve, smtp, smtps, tds, xmpp, --P,--protocol protocol;xmpp-server. +-P,--protocol protocol;h2 (HTTP/2), h3 (HTTP/3), imap, imaps, +-P,--protocol protocol;irc, ircs, ldap, ldaps, mqtts, mysql, +-P,--protocol protocol;pop3, pop3s, postgres, sieve, smtp, smtps, +-P,--protocol protocol;tds, xmpp, xmpp-server. +-P,--protocol protocol;ftp, imap, irc, ldap, pop3, postgres, +-P,--protocol protocol;sieve, smtp: switch to TLS using StartTLS -V,--version;version -c,--critical days;Can be a floating point number, e.g., 0.5 -c,--critical days;Default: ${CRITICAL_DAYS}