CLOVER🍀

That was when it all began.

openssl s_clientコマンドを䜿う

これは、なにをしたくお曞いたもの

最近の通信はSSLTLS䞊で行われるこずが倚くなり、平文のものはあたり芋かけなくなっおきたした。

平文の頃はtelnetコマンドやcurlのtelnet://プロトコルでのアクセスでいろいろやっおいたしたが、SSLTLSずなるずちょっず困りたす。
こういう時はどうしたらず思ったのですが、OpenSSLのクラむアントコマンドを䜿うのが良さそうですね。

これからのこずを考えるず、openssl s_clientにもっず慣れ芪しんだ方がいいのかもしれたせん。

openssl s_client

OpenSSLのオフィシャルサむトはこちら。

OpenSSL

openssl s_clientコマンドのmanペヌゞはこちら。

openssl s_client

openssl s_clientは、SSLTLSを䜿っおリモヌトホストに接続するための汎甚的なSSLTLSクラむアントを実装したコマンドです。
SSLサヌバヌの蚺断ツヌルずしお䟿利だ、ずされおいたす。

This command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS. It is a very useful diagnostic tool for SSL servers.

今回はこのコマンドを䜿っおいろいろ詊しおみたす。

環境

今回の環境は、こちら。Ubuntu Linux 22.04 LTSです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.3 LTS
Release:        22.04
Codename:       jammy


$ uname -srvmpio
Linux 5.15.0-83-generic #92-Ubuntu SMP Mon Aug 14 09:30:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

OpenSSLのバヌゞョン。

$ openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

たた、Ubuntu Linux 22.04 LTSをもう1台甚意しお、こちらにSSLTLSを有効化したApacheをむンストヌルしおおきたす。

$ sudo apt install apache2
$ sudo systemctl enable apache2

SSLTLSを有効化。

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl
$ sudo systemctl restart apache2

このApacheが皌働するサヌバヌのIPアドレスは、192.168.33.10ずしたす。

ヘルプを芋る

なにはずもあれ、たずはヘルプから。

$ openssl s_client -help

SSLTLSサヌバヌに接続する

-connectの埌に[host:port]圢匏で、接続先を指定したす。

$ openssl s_client -connect [host:port]

HTTPSでアクセスしおみる

HTTPSでアクセスしおみたしょう。甚意したApacheにアクセスしおみたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf

-crlfオプションは、改行をCRLFで送信するものです。

蚌明曞情報などがいろいろ出力されお、入力埅ちになりたす。

CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = ubuntu2204.localdomain
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = ubuntu2204.localdomain
verify return:1
---
Certificate chain
 0 s:CN = ubuntu2204.localdomain
   i:CN = ubuntu2204.localdomain
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  9 13:39:03 2023 GMT; NotAfter: Sep  6 13:39:03 2033 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIUMZMUSvCr6TT7hGfk9OoJGFmmBgAwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWdWJ1bnR1MjIwNC5sb2NhbGRvbWFpbjAeFw0yMzA5MDkx
MzM5MDNaFw0zMzA5MDYxMzM5MDNaMCExHzAdBgNVBAMMFnVidW50dTIyMDQubG9j
YWxkb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgsQH1T4yX
TpXXNQtC/KuSPpAGk+XpwSsdSQ21MrscFWojw7T+Hv/+tmKNvVI7/4i8w6sf56Jk
tQwFnF+BsaVUwMe/kFRF6A98uUjMWsOmpnP4BP4U43eqaBwQSQG+ylsqSyiwMnM1
qkrGafrc4FAUM5Oi2X+dH9TbzEUJdgijGYEc5L06IozyS/M6hul6jbGupnNxHuKG
EwWj07T77DhL/0oV5asu4S8CuYLn2IGcrqlU58Nqv0lt2n97OnSlcocnFlDcdVc7
4DQ/ThmVsXaZR2CghWdsgQaN5rTM/Fn3XJxnqOp/wBgSVrJAWtKMAaVFJPm0W1KJ
UcaFGJQzHsZ9AgMBAAGjTzBNMAkGA1UdEwQCMAAwIQYDVR0RBBowGIIWdWJ1bnR1
MjIwNC5sb2NhbGRvbWFpbjAdBgNVHQ4EFgQUtgGicseT4uY5IR/zyIkyAfwJJE8w
DQYJKoZIhvcNAQELBQADggEBAHG39cf00tFMNNInCY6Y39H3vjjL8zzvn085jaPs
PVceDWWxHNU1tPlHKgPQVJEvpbd8SX7AG66b0/vvlAOOAE0E8gxrHkbZBQXqMVSN
3ILtYQ6byDk3QazwnPBNLHLG08M5X/ySuBHxDsqx07E2Fm1jTZ/zZBxbMwWyZbKT
jIbMYe5GqiAW4mXwc0uxOQx559jhP/dpO9ncUyg7ScWuZEQeaMJn9q0YiJxSIlKD
Lb3brYuDNq0N4kfXLKKcfd4jcmZsLYo7a+WUO5Sg5ZUxsjOXZEqXxdVfRULnob7C
r/rE3QtTqdOH1hrclCMnKfkxnZju1tk/PSaLTlxtzxNYY/E=
-----END CERTIFICATE-----
subject=CN = ubuntu2204.localdomain
issuer=CN = ubuntu2204.localdomain

〜省略〜

---
read R BLOCK

ちなみに、Apacheの蚌明曞は自己眲名蚌明曞なのですが、特に゚ラヌにならないようです。

HTTPリク゚ストを入力。

GET / HTTP/1.1
Host: 192.168.33.10

レスポンス。

GET / HTTP/1.1
Host: 192.168.33.10

HTTP/1.1 200 OK
Date: Sat, 09 Sep 2023 13:49:48 GMT
Server: Apache/2.4.52 (Ubuntu)
Last-Modified: Sat, 09 Sep 2023 13:39:08 GMT
ETag: "29af-604ed37b097b8"
Accept-Ranges: bytes
Content-Length: 10671
Vary: Accept-Encoding
Content-Type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">


〜省略〜

最初の蚌明曞情報を衚瀺させたくない堎合は、-quietオプションを指定したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -quiet

衚瀺内容は、これくらいに少なくなりたす。

Can't use SSL_get_servername
depth=0 CN = ubuntu2204.localdomain
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = ubuntu2204.localdomain
verify return:1

この埌は入力埅ちになりたす。

ちなみに、アクセス先がApacheの堎合、-crlfがないずBad Requestを返すようです。

GET / HTTP/1.1
HTTP/1.1 400 Bad Request
Date: Sat, 09 Sep 2023 13:52:23 GMT
Server: Apache/2.4.52 (Ubuntu)
Content-Length: 315
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at ubuntu2204.localdomain Port 443</address>
</body></html>
closed

HTTPヘッダヌを入力する前に匟かれおしたいたす。

サヌバヌの蚌明曞を取埗する

サヌバヌの蚌明曞を取埗するには、以䞋のコマンドを実行したす。

$ echo | openssl s_client -connect 192.168.33.10:443 2>&1 | \
    perl -wn -e 'print if /-BEGIN CERTIFICATE-/ .. /-END CERTIFICATE-/' > server.crt

埌半はPerl One Linerで、蚌明曞の郚分だけを切り取っおいたす。䜿わない堎合は、別の方法゚ディタなどで蚌明曞の郚分を
切り出したしょう。

このようなファむルが取埗できたした。

server.crt

-----BEGIN CERTIFICATE-----
MIIDHzCCAgegAwIBAgIUMZMUSvCr6TT7hGfk9OoJGFmmBgAwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWdWJ1bnR1MjIwNC5sb2NhbGRvbWFpbjAeFw0yMzA5MDkx
MzM5MDNaFw0zMzA5MDYxMzM5MDNaMCExHzAdBgNVBAMMFnVidW50dTIyMDQubG9j
YWxkb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgsQH1T4yX
TpXXNQtC/KuSPpAGk+XpwSsdSQ21MrscFWojw7T+Hv/+tmKNvVI7/4i8w6sf56Jk
tQwFnF+BsaVUwMe/kFRF6A98uUjMWsOmpnP4BP4U43eqaBwQSQG+ylsqSyiwMnM1
qkrGafrc4FAUM5Oi2X+dH9TbzEUJdgijGYEc5L06IozyS/M6hul6jbGupnNxHuKG
EwWj07T77DhL/0oV5asu4S8CuYLn2IGcrqlU58Nqv0lt2n97OnSlcocnFlDcdVc7
4DQ/ThmVsXaZR2CghWdsgQaN5rTM/Fn3XJxnqOp/wBgSVrJAWtKMAaVFJPm0W1KJ
UcaFGJQzHsZ9AgMBAAGjTzBNMAkGA1UdEwQCMAAwIQYDVR0RBBowGIIWdWJ1bnR1
MjIwNC5sb2NhbGRvbWFpbjAdBgNVHQ4EFgQUtgGicseT4uY5IR/zyIkyAfwJJE8w
DQYJKoZIhvcNAQELBQADggEBAHG39cf00tFMNNInCY6Y39H3vjjL8zzvn085jaPs
PVceDWWxHNU1tPlHKgPQVJEvpbd8SX7AG66b0/vvlAOOAE0E8gxrHkbZBQXqMVSN
3ILtYQ6byDk3QazwnPBNLHLG08M5X/ySuBHxDsqx07E2Fm1jTZ/zZBxbMwWyZbKT
jIbMYe5GqiAW4mXwc0uxOQx559jhP/dpO9ncUyg7ScWuZEQeaMJn9q0YiJxSIlKD
Lb3brYuDNq0N4kfXLKKcfd4jcmZsLYo7a+WUO5Sg5ZUxsjOXZEqXxdVfRULnob7C
r/rE3QtTqdOH1hrclCMnKfkxnZju1tk/PSaLTlxtzxNYY/E=
-----END CERTIFICATE-----

SSLTLS蚌明曞を指定しおアクセスする

今回のApacheは、自己眲名蚌明曞を䜿っおいたので

$ openssl s_client -connect 192.168.33.10:443 -crlf

よく芋るずアクセス時にverify errorが出力されおいたした。

CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = ubuntu2204.localdomain
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = ubuntu2204.localdomain
verify return:1

蚌明曞の怜蚌にも倱敗しおいたす。

---
SSL handshake has read 1363 bytes and written 404 bytes
Verification error: self-signed certificate
---

これでコマンドが止たったりはしないのですが。

ここで、先皋取埗したサヌバヌ蚌明曞を-CAfileオプションで指定するこずで、この゚ラヌが出ないようにするこずができたす。

$ openssl s_client -connect 192.168.33.10:443  -crlf -CAfile server.crt

今床は、蚌明曞の゚ラヌが出なくなりたした。

CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = ubuntu2204.localdomain
verify return:1

こちらもOKです。

---
SSL handshake has read 1359 bytes and written 373 bytes
Verification: OK
---

蚌明曞゚ラヌになる堎合に停止する

-verify_return_errorオプションを指定するず、蚌明曞゚ラヌになるず凊理を停止したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -verify_return_error

ここで止たりたす。

CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = ubuntu2204.localdomain
verify error:num=18:self-signed certificate
40671ED1CC7F0000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:../ssl/statem/statem_clnt.c:1883:
---
Certificate chain
 0 s:CN = ubuntu2204.localdomain
   i:CN = ubuntu2204.localdomain
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  9 13:39:03 2023 GMT; NotAfter: Sep  6 13:39:03 2033 GMT
---
no peer certificate available
---
No client certificate CA names sent
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 999 bytes and written 300 bytes
Verification error: self-signed certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 18 (self-signed certificate)
---

有効な蚌明曞を指定するず、動䜜するようになりたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -CAfile server.crt -verify_return_error

䜿甚するプロトコルを指定する

-tlsXXXオプションを䜿甚したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -tls1_3

指定可胜なTLSプロトコルはこちら。

$ openssl s_client -help 2>&1 | grep '\-tls1'
 -tls1                      Just use TLSv1
 -tls1_1                    Just use TLSv1.1
 -tls1_2                    Just use TLSv1.2
 -tls1_3                    Just use TLSv1.3

サヌバヌがサポヌトしおいないプロトコルを指定するず、゚ラヌになりたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -tls1
CONNECTED(00000003)
40A7D6A9477F0000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:../ssl/statem/statem_lib.c:104:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 7 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

このあたりは、以前こちらで確認したした。

サーバーが対応しているSSL/TLSプロトコルを確認する(openssl s_client、nmap) - CLOVER🍀

䜿いたくないプロトコルを-no_tlsXXXで指定するこずもできたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -no_tls1

このあたりが指定できたすね。

$ openssl s_client -help 2>&1 | grep '\-no_tls1'
 -no_tls1                   Just disable TLSv1
 -no_tls1_1                 Just disable TLSv1.1
 -no_tls1_2                 Just disable TLSv1.2
 -no_tls1_3                 Just disable TLSv1.3

暗号スむヌトを指定する

-ciphersuitesオプションで、TLSv1.3で䜿甚する暗号スむヌトを指定できたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -ciphersuites TLS_AES_128_GCM_SHA256

耇数指定する堎合は、:で区切りたす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384

䜿甚できる暗号スむヌトは、以䞋のようなコマンドでプロトコルごずに確認するずよいでしょう。

$ openssl ciphers -v -s -tls1_3

TLSv1.2以䞋の堎合は、-cipherで指定したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -cipher 'HIGH:!aNULL:!MD5' -tls1_2

これに぀いおは、こちらにも曞きたした。

OpenSSLでの暗号スイートと指定方法を確認する(+Apache、nginxでのIPAガイド設定例含む)) - CLOVER🍀

プロキシサヌバヌを指定する

-proxyオプションを指定するこずで、プロキシサヌバヌを介しおアクセスしたす。

$ openssl s_client -connect [host]:[port] -proxy [proxy-host]:[proxy-port]

-connectず合わせお䜿うこずで、指定されたプロキシサヌバヌにHTTP CONNECTでアクセスしたす。

サヌバヌ名を指定する

デフォルトでは、-connectで指定された名前がサヌバヌ名ずしおClientHelloメッセヌゞで䜿われたす。

これず異なる名前を指定する堎合は-servernameオプションで指定したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -servername ubuntu2204.localdomain

トラフィックをダンプするデバッグする

あたり䜿うこずはないかもしれたせんが、-debugオプションを指定したす。

$ openssl s_client -connect 192.168.33.10:443 -crlf -debug

おわりに

OpenSSLのs_clientコマンドに぀いお、いろいろ調べおみたした。

軜く詊すくらいにする぀もりが、オプションを眺めおいたらけっこう増えおしたいたしたが。

これからちゃんず䜿えおいけたらいいなず思いたす。