From 18da1b8df5069ada5dede40a4e90f9b0f7d38d81 Mon Sep 17 00:00:00 2001 From: Dirk Wetter <dirk@testssl.sh> Date: Tue, 25 Mar 2025 19:13:30 +0100 Subject: [PATCH 1/6] Fix some IPv6 proxy issues As a quick hack this PR enables *basically* the IPv6 proxy which results that testssl.sh will use an IPv6 proxy when * the binary supports that * the binary is used an not tls_sockets() * there's no A record but an AAAA record of the proxy or an IPv6 address as proxy address was specified. The latter should guarantee that it doesn't break anything. However tls_sockets() still uses IPv4 for the connection to the proxy. See #1105 --- testssl.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6c61a38..0ca9a5b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21962,17 +21962,23 @@ check_proxy() { # strip off http/https part if supplied: PROXY="${PROXY/http\:\/\//}" PROXY="${PROXY/https\:\/\//}" # this shouldn't be needed + PROXYPORT="${PROXY##*:}" PROXYNODE="${PROXY%:*}" - PROXYPORT="${PROXY#*:}" is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" $ERR_CMDLINE - #if is_ipv4addr "$PROXYNODE" || is_ipv6addr "$PROXYNODE" ; then - # IPv6 via openssl -proxy: that doesn't work. Sockets does -#FIXME: finish this with LibreSSL which supports an IPv6 proxy + #FIXME: finish this with IPv6 proxy support, see #1105. if is_ipv4addr "$PROXYNODE"; then PROXYIP="$PROXYNODE" + elif is_ipv6addr "$PROXYNODE"; then + # Maybe an option like --proxy6 is better for purists + PROXYIP="[$PROXYNODE]" else + # We check now preferred whether there was an IPv4 proxy via DNS specified + # If it fails it could be an IPv6 only proxy via DNS or we just can't reach the proxy PROXYIP="$(get_a_record "$PROXYNODE" 2>/dev/null | grep -v alias | sed 's/^.*address //')" + if [[ -z "$PROXYIP" ]]; then + PROXYIP="$(get_aaaa_record "$PROXYNODE" 2>/dev/null | grep -v alias | sed 's/^.*address //')" + fi [[ -z "$PROXYIP" ]] && fatal "Proxy IP cannot be determined from \"$PROXYNODE\"" $ERR_CMDLINE fi PROXY="-proxy $PROXYIP:$PROXYPORT" From e81b09176dcd2164f858bbce7d3bed922d7edc3f Mon Sep 17 00:00:00 2001 From: Dirk Wetter <dirk@testssl.sh> Date: Tue, 25 Mar 2025 19:42:54 +0100 Subject: [PATCH 2/6] Distunguish between LibreSSL and OpenSSL IPv6 proxy Somehow the proxy now shows only IPv6 source addresses when specifying --proxy=IPV6ADDRESS:PORT --- testssl.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 0ca9a5b..7603a9a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21966,12 +21966,16 @@ check_proxy() { PROXYNODE="${PROXY%:*}" is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" $ERR_CMDLINE - #FIXME: finish this with IPv6 proxy support, see #1105. + #FIXME: finish IPv6 proxy support, see #1105. if is_ipv4addr "$PROXYNODE"; then PROXYIP="$PROXYNODE" elif is_ipv6addr "$PROXYNODE"; then # Maybe an option like --proxy6 is better for purists - PROXYIP="[$PROXYNODE]" + if [[ "$OSSL_NAME" =~ LibreSSL ]]; then + PROXYIP="$PROXYNODE" + else + PROXYIP="[$PROXYNODE]" + fi else # We check now preferred whether there was an IPv4 proxy via DNS specified # If it fails it could be an IPv6 only proxy via DNS or we just can't reach the proxy From 36a58e2b3edb46b7c14f87e613addf42a179e9d5 Mon Sep 17 00:00:00 2001 From: Dirk Wetter <dirk@testssl.sh> Date: Thu, 27 Mar 2025 18:26:17 +0100 Subject: [PATCH 3/6] Allow square bracket notation for IPv6 proxy --- testssl.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 7603a9a..9889ff8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21959,11 +21959,14 @@ check_proxy() { [[ -z "$PROXY" ]] && PROXY="${http_proxy#*\/\/}" [[ -z "$PROXY" ]] && fatal "you specified \"--proxy=auto\" but \"\$http(s)_proxy\" is empty" $ERR_CMDLINE fi - # strip off http/https part if supplied: + # strip http/https part if supplied: PROXY="${PROXY/http\:\/\//}" PROXY="${PROXY/https\:\/\//}" # this shouldn't be needed PROXYPORT="${PROXY##*:}" PROXYNODE="${PROXY%:*}" + # strip square brackets in IPv6 notation, but we may enter them later + PROXYNODE="${PROXYNODE/\[/}" + PROXYNODE="${PROXYNODE/\]/}" is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" $ERR_CMDLINE #FIXME: finish IPv6 proxy support, see #1105. From 87edb78b3e787fccd4dc15ee01b6f7f1105d7f53 Mon Sep 17 00:00:00 2001 From: Dirk Wetter <dirk@testssl.sh> Date: Thu, 27 Mar 2025 18:27:00 +0100 Subject: [PATCH 4/6] Add docu for IPv6 proxy --- doc/testssl.1 | 2 +- doc/testssl.1.html | 2 +- doc/testssl.1.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index 810d54a..55bb900 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -90,7 +90,7 @@ A typical internal conversion to testssl\.sh file format from nmap's grep(p)able .P \fB\-\-ip <ip>\fR tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in \fB<URI>\fR\. IPv6 addresses need to be supplied in square brackets\. \fB\-\-ip=one\fR means: just test the first A record DNS returns (useful for multiple IPs)\. If \fB\-6\fR and \fB\-\-ip=one\fR was supplied an AAAA record will be picked if available\. The \fB\-\-ip\fR option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit \fB/etc/hosts\fR or \fB/c/Windows/System32/drivers/etc/hosts\fR\. \fB\-\-ip=proxy\fR tries a DNS resolution via proxy\. \fB\-\-ip=proxy\fR plus \fB\-\-nodns=min\fR is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records\. .P -\fB\-\-proxy <host>:<port>\fR does ANY check via the specified proxy\. \fB\-\-proxy=auto\fR inherits the proxy setting from the environment\. The hostname supplied will be resolved to the first A record\. In addition if you want lookups via proxy you can specify \fBDNS_VIA_PROXY=true\fR\. OCSP revocation checking (\fB\-S \-\-phone\-out\fR) is not supported by OpenSSL via proxy\. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed\. However if \fBIGN_OCSP_PROXY=true\fR has been supplied it will be tried directly\. Authentication to the proxy is not supported\. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported\. +\fB\-\-proxy <host>:<port>\fR does ANY check via the specified proxy\. \fB\-\-proxy=auto\fR inherits the proxy setting from the environment\. Any hostname supplied will be resolved to the first A record, if it does not exist the AAAA record is used\. IPv4 and IPv6 addresses can be passed too, the latter \fIalso\fR with square bracket notation\. Please note that you need a newer OpenSSL or LibreSSL version for IPv6 proxy functionality\. In addition if you want lookups via proxy you can specify \fBDNS_VIA_PROXY=true\fR\. OCSP revocation checking (\fB\-S \-\-phone\-out\fR) is not supported by OpenSSL via proxy\. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed\. However if \fBIGN_OCSP_PROXY=true\fR has been supplied it will be tried directly\. Authentication to the proxy is not supported\. Proxying via IPv6 addresses is not supported, also no HTTPS or SOCKS proxy\. .P \fB\-6\fR does (also) IPv6 checks\. Please note that testssl\.sh doesn't perform checks on an IPv6 address automatically, because of two reasons: testssl\.sh does no connectivity checks for IPv6 and it cannot determine reliably whether the OpenSSL binary you're using has IPv6 s_client support\. \fB\-6\fR assumes both is the case\. If both conditions are met and you in general prefer to test for IPv6 branches as well you can add \fBHAS_IPv6\fR to your shell environment\. Besides the OpenSSL binary supplied IPv6 is known to work with vanilla OpenSSL >= 1\.1\.0 and older versions >=1\.0\.2 in RHEL/CentOS/FC and Gentoo\. .P diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 0336c4b..b323e8d 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -204,7 +204,7 @@ The same can be achieved by setting the environment variable <code>WARNINGS</cod <p><code>--ip <ip></code> tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in <code><URI></code>. IPv6 addresses need to be supplied in square brackets. <code>--ip=one</code> means: just test the first A record DNS returns (useful for multiple IPs). If <code>-6</code> and <code>--ip=one</code> was supplied an AAAA record will be picked if available. The <code>--ip</code> option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit <code>/etc/hosts</code> or <code>/c/Windows/System32/drivers/etc/hosts</code>. <code>--ip=proxy</code> tries a DNS resolution via proxy. <code>--ip=proxy</code> tries a DNS resolution via proxy. </code>--ip=proxy</code> plus <code>--nodns=min</code> is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records.</p> -<p><code>--proxy <host>:<port></code> does ANY check via the specified proxy. <code>--proxy=auto</code> inherits the proxy setting from the environment. The hostname supplied will be resolved to the first A record. In addition if you want lookups via proxy you can specify <code>DNS_VIA_PROXY=true</code>. OCSP revocation checking (<code>-S --phone-out</code>) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if <code>IGN_OCSP_PROXY=true</code> has been supplied it will be tried directly. Authentication to the proxy is not supported. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported.</p> +<p><code>--proxy <host>:<port></code> does ANY check via the specified proxy. <code>--proxy=auto</code> inherits the proxy setting from the environment. Any hostname supplied will be resolved to the first A record, if it does not exist the AAAA record is used. IPv4 and IPv6 addresses can be passed too, the latter <em>also</em> with square bracket notation. Please note that you need a newer OpenSSL or LibreSSL version for IPv6 proxy functionality. In addition if you want lookups via proxy you can specify <code>DNS_VIA_PROXY=true</code>. OCSP revocation checking (<code>-S --phone-out</code>) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if <code>IGN_OCSP_PROXY=true</code> has been supplied it will be tried directly. Authentication to the proxy is not supported, also no HTTPS or SOCKS proxy.</p> <p><code>-6</code> does (also) IPv6 checks. Please note that testssl.sh doesn't perform checks on an IPv6 address automatically, because of two reasons: testssl.sh does no connectivity checks for IPv6 and it cannot determine reliably whether the OpenSSL binary you're using has IPv6 s_client support. <code>-6</code> assumes both is the case. If both conditions are met and you in general prefer to test for IPv6 branches as well you can add <code>HAS_IPv6</code> to your shell environment. Besides the OpenSSL binary supplied IPv6 is known to work with vanilla OpenSSL >= 1.1.0 and older versions >=1.0.2 in RHEL/CentOS/FC and Gentoo.</p> diff --git a/doc/testssl.1.md b/doc/testssl.1.md index edbc304..0f78672 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -126,7 +126,7 @@ The same can be achieved by setting the environment variable `WARNINGS`. `--ip <ip>` tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in `<URI>`. IPv6 addresses need to be supplied in square brackets. `--ip=one` means: just test the first A record DNS returns (useful for multiple IPs). If `-6` and `--ip=one` was supplied an AAAA record will be picked if available. The ``--ip`` option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit `/etc/hosts` or `/c/Windows/System32/drivers/etc/hosts`. `--ip=proxy` tries a DNS resolution via proxy. `--ip=proxy` plus `--nodns=min` is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records. -`--proxy <host>:<port>` does ANY check via the specified proxy. `--proxy=auto` inherits the proxy setting from the environment. The hostname supplied will be resolved to the first A record. In addition if you want lookups via proxy you can specify `DNS_VIA_PROXY=true`. OCSP revocation checking (`-S --phone-out`) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if `IGN_OCSP_PROXY=true` has been supplied it will be tried directly. Authentication to the proxy is not supported. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported. +`--proxy <host>:<port>` does ANY check via the specified proxy. `--proxy=auto` inherits the proxy setting from the environment. Any hostname supplied will be resolved to the first A record, if it does not exist the AAAA record is used. IPv4 and IPv6 addresses can be passed too, the latter *also* with square bracket notation. Please note that you need a newer OpenSSL or LibreSSL version for IPv6 proxy functionality. In addition if you want lookups via proxy you can specify `DNS_VIA_PROXY=true`. OCSP revocation checking (`-S --phone-out`) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if `IGN_OCSP_PROXY=true` has been supplied it will be tried directly. Authentication to the proxy is not supported, also no HTTPS or SOCKS proxy. `-6` does (also) IPv6 checks. Please note that testssl.sh doesn't perform checks on an IPv6 address automatically, because of two reasons: testssl.sh does no connectivity checks for IPv6 and it cannot determine reliably whether the OpenSSL binary you're using has IPv6 s_client support. `-6` assumes both is the case. If both conditions are met and you in general prefer to test for IPv6 branches as well you can add `HAS_IPv6` to your shell environment. Besides the OpenSSL binary supplied IPv6 is known to work with vanilla OpenSSL >= 1.1.0 and older versions >=1.0.2 in RHEL/CentOS/FC and Gentoo. From 44d9f520fb1cc87739479775865a238c77023cb8 Mon Sep 17 00:00:00 2001 From: Dirk Wetter <dirk@testssl.sh> Date: Tue, 1 Apr 2025 23:37:54 +0200 Subject: [PATCH 5/6] Add check for proxy IPv6 support ... of the binary. Testing needs to be done. --- testssl.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 9889ff8..bbc879b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21977,7 +21977,12 @@ check_proxy() { if [[ "$OSSL_NAME" =~ LibreSSL ]]; then PROXYIP="$PROXYNODE" else - PROXYIP="[$PROXYNODE]" + # This was tested with vanilla OpenSSL versions + if [[ ${OSSL_VER_MAJOR$}${OSSL_VER_MINOR} -ge 11 ]]; then + PROXYIP="[$PROXYNODE]" + else + fatal_cmd_line "OpenSSL version >= 1.1.0 required for IPv6 proxy support" $ERR_OSSLBIN + fi fi else # We check now preferred whether there was an IPv4 proxy via DNS specified @@ -21985,6 +21990,11 @@ check_proxy() { PROXYIP="$(get_a_record "$PROXYNODE" 2>/dev/null | grep -v alias | sed 's/^.*address //')" if [[ -z "$PROXYIP" ]]; then PROXYIP="$(get_aaaa_record "$PROXYNODE" 2>/dev/null | grep -v alias | sed 's/^.*address //')" + if [[ -n "$PROXYIP" ]]; then + if [[ ${OSSL_VER_MAJOR$}${OSSL_VER_MINOR} -lt 11 ]]; then + fatal_cmd_line "OpenSSL version >= 1.1.0 required for IPv6 proxy support" $ERR_OSSLBIN + fi + fi fi [[ -z "$PROXYIP" ]] && fatal "Proxy IP cannot be determined from \"$PROXYNODE\"" $ERR_CMDLINE fi From ffe5dea84401027fbbe058017fc8ba76627d4815 Mon Sep 17 00:00:00 2001 From: Dirk <dirk@testssl.sh> Date: Tue, 22 Apr 2025 12:55:42 +0200 Subject: [PATCH 6/6] remove misleading command --- testssl.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index bbc879b..b1d86e7 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21969,7 +21969,6 @@ check_proxy() { PROXYNODE="${PROXYNODE/\]/}" is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" $ERR_CMDLINE - #FIXME: finish IPv6 proxy support, see #1105. if is_ipv4addr "$PROXYNODE"; then PROXYIP="$PROXYNODE" elif is_ipv6addr "$PROXYNODE"; then