OpenSSL for SNI-less connection testing

With all our problems in Uzbekistan let me remind you that OpenSSL is a fast and dirty way to check whether a SNI-less connection is available to a blocked resource. It’s fast.
It’s also dirty, because an openssl s_client/openssl s_server pair talks it’s own protocol, which is not known to the server being tested.
Servers reject all the SNI-less connections quite often, so probably you’ll have to probe an another resource to come to a definite conclusion.
I’d recommend adding a ‘-debug’ parameter to the command line mentioned in the SO answer.

What do you mean? s_client is a regular TLS connection, nothing more.

Example
$ (echo -ne "GET / HTTP/1.1\r\nHost: yandex.ru\r\n\r\n"; sleep 3) | openssl s_client -connect yandex.ru:443

CONNECTED(00000003)
depth=2 C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
verify return:1
depth=1 C = RU, O = Yandex LLC, OU = Yandex Certification Authority, CN = Yandex CA
verify return:1
depth=0 C = RU, L = Moscow, OU = ITO, O = Yandex LLC, CN = yandex.ru
verify return:1
---
Certificate chain
 0 s:C = RU, L = Moscow, OU = ITO, O = Yandex LLC, CN = yandex.ru
   i:C = RU, O = Yandex LLC, OU = Yandex Certification Authority, CN = Yandex CA
 1 s:C = RU, O = Yandex LLC, OU = Yandex Certification Authority, CN = Yandex CA
   i:C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
 2 s:C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
   i:C = PL, O = Unizeto Sp. z o.o., CN = Certum CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIIozCCB4ugAwIBAgIQI+zI37IaBcnHK05XQ4cS1zANBgkqhkiG9w0BAQsFADBf
MQswCQYDVQQGEwJSVTETMBEGA1UEChMKWWFuZGV4IExMQzEnMCUGA1UECxMeWWFu
ZGV4IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRIwEAYDVQQDEwlZYW5kZXggQ0Ew
HhcNMjEwODMwMTQyMTU5WhcNMjIwMjI4MDAwMDAwWjBVMQswCQYDVQQGEwJSVTEP
MA0GA1UEBwwGTW9zY293MQwwCgYDVQQLDANJVE8xEzARBgNVBAoMCllhbmRleCBM
TEMxEjAQBgNVBAMMCXlhbmRleC5ydTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BPXbn2MaxSzpkdTNPqpGMA4RWtw+v66S91GuZq7hDviCr3cnb7dXHNoY1/weJaWP
+bgGMtqsppVannS2jqNH20mjggYuMIIGKjAMBgNVHRMBAf8EAjAAMGkGA1UdHwRi
MGAwL6AtoCuGKWh0dHA6Ly9jcmxzLnlhbmRleC5uZXQvY2VydHVtL3ljYXNoYTIu
Y3JsMC2gK6AphidodHRwOi8veWFuZGV4LmNybC5jZXJ0dW0ucGwveWNhc2hhMi5j
cmwwcQYIKwYBBQUHAQEEZTBjMCwGCCsGAQUFBzABhiBodHRwOi8veWFuZGV4Lm9j
c3AtcmVzcG9uZGVyLmNvbTAzBggrBgEFBQcwAoYnaHR0cDovL3JlcG9zaXRvcnku
Y2VydHVtLnBsL3ljYXNoYTIuY2VyMB8GA1UdIwQYMBaAFDdc4xngso6hqE7Sz6vQ
3OMLXDVNMB0GA1UdDgQWBBQcg2nJ+yIj2TfUK4f2SeUmYoXvaTBMBgNVHSAERTBD
MAgGBmeBDAECAjA3BgwqhGgBhvZ3AgUBCgIwJzAlBggrBgEFBQcCARYZaHR0cHM6
Ly93d3cuY2VydHVtLnBsL0NQUzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
AwIwDgYDVR0PAQH/BAQDAgeAMIIC+wYDVR0RBIIC8jCCAu6CCXlhbmRleC5ydYIK
eWFuZGV4Lm5ldIILeWFuZGV4LmFlcm+CFnhuLS1kMWFjcGp4M2YueG4tLXAxYWmC
DXlhbmRleC5jb20ucnWCCXlhbmRleC5kZYINeWFuZGV4LmNvbS51YYIPKi55YW5k
ZXguY29tLnRyggl5YW5kZXguYnmCCnlhbmRleC5vcmeCCXlhbmRleC5lZYIJeWFu
ZGV4LnRqggsqLnlhbmRleC51eoILKi55YW5kZXgubHaCCXlhbmRleC5reoILKi55
YW5kZXguZnKCCXlhbmRleC5sdIIPKi55YW5kZXguY29tLnVhggsqLnlhbmRleC51
YYINKi55YW5kZXguam9ic4IMeWFuZGV4LmNvLmlsgg15YW5kZXguY29tLmFtgg15
YW5kZXguY29tLnRyggV5YS5ydYIJeWFuZGV4LmF6ggsqLnlhbmRleC50bYIJeWFu
ZGV4Lmtnggl5YW5kZXgubWSCDCoueWFuZGV4Lm5ldIIMKi55YW5kZXgub3Jnggl5
YW5kZXguZnKCCyoueWFuZGV4LmRlghgqLnhuLS1kMWFjcGp4M2YueG4tLXAxYWmC
CyoueWFuZGV4LmJ5ggcqLnlhLnJ1gg8qLnlhbmRleC5jb20uZ2WCDXlhbmRleC5j
b20uZ2WCCXlhbmRleC51YYILKi55YW5kZXgudGqCCyoueWFuZGV4LmVlggsqLnlh
bmRleC5sdIIJeWFuZGV4LnRtggl5YW5kZXgudXqCCyoueWFuZGV4LmF6ggt5YW5k
ZXguam9ic4ILKi55YW5kZXgucnWCCXlhbmRleC5sdoILKi55YW5kZXgubWSCDCou
eWFuZGV4LmNvbYILKi55YW5kZXgua3qCCnlhbmRleC5jb22CDyoueWFuZGV4LmNv
bS5ydYIOKi55YW5kZXguY28uaWyCCyoueWFuZGV4Lmtngg0qLnlhbmRleC5hZXJv
gg8qLnlhbmRleC5jb20uYW0wggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB1AG9T
dqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABe5drp7UAAAQDAEYwRAIg
QT250o43qTQ82/FcaUeiqT/cNr+lwm/YNCatXOiiPbwCIA2pgTN9PZ1dYqHzsJfu
2jHOeMoNJhZfg2neFMnZ1H2rAHYARqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy
/HD+bUcAAAF7l2untAAABAMARzBFAiEA8/1KXVBK4k7jpfIJJWXa3at+Br/fhtGl
qfwReQrYEkQCICQIipOhWcfsFn1luHLs3uuZ5Y2xZC1ED21Z5Rnl/E7oAHcAVYHU
whaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0wwAAAF7l2un3AAABAMASDBGAiEA
3haQavO9xagPVJDZmfpXAUxEmrFOnKFTjWusBUcqtZQCIQCH6IlPb+sBlUZPmHnh
2zRxGWidCklmfC4K3MpziH/PqTANBgkqhkiG9w0BAQsFAAOCAQEAbIUAxjezMTPB
mgFTpR5JpoEABqZEif1O4dqlDArGBkXJ9x0fLwjmYFvG/PgIoPaI0dm/UWP2rrxo
xwU57I2c/zVxxwOUwnNsZVv5RtiYePTNtbdOsMWTKMyPTXVGy4fvndAdS3Cg9sqn
vmqebO75hx0/L6upg3Aojf9XaQNA3Iucmb3zXMiUB3PQQccyVxyRqXFIlB6Q8uGG
F3pyYuidqa3jU+ToWrCO7lD+brkFPCDC+/EALw6AfrrsLa3uDWU6b2G4x0MQrOTI
vd9460f1nmW3d8LXdcc1Y7ai8RcMEtdV5qHXj8jz2mhWR1OgUnTH35G2vtjLR1sG
eX4RWZWlWQ==
-----END CERTIFICATE-----
subject=C = RU, L = Moscow, OU = ITO, O = Yandex LLC, CN = yandex.ru

issuer=C = RU, O = Yandex LLC, OU = Yandex Certification Authority, CN = Yandex CA

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 5000 bytes and written 391 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 9185FFB53311D846CB76EDA755A115431B800EA7D86308E15BA99F9E71E26B37
    Session-ID-ctx: 
    Resumption PSK: 831D819F1E2AE84E302FAEE7B02B5A6C80820D35313371A33FAE5905BA0EFD18462F367F39A39311FECBAC82A443A7E4
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 17 31 08 61 a6 42 6c a3-26 c7 0e 6b 5a 96 33 d1   .1.a.Bl.&..kZ.3.
    0010 - e0 e1 a1 66 fd 25 82 93-8f 97 5d c0 cd 7e 3a b8   ...f.%....]..~:.
    0020 - 0e d1 c6 8f aa 9d 24 69-59 eb 75 47 4f 0b 2a 61   ......$iY.uGO.*a
    0030 - ee 99 85 bd d6 47 f3 7f-c9 cb 2c 87 1f 84 92 76   .....G....,....v
    0040 - 1a c8 7b d2 5e cd 34 11-cb 0f a2 cf 45 0f a6 c7   ..{.^.4.....E...
    0050 - de 09 9a b6 8d d0 57 9a-ec 0e cd 13 70 e2 63 95   ......W.....p.c.
    0060 - fd df 4e 2f 39 fb 4d cc-d7 b2 c2 ce b8 bc 4a 58   ..N/9.M.......JX
    0070 - f1 12 8b 5f 43 b3 f2 57-0d bb 2b 8b ad 19 48 c1   ..._C..W..+...H.
    0080 - 41 5e 6f 3d c2 ff 80 39-09 36 38 bb 86 6f 58 52   A^o=...9.68..oXR
    0090 - b1 f4 4b 8c 9b e9 d6 49-41 6a d4 a9 58 d8 e9 31   ..K....IAj..X..1
    00a0 - 0c 0f 8e 58 ef a7 93 8e-49 5d 35 ff 97 d4 12 36   ...X....I]5....6
    00b0 - d2 bb cf a5 ac 32 80 57-02 00 c1 6b 13 aa 10 ee   .....2.W...k....

    Start Time: 1636032058
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 939BA184F96D08DC33E2236E7AC76ADF3D9F440792E235C1C9E93F7B3980D639
    Session-ID-ctx: 
    Resumption PSK: C5282598982E929C3587169A663817F417B3B0CDD07B0D18CFD92B461F33A7877EA0FCAFCDF9C64B7A52CB355BB7F4DE
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 17 31 08 61 a6 42 6c a3-26 c7 0e 6b 5a 96 33 d1   .1.a.Bl.&..kZ.3.
    0010 - 11 5c 6d 07 e3 27 c0 98-9e cb e6 57 24 d0 1a 81   .\m..'.....W$...
    0020 - ea 47 79 65 8f ff 07 97-fc ab bb 75 b5 68 30 1e   .Gye.......u.h0.
    0030 - 5d ee 90 aa 70 d8 16 a3-fa 9c aa 10 ee 47 27 b3   ]...p........G'.
    0040 - 93 46 a5 a8 a3 40 4f 5e-df 54 53 7f a3 a9 19 83   .F...@O^.TS.....
    0050 - 96 80 58 64 2a 7a c3 28-43 d4 56 ef e3 62 b4 8f   ..Xd*z.(C.V..b..
    0060 - 20 bb 91 3b 65 7f 35 94-67 82 36 7e f4 92 42 3d    ..;e.5.g.6~..B=
    0070 - 82 61 e8 b1 c6 64 ee 17-24 4b ad 78 89 b9 e1 f8   .a...d..$K.x....
    0080 - 69 d7 08 0a 71 64 0a d6-95 91 10 ba 51 6c af ac   i...qd......Ql..
    0090 - 1b 59 8d ae 4d d0 49 d8-51 ef 92 e1 d6 aa b4 dc   .Y..M.I.Q.......
    00a0 - af 9a ba a7 67 c8 42 c4-f5 ae f0 1d 79 87 68 88   ....g.B.....y.h.
    00b0 - 91 b5 80 19 20 86 59 b9-66 30 08 d4 8b e1 b0 5c   .... .Y.f0.....\

    Start Time: 1636032058
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
HTTP/1.1 200 Ok
Accept-CH: Viewport-Width, DPR, Device-Memory, RTT, Downlink, ECT
Accept-CH-Lifetime: 31536000
Cache-Control: no-cache,no-store,max-age=0,must-revalidate
...

Of course, you are right. One can check TLS connection establishment using openssl s_client. But after the connection establishment s_client makes a special request to s_server. A server being tested most probably doesn’t await it.

I was not aware of that, will take a look.
Check the following: HTTP headers/TLS padding as a censorship circumvention method - #2 by ValdikSS

To my shame, there is no special magic between an openssl s_server and an openssl s_client. Without an ‘-www’ option openssl s_server talks a trivial protocol. ’ If a connection request is established with an SSL client and neither the -www nor the -WWW option has been used then normally any data received from the client is displayed and any key presses will be sent to the client.’
Simple hacks with GET requests are possible.

So openssl s_client -quiet is a fast and smart way to check whether a SNI-less connection is available to some blocked resource.