Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.6k views
in Technique[技术] by (71.8m points)

Actually securing an SSL connection with not-too-recent stunnel (or openssl(1))

(Note: SSL here is a generic name for the suites of SSL/TLS protocols.)

I’m wondering whether it is actually possible to use stunnel before version 5.15 to securely communicate. (Some side wonderings leave me to asking the same about the openssl(1) command-line utility in older versions.) Version 5.15 introduced an option checkHost which requires OpenSSL 1.0.2 or higher, for some reason.

Before version 5.15, a typical stunnel4 configuration file looked like this:

client = yes
connect = server.example.com:1234
service = example-stunnel
socket = r:SO_KEEPALIVE=1
socket = r:TCP_KEEPCNT=4
socket = r:TCP_KEEPIDLE=40
socket = r:TCP_KEEPINTVL=5
sslVersion = all
CApath = /etc/ssl/certs
verify = 2

(For stunnel 3.x there was a -v 2 command line option that did the same.)

Now I tested something: my server is reachable from a LAN both as intname.lan.example.com and as extname.example.com but its SSL certificate only has the latter (as it’s supposed to be used by the external name only except for management connections via SSH).

Typical web browsers will refuse the connection to intname.lan.example.com because it doesn’t match the names on the certifiate. cURL 7.21.0 does this even with OpenSSL 0.9.8o, for example (I’m using a Debian 6 “squeeze” chroot, as this comes with stunnel4 4.29, the oldest version otherwise suitable for my larger purpose). GNU wget does this with nonGNUtls as well. stunnel4, however, gives me this:

stunnel: LOG5[27785:4156769984]: stunnel 4.29 on i486-pc-linux-gnu with OpenSSL 0.9.8o 01 Jun 2010
stunnel: LOG5[27785:4156769984]: Threading:PTHREAD SSL:ENGINE Sockets:POLL,IPv6 Auth:LIBWRAP
stunnel: LOG5[27785:4156769984]: connect_blocking: connected 192.168.123.45:1234
stunnel: LOG5[27785:4156769984]: arngc-stunnel connected remote server from 172.16.67.89:38934
stunnel: LOG5[27785:4156769984]: CRL: verification passed
stunnel: LOG5[27785:4156769984]: VERIFY OK: depth=2, /O=Digital Signature Trust Co./CN=DST Root CA X3
stunnel: LOG5[27785:4156769984]: CRL: verification passed
stunnel: LOG5[27785:4156769984]: VERIFY OK: depth=1, /C=US/O=Let's Encrypt/CN=R3
stunnel: LOG5[27785:4156769984]: CRL: verification passed
stunnel: LOG5[27785:4156769984]: VERIFY OK: depth=0, /CN=extname.example.com

Now stunnel 5.56 (Debian unstable) does the same, except without even the debug messages by default! (openssl s_client -CApath /etc/ssl/certs -connect intname.lan.example.com:1234 behaves the same.)

Looking at the manpage, I’m supposed to use the following configuration now instead:

client = yes
connect = server.example.com:1234
service = example-stunnel
socket = r:SO_KEEPALIVE=1
socket = r:TCP_KEEPCNT=4
socket = r:TCP_KEEPIDLE=40
socket = r:TCP_KEEPINTVL=5
sslVersion = all
CApath = /etc/ssl/certs
checkHost = extname.example.com
verifyChain = yes

The verify was replaced with verifyChain (though the former will probably still work) and a checkHost was added, duplicating the hostname from connect. (The OpenSSL CLI is, again, similar: It also requires an additional -verify_hostname extname.example.com (which does not exist in 0.9.8, probably causing the above minimum version requirement) to validate the hostname. It’s worse though because it yields Verify return code: 62 (Hostname mismatch) but still proceeds with the connection (unless adding -verify_return_error as well, which is in a totally different manpage!), whereas stunnel4 5.x at least aborts.)

Colour me surprised that

  • low-level SSL utilities don’t have the same safety a webbrowser (or even my MUA, pine, from 2005!) implicitly has
  • one can only get hostname validation in very recent versions
  • even then one has to add an extra option to validate the hostname against an arbitrary string, instead of it just using the connection peer’s hostname like a webbrowser or MUA does

This basically means that there’s no “bare SSL” CLI utility at all suitable for secure communication before 2015 (OpenSSL 1.0.2 and stunnel4 5.15 were both released about then)?

Checking Debian 8 “jessie” (still in extended LTS support!), released January 2015 (so wouldn’t include things that came out only in 2015), this seems to indeed be true! It’s got OpenSSL 1.0.1t and stunnel4 5.06 (a backport of 5.30 is available, but the checkHost option just fails with this OpenSSL version (at least that; silently proceeding would be worse): [!] /tmp/c:10: "checkHost = intname.lan.example.com": Specified option name is not valid here… for some reason it also doesn’t accept verifyChain then.).

There’s gnutls-cli in jessie (gnutls-bin 3.3.30), which seems to DTRT: gnutls-cli -p 1234 intname.lan.example.com yields - Status: The certificate is NOT trusted. The name in the certificate does not match the expected. and aborts. But virtually nobody uses that suite of tools…

This basically means that anything before Debian 9 “stretch”, released mid-2017, using standard tools for SSL connections, is vulnerable to MITM attacks?—?present a valid, CA-signed, certificate for any hostname and you’re good.

Am I just not seeing something? What makes SSL CLI tools “special” (in the negative sense) compared with HTTP CLI clients (or full-blown webbrowsers) or my decade-older MUA? Is there a magic toggle I can use to enable “normal” server validation? Having to divine a hostname the server’s certificate must validate against is not considered “normal”, and it’ll most likely break with wildcard certificates anyway…


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...