Open HLFH opened 4 years ago
It already support IPv6:
$ docker run --rm aeris22/cryptcheck https 2001:bc8:1200:4:208:a2ff:fe0c:67ea
2001:bc8:1200:4:208:a2ff:fe0c:67ea:443
Supported methods
Method TLSv1_2
Supported ciphers
Cipher TLSv1_2 ECDHE-ECDSA-AES128-GCM-SHA256 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES256-GCM-SHA384 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-CHACHA20-POLY1305 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES128-SHA256 []
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES256-SHA384 []
PFS : ECC 256 bits
But you need to have working IPv6 stack on the host performing check and to activate IPv6 on docker daemon:
# cat /etc/docker/daemon.json
{
"ipv6": true,
"fixed-cidr-v6": "xxxx:xxxx:xxxx::/80"
}
Currently web frontend is not "IPv6 ready" because of confusion about :
, guessed as port separator, on naked IPv6. But fully dual-stacked hostname is checked for both IPv4 & IPv6, as on https://cryptcheck.fr/https/imirhil.fr
@aeris
As stated in the Docker documentation:
IPv6 networking is only supported on Docker daemons running on Linux hosts. Docker for Mac does not support IPv6 networking.
So I migrated Docker from Mac platform to ArchLinux and I followed your advice for /etc/docker/daemon.json
:
{
"ipv6": true,
"fixed-cidr-v6": "xxxx:xxxx:xxxx:xxxx::/56"
}
And it worked in CLI.
Regarding the web frontend, I would presume the confusion can be fixed with the fact that RFC 3986, section 3.2.2 clarifies that:
A host identified by an Internet Protocol literal address, version 6 [RFC3513] or later, is distinguished by enclosing the IP literal within square brackets ("[" and "]"). This is the only place where square bracket characters are allowed in the URI syntax. In anticipation of future, as-yet-undefined IP literal address formats, an implementation may use an optional version flag to indicate such a format explicitly rather than rely on heuristic determination.
The Cloudflare DNS service is accessible in IPv6 on:
If we use in CLI the https command
to check TLS certificates with IPv6 addresses, the HSTS check should not be done as RFC 6797 Appendix A excludes IP addresses:
HSTS Hosts are identified only via domain names -- explicit IP address identification of all forms is excluded.
If we use in CLI the https command to check TLS certificates with IPv6 addresses, the HSTS check should not be done as RFC 6797 Appendix A excludes IP addresses:
HSTS Hosts are identified only via domain names -- explicit IP address identification of all forms is excluded.
I assume https
command is used with a FQDN and not an IP, because of the trouble of vhost only testable with a valid FQDN (or you catch the default vhost which is neither reproducible nor guessable nor stable). And by design CryptCheck always validates both endpoint for dual-IP-stacked endpoint, testing naked IP is not very usefull, standard users don't use such address.
The only check where nake address seems acceptable is the tls
command (basically this is already HTTPS = TLS + HSTS).
But I will try to disable HSTS on naked IP address to be compliant with the RFC.
I presume the Docker build is using ruby 2.3.8
.
I want to check the TLS certificate of Cloudflare at URI [2606:4700:4700::1111]:443
.
docker run --rm aeris22/cryptcheck tls 2606:4700:4700::1111 443
I am getting:
docker run --rm aeris22/cryptcheck tls 2606:4700:4700::1111 443
2606:4700:4700::1111:443
Supported methods
Method TLSv1_2
Method TLSv1_1
Method TLSv1
Supported ciphers
Cipher TLSv1_2 ECDHE-ECDSA-AES128-GCM-SHA256 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES256-GCM-SHA384 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-CHACHA20-POLY1305 [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-CHACHA20-POLY1305-D [aead]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES128-SHA256 []
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES256-SHA384 []
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES128-SHA [sha1]
PFS : ECC 256 bits
Cipher TLSv1_2 ECDHE-ECDSA-AES256-SHA [sha1]
PFS : ECC 256 bits
Cipher TLSv1_1 ECDHE-ECDSA-AES128-SHA [sha1]
PFS : ECC 256 bits
Cipher TLSv1_1 ECDHE-ECDSA-AES256-SHA [sha1]
PFS : ECC 256 bits
Cipher TLSv1 ECDHE-ECDSA-AES128-SHA [sha1]
PFS : ECC 256 bits
Cipher TLSv1 ECDHE-ECDSA-AES256-SHA [sha1]
PFS : ECC 256 bits
Cipher suite preferences
TLSv1_2 : ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-ECDSA-CHACHA20-POLY1305-D, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384
TLSv1_1 : ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES256-SHA
TLSv1 : ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES256-SHA
Supported elliptic curves
ECC curve secp256k1
ECC curve prime256v1
Curves preference : prime256v1, secp256k1
Fallback SCSV : not supported
Certificates
Certificate /C=US/ST=California/L=San Francisco/O=Cloudflare, Inc./CN=cloudflare-dns.com [2393062632280249844899714234728687389] issued by /C=US/O=DigiCert Inc/CN=DigiCert ECC Secure Server CA
Key : ECC prime256v1 256 bits
Identity : invalid
Trust : trusted
Grade : V
{
:critical => {
:mdc2_sign => false,
:md2_sign => false,
:md4_sign => false,
:md5_sign => false,
:sha_sign => false,
:sha1_sign => false,
:ecc => false,
:sslv2 => false,
:sslv3 => false,
:dss => false,
:anonymous => false,
:null => false,
:export => false,
:des => false,
:md5 => false,
:rc4 => false,
:sweet32 => false
},
:error => {
:ecc => false,
:tlsv1_0 => true,
:tlsv1_1 => true,
:pfs => false
},
:warning => {
:ecc => false,
:sha1 => true,
:dhe => false
},
:good => {
:fallback_scsv => false,
:aead => true
},
:great => {},
:best => {}
}
I wonder why the Identity is invalid.
I presume the file cert.rb
is being called on this very specific function:
::OpenSSL::SSL.verify_certificate_identity @cert, host
Does that mean with the current Docker build, it is returning false to show in the CLI the Identity is invalid?
When I am using ruby 2.7.1
to try this function on the same host:
openssl s_client -showcerts -connect [2606:4700:4700::1111]:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >cert.pem
I am getting:
-----BEGIN CERTIFICATE-----
MIIFxjCCBUygAwIBAgIQAczjGN6fVn+rKySQH62nHTAKBggqhkjOPQQDAjBMMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSYwJAYDVQQDEx1EaWdp
Q2VydCBFQ0MgU2VjdXJlIFNlcnZlciBDQTAeFw0xOTAxMjgwMDAwMDBaFw0yMTAy
MDExMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYw
FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZGZsYXJlLCBJbmMu
MRswGQYDVQQDExJjbG91ZGZsYXJlLWRucy5jb20wWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAATFIHCMIEJQKB59REF8MHkpHGNeHUSbxfdxOive0qKksWw9ash3uMuP
LlBT/fQYJn9hN+3/wr7pC125fuHfHOJ0o4ID6DCCA+QwHwYDVR0jBBgwFoAUo53m
H/naOU/AbuiRy5Wl2jHiCp8wHQYDVR0OBBYEFHCV3FyjjmYH28uBEMar58OoRX+g
MIGsBgNVHREEgaQwgaGCEmNsb3VkZmxhcmUtZG5zLmNvbYIUKi5jbG91ZGZsYXJl
LWRucy5jb22CD29uZS5vbmUub25lLm9uZYcEAQEBAYcEAQAAAYcEop+ENYcQJgZH
AEcAAAAAAAAAAAAREYcQJgZHAEcAAAAAAAAAAAAQAYcQJgZHAEcAAAAAAAAAAAAA
ZIcQJgZHAEcAAAAAAAAAAABkAIcEop8kAYcEop8uATAOBgNVHQ8BAf8EBAMCB4Aw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGkGA1UdHwRiMGAwLqAsoCqG
KGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zc2NhLWVjYy1nMS5jcmwwLqAsoCqG
KGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLWVjYy1nMS5jcmwwTAYDVR0g
BEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGln
aWNlcnQuY29tL0NQUzAIBgZngQwBAgIwewYIKwYBBQUHAQEEbzBtMCQGCCsGAQUF
BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRQYIKwYBBQUHMAKGOWh0dHA6
Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEVDQ1NlY3VyZVNlcnZlckNB
LmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCk
uQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWiVHhSLAAAEAwBHMEUC
IQDlnoPeMXtFkRsy3Vs0eovk3ILKt01x6bgUdMlmQTFIvAIgcAn0lFSjiGzHm2eO
jDZJzMiP5Uaj0Jwub9GO8RkxkkoAdQCHdb/nWXz4jEOZX73zbv9WjUdWNv9KtWDB
tOr/XqCDDwAAAWiVHhVsAAAEAwBGMEQCIFC0n0JModeol8b/Qicxd5Blf/o7xOs/
Bk0j9hdc5N7jAiAQocYnHL9iMqTtFkh0vmSsII5NbiakM/2yDEXnwkPRvAB3ALvZ
37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABaJUeFJEAAAQDAEgwRgIh
AL3OPTBzOZpS5rS/uLzqMOiACCFQyY+mTJ+L0I9TcB3RAiEA4+SiPz0/5kFxvrk7
AKYKdvelgV1hiiPbM2YHY+/0BIkwCgYIKoZIzj0EAwIDaAAwZQIwez76hX2HTMur
/I3XRuwfdmVoa8J6ZVEVq+AZsE7DyQh7AV4WNLU+092BrPbnyVUFAjEAzUf5jdz1
pyc74lgOunC7LBE6cPtWbzfGpJiYyT/T+c5eIAwRYziKT0DKbaql7tiZ
-----END CERTIFICATE-----
irb
require 'openssl'
raw = File.read "cert.pem"
cert = OpenSSL::X509::Certificate.new raw
::OpenSSL::SSL.verify_certificate_identity cert, '2606:4700:4700::1111'
=> true #and not false
For this latter test, the openssl
version is OpenSSL 1.1.1f
.
For the related 1.1.1.1 URI with the aeris22/cryptcheck
Docker build, I am getting the Identity as "valid", so it seems there is a bug here when we do the check for the IPv6 addresses.
There is a bug in Ruby OpenSSL v2.1.2 binding. Comparison is done with string without any normalization before comparison.
2606:4700:4700::1111
is so basically compared to 2606:4700:4700:0:0:0:0:1111
which is false…
It was corrected on master but not released at the moment.
I quote you:
I'm currently working on a huge rework to try supporting TLSv1.3 with a dual stacked Ruby (2.3 & 2.6).
Yusuke Endoh from the ruby
team has just said:
Ruby 2.7 bundles an unreleased version 2.2.0 of openssl that includes the PR. The version management of gems bundled with Ruby by default are not well-organised.
Happily, your huge rework (unless it is cryptcheck-engine
project without the openssl
dep?),
with Ruby 2.6
included will solve this bug as Ruby bundles the unreleased version 2.2.0 of openssl
from ruby 2.6.0 preview 3
onwards.
It's not related to the full rewrite of openssl dep :joy: I just try to be able to run checking code on 2.6, to be able to access TLSv1.3 too.
As
acme-ip
is not yet implemented intoboulder
, I generate TLS certificates for IP addresses withminica
that facilitates issuance of self-signed certificates.So I do:
And I get:
Do you plan to support the TLS certificates with IPv6 addresses check in the future? I see it works for IPv4 addresses like
1.1.1.1
: https://cryptcheck.fr/https/1.1.1.1Thanks, HLFH