AWS / PHP / Python ちょいメモ

amazon web service , PHP, Python を使ったときのメモ。日本語でググってもわからなかった事を中心に。

HTTPS調べるときに便利なOpenSSLの使い方 <s_client編>

二ヶ月ほどよく使う機会があったので、まとめ。

基本の書式

$ openssl command [ commandオプション ] [ command引数 ] 

かならず command 部分が必須パラメーターになるのがポイント。

openssl というコマンドというよりも command を含めての覚えておくのが吉かなと(私自身がよく忘れてました)。


今回は、次の standard-command を紹介します。

  • openssl s_client : 汎用的な SSL/TLS クライアント

その他、cipher commandmessage-digest command がありますが、関連するものだけ合わせて。

※なお $ openssl だけを入力することで、インタラクティブモードにも入れますが、ここでは割愛

バージョン確認

バージョンによって、対応しているciper , message-digestが全然違います。古いOSで作業する場合には、要確認かなと。

Ubuntu 14.04 の場合:

$ openssl version
OpenSSL 1.0.1f 6 Jan 2014

macOS High Sierra (v.10.13.4) の場合:

$ openssl version
LibreSSL 2.2.7

HTTPSサイトへの通信と証明書の確認

「openssl s_client」 関連の紹介です。

HTTPSサイトへの通信と証明書の確認

$ openssl s_client -connect www.google.com:443
もしくは
$ openssl s_client -port 443 -host www.google.com
※公式の推奨は -connect の方

ポイントは、ポートのデフォルト値は443じゃないので明示する事。またhttp://は不要です。

SNI設定された、HTTPSサイトへの通信と証明書の確認

SNI : Server Name Indication は、1つのIP上で複数のSSL証明書を保持する技術です。Webサーバーでいう、名前ベース仮想ホストと同じようなイメージですね。

この設定がされたサーバーに接続しにいくときには、SNIに必要なドメイン情報を -servername オプションで指定してあげます。

$ openssl s_client -port 443 -host 13.32.115.6  -servername host.domain.toplevel


SNI設定されたIPに対して、 -servername なしで接続に行くと、次のようなエラーが返りました。

$ openssl s_client -port 443 -host 13.32.115.6
CONNECTED(00000003)
140210945451680:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:770:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 295 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

SSLサイトのはずなのに、 no peer certificate となったり、IPは正しいはずなのに、レスポンスされる証明書情報が異なる場合には -servername オプション忘れを疑うといいかもしれません。

表示を最小限にする -quiet

$ openssl s_client -connect www.google.com:443 -quiet
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
...

TLSバージョンを指定して接続 -tls1 , -tls1_1 , -tls1_2

$ openssl s_client -connect www.google.com:443 -tls1
$ openssl s_client -connect www.google.com:443 -tls1_1
$ openssl s_client -connect www.google.com:443 -tls1_2

openssl が対応している cipher を取得

沢山出力されるので、楕円曲線DH鍵共有 方式 ECDHE で絞り込んでみると、こんな感じ。

$ openssl ciphers -v | grep ECDHE | sort
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=ChaCha20-Poly1305 Mac=AEAD
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH     Au=ECDSA Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-RC4-SHA     SSLv3 Kx=ECDH     Au=ECDSA Enc=RC4(128)  Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=RSA  Enc=ChaCha20-Poly1305 Mac=AEAD
ECDHE-RSA-DES-CBC3-SHA  SSLv3 Kx=ECDH     Au=RSA  Enc=3DES(168) Mac=SHA1
ECDHE-RSA-RC4-SHA       SSLv3 Kx=ECDH     Au=RSA  Enc=RC4(128)  Mac=SHA1

cipher を指定して接続

前述のcipher一覧をみてopenssl自身が対応しているものの中から、特定の cipher を指定して接続する。

$ openssl s_client -connect google.com:443 -tls1_2 -cipher ECDHE-RSA-AES256-SHA

前述の TLS バージョンの指定との組み合わせも可能。

$ openssl s_client -connect google.com:443 -tls1_2 -cipher ECDHE-RSA-AES256-SHA

自分(openssl)も知らない cipher の場合にでるエラー。

$ openssl s_client -connect google.com:443 -cipher ECDHE-RSA-AES128-SHA384
error setting cipher list
140735588447176:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/ssl_lib.c:1323:

自分(openssl)は知ってるけど、相手(サーバー)は知らない場合のエラー。

$ openssl s_client -connect google.com:443 -cipher ECDHE-RSA-AES128-SHA256
CONNECTED(00000005)
140735588447176:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.50.2/libressl/ssl/s23_clnt.c:541:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 170 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---

参照

サイト

公式に一通りのコマンドまとまっています

OpenSSLの使い方各種のまとめ


証明書ファイルの拡張子やフォーマットについての説明が詳しいです。利用しているツールは openssl なので入りやすい?かも。

ヘルプ

openssl って グローバルなhelpコマンドは存在しない?のですよね。Macでエラー出た時の、コマンド一覧。

$ openssl -h
openssl:Error: '-h' is an invalid command.

Standard commands
asn1parse         ca                certhash          ciphers
crl               crl2pkcs7         dgst              dh
dhparam           dsa               dsaparam          ec
ecparam           enc               engine            errstr
gendh             gendsa            genpkey           genrsa
nseq              ocsp              passwd            pkcs12
pkcs7             pkcs8             pkey              pkeyparam
pkeyutl           prime             rand              req
rsa               rsautl            s_client          s_server
s_time            sess_id           smime             speed
spkac             ts                verify            version
x509

Message Digest commands (see the `dgst' command for more details)
gost-mac          md4               md5               md_gost94
ripemd160         sha               sha1              sha224
sha256            sha384            sha512            streebog256
streebog512       whirlpool

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb
aes-256-cbc       aes-256-ecb       base64            bf
bf-cbc            bf-cfb            bf-ecb            bf-ofb
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb
chacha            des               des-cbc           des-cfb
des-ecb           des-ede           des-ede-cbc       des-ede-cfb
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb
des-ede3-ofb      des-ofb           des3              desx
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc
rc2-cfb           rc2-ecb           rc2-ofb           rc4
rc4-40

command で、ciphers のようにヘルプが用意されてるものも。

$ openssl ciphers -h
usage: ciphers [-hVv] [-tls1] [cipherlist]
 -tls1              This option is deprecated since it is the default
 -v                 Provide cipher listing
 -V                 Provide cipher listing with cipher suite values

ヘルプ・オプションなくても、使い方は表示されます。

$ openssl s_client -h
unknown option -h
usage: s_client args

 -4            - Force IPv4
 -6            - Force IPv6
 -host host     - use -connect instead
 -port port     - use -connect instead
 -connect host:port - who to connect to (default is localhost:4433)
 -proxy host:port - connect to http proxy
 -verify arg   - turn on peer certificate verification
 -cert arg     - certificate file to use, PEM format assumed
 -certform arg - certificate format (PEM or DER) PEM default
 -key arg      - Private key file to use, in cert file if
                 not specified but cert file is.
 -keyform arg  - key format (PEM or DER) PEM default
 -pass arg     - private key file pass phrase source
...

対応しているコマンドの確認方法

openssl の standard-command , cipher command, message-digest command 、それぞれの確認方法です。

  • $ openssl list-standard-commands
  • $ openssl list-cipher-commands
  • $ openssl list-message-digest-commands

その他

MacOS では、OpenSSLパッケージではなく、LibreSSLパッケージが導入されています

x509編とかも書きたいなぁ。