= openssl s_client = * SSLサーバー(とボカしておく)に接続確認を行うための方法。 * telnet(1) 的な使い方(ネゴシエーション後)も可能であるため、手動で通信確認を行う場合にも使用する。 * ここでは検証にフォーカスする。 * 検証だけなら[[https://www.ssllabs.com/ssltest/|SSL Server Test (Powered by Qualys SSL Labs)]]や[[https://cryptoreport.websecurity.symantec.com/checker/views/certCheck.jsp|Symantec SSL Cheker]]使えばいいぢゃんという話もあるが、より簡易な範囲で検証したい場合に使用する。 * 実際、実運用前の検証に上記サイトで確認することをお勧めする。 <> = コマンド(基本形) = {{{ openssl s_client -connect wiki.ninth-nine.com:https < /dev/null }}} インタラクティブモードで使うなら {{{-ign_eof}}} オプションを付けること。 {{{ openssl s_client -connect wiki.ninth-nine.com:https -ign_eof }}} == 実行結果例(基本形・問題無い場合) == {{{ CONNECTED(00000003) depth=2 /O=Digital Signature Trust Co./CN=DST Root CA X3 verify return:1 depth=1 /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 verify return:1 depth=0 /CN=wiki.ninth-nine.com verify return:1 --- Certificate chain 0 s:/CN=wiki.ninth-nine.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- MIIFCjCCA/KgAwIBAgISA+EPIHSAAQuC+K1TOdh0ME8CMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjA0MzAwOTA4MDBaFw0x NjA3MjkwOTA4MDBaMB4xHDAaBgNVBAMTE3dpa2kubmludGgtbmluZS5jb20wggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDboGgyujSarnx7yPCPoDGd/rh V4kHvRAW27JA6dWFJOU/hKz3YAd692Kqn+v17tpO/xMG13fHKd1+iWh1OMpaEMbV jnqVW1mQW1mcF3Rp6v7XqZGvAcbL2ZXMCyejw6/36+jiOpm6Gp782/7Vt/2Ogdqt ed3rGbK7ih0Etvq7SU2n4UNCBbZFG4NfUhLZlwUH/5J6lo3zGXudC88BVBxdQYdd EejRmwN6sxYxVZ+1N4iTQNYpld9oJOhrWvVQ/JtVE4rdK4gZkxTep7y1ahyPBGd0 a/25q1bK5wRjYyzMCsz5z7BY28X6CwirbFpcnsHCKXKwy8MLqk9IqgrPPIqxAgMB AAGjggIUMIICEDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFIpp8i7c66kjUqM2OjrX LrGi1jeEMB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUF BwEBBGQwYjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNy eXB0Lm9yZy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5j cnlwdC5vcmcvMB4GA1UdEQQXMBWCE3dpa2kubmludGgtbmluZS5jb20wgf4GA1Ud IASB9jCB8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIB FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtU aGlzIENlcnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlp bmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRp ZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9y ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEARdYBZ/13CAnEQoN73VPriX+M 047m9+QXC9shoKroZGBZuMwMETs0FNxKbFpVHlf/PIbryJ4XBJK34JyQT7aPpEH8 PvWbeOsorxxKfSC6dn4kds/RFgfTOo9CU17ddDG4d0PVGb8q/V7gweOvYf58CwG7 EhDFZFqmi/upGMzyPHkag76qBewILQXMMSSrgSyVfJwCW6PqODyxOL5x3+xqdpqG GYwCcf8WQC9uQcuBRLhX+YWubv2QMh/ote37FdOMw8TuL9xhJoFzCAYt3rC1SAc+ dV07vJ77AafMTskyKpkZJix4hPVYBHV3Gfmm5irienNhOd+BRJEE6BVhBfUZXA== -----END CERTIFICATE----- subject=/CN=wiki.ninth-nine.com issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 --- Acceptable client certificate CA names /C=JP/O=Ninth Nine/CN=Ninth Nine SelfSign CA --- SSL handshake has read 3477 bytes and written 425 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: Session-ID-ctx: Master-Key: 7EF85F46358E5F73A0226EC23CAFE6B31907E4EACA9BCA5E9969BC410E78F8091DA6F33F786F509D41D6E404B91A5671 Key-Arg : None Krb5 Principal: None Start Time: 1462285501 Timeout : 300 (sec) Verify return code: 0 (ok) --- DONE }}} == 実行結果例(基本形・問題有る場合) == {{{ CONNECTED(00000003) depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/CN=wiki.ninth-nine.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- MIIFCjCCA/KgAwIBAgISA+EPIHSAAQuC+K1TOdh0ME8CMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjA0MzAwOTA4MDBaFw0x NjA3MjkwOTA4MDBaMB4xHDAaBgNVBAMTE3dpa2kubmludGgtbmluZS5jb20wggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDboGgyujSarnx7yPCPoDGd/rh V4kHvRAW27JA6dWFJOU/hKz3YAd692Kqn+v17tpO/xMG13fHKd1+iWh1OMpaEMbV jnqVW1mQW1mcF3Rp6v7XqZGvAcbL2ZXMCyejw6/36+jiOpm6Gp782/7Vt/2Ogdqt ed3rGbK7ih0Etvq7SU2n4UNCBbZFG4NfUhLZlwUH/5J6lo3zGXudC88BVBxdQYdd EejRmwN6sxYxVZ+1N4iTQNYpld9oJOhrWvVQ/JtVE4rdK4gZkxTep7y1ahyPBGd0 a/25q1bK5wRjYyzMCsz5z7BY28X6CwirbFpcnsHCKXKwy8MLqk9IqgrPPIqxAgMB AAGjggIUMIICEDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFIpp8i7c66kjUqM2OjrX LrGi1jeEMB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUF BwEBBGQwYjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNy eXB0Lm9yZy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5j cnlwdC5vcmcvMB4GA1UdEQQXMBWCE3dpa2kubmludGgtbmluZS5jb20wgf4GA1Ud IASB9jCB8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIB FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtU aGlzIENlcnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlp bmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRp ZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9y ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEARdYBZ/13CAnEQoN73VPriX+M 047m9+QXC9shoKroZGBZuMwMETs0FNxKbFpVHlf/PIbryJ4XBJK34JyQT7aPpEH8 PvWbeOsorxxKfSC6dn4kds/RFgfTOo9CU17ddDG4d0PVGb8q/V7gweOvYf58CwG7 EhDFZFqmi/upGMzyPHkag76qBewILQXMMSSrgSyVfJwCW6PqODyxOL5x3+xqdpqG GYwCcf8WQC9uQcuBRLhX+YWubv2QMh/ote37FdOMw8TuL9xhJoFzCAYt3rC1SAc+ dV07vJ77AafMTskyKpkZJix4hPVYBHV3Gfmm5irienNhOd+BRJEE6BVhBfUZXA== -----END CERTIFICATE----- subject=/CN=wiki.ninth-nine.com issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 --- Acceptable client certificate CA names /C=JP/O=Ninth Nine/CN=Ninth Nine SelfSign CA --- SSL handshake has read 3299 bytes and written 469 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-SHA Session-ID: F2B072DD85862F75E2A4B3D0A7FABFEACB07CF963A29166F4082936699F0658F Session-ID-ctx: Master-Key: A2A188B69E7C6408F3E4D12996E5E4077AC349F0CD5747536944F953B565E7B255AE4D8722E32FF7A5398FB3D153AF6C Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 300 (seconds) TLS session ticket: 0000 - 60 98 5e c2 e7 95 a6 3e-e0 c5 8b 03 0a f6 ff cc `.^....>........ 0010 - 36 90 e5 7b 2c 59 f6 4d-44 a9 63 07 78 e4 e7 27 6..{,Y.MD.c.x..' 0020 - 32 0a 10 8a 9c f7 c3 41-d8 fc 41 18 8e 62 75 c8 2......A..A..bu. 0030 - 70 a3 43 8e 85 c6 d4 2c-48 5d 0c 46 db 9b 14 85 p.C....,H].F.... 0040 - 28 05 d3 7a bf d6 ca e3-d0 2e 97 08 21 c4 69 62 (..z........!.ib 0050 - 56 65 46 bf 78 1a 5c 06-6f 1d 1c 98 0d b0 56 f4 VeF.x.\.o.....V. 0060 - c5 92 64 7c ff 42 11 4f-bb 91 ae 10 70 4f cf 9a ..d|.B.O....pO.. 0070 - 65 f8 af 67 c4 44 7a 2c-95 df a0 e1 9d c2 92 d3 e..g.Dz,........ 0080 - 74 6b 80 23 90 13 60 32-cd 3d 66 86 dd d6 25 08 tk.#..`2.=f...%. 0090 - 26 51 5c 03 da 5d 8c e8-42 ef 14 ce cd 8b 3b 08 &Q\..]..B.....;. 00a0 - b5 1a e7 31 4f d5 1d be-e8 00 bb e0 73 4a 01 13 ...1O.......sJ.. 00b0 - a6 da 5a 5d e8 2e 24 3a-c5 33 ac e0 ca 95 46 76 ..Z]..$:.3....Fv Start Time: 1462285514 Timeout : 300 (sec) Verify return code: 20 (unable to get local issuer certificate) --- DONE }}} == 実行結果から読み取れること == 実行結果からは以下のことが読み取れる。 * 証明書チェインの、たどっている状態。 * TLS/SSLネゴシエーション結果。 * SSL証明書の状態。 以下、個別に見ていく。 == 証明書チェイン == 証明書チェインの状態については下記の箇所にまとめられている。 {{{ Certificate chain 0 s:/CN=wiki.ninth-nine.com i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 }}} * `0`, `1` は段数(通常「深さ」で表現される)を意味し、1枚目の証明書、2枚目の証明書がサーバーが送られてきたことがわかる。 * `s:` はサブジェクト(主体者)の、`i:` はイシュア(発行者)の、ディスティングイッシュ名を意味する。 * 1枚目のイシュアと2枚目のサブジェクトが同じであることに意味がある。 * これは2枚目の証明書(いわゆる中間証明書)で1枚目の証明書が署名され、認証のチェインがつながっていることを意味する。 * この中間証明書を署名し、認証のチェインをつなげているのが「ルート証明書」となる。 * ルート証明書は具体的には「/usr/local/share/certs/ca-root-nss.crt」や「/etc/pki/tls/cert.pem」というファイルに格納されている「自己署名証明書」となる。 * 上記表現に合わせるなら、下記のような検証が暗黙に行われている(外挿は当然不可)。 {{{ 2 s:/O=Digital Signature Trust Co./CN=DST Root CA X3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 }}} * 証明書間で Issuer-Subject はつながらないといけないわけで、仮につながりが無い状態が発生した場合、鍵の設置状態としては間違った状態にある。この時、SSL証明書が不正扱いとして通信できない可能性がある。FirefoxやIEなど高次wブラウザでは自前で持ってる中間証明書を使用して通信できちゃう場合もある。 * また本ケースではルート証明書を含めて3段しか無いので間違いようがないが、クロスルート証明書でルート証明書と中間証明書をつないでるケースの場合、指定する順番が重要なケースもある。 * 下記事例は、とある著名サイトのシマンテックのOV SSL証明書のケースである。 {{{ Certificate chain 0 s:/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Cabinet Secretariat/OU=Cabinet Public Relations Office-1/CN=www.kantei.go.jp i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4 1 s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4 i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 2 s:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority }}} * ベリサイン(旧)からベリサイン(新・シマンテック)へのクロスルート証明書が設置されている。 * 2枚目の中間証明書と3枚目のクロスルート証明書の順番がひっくり返った場合、 * 組み込み系の簡易なSSLエンジン(フューチャーフォン端末や一部Android端末で確認した)だと順番をたどれずに、SSL証明書が不正扱いになる。 * FirefoxやIEといった高次wブラウザの場合、自前で順番をたどってしまい、問題に気がつかないケースがある。 実際には検証はもっとふか~いものがあるが、設置検証レベルで(s_client を使ってるので)あれば、これで十分である。 === 参考文献 === * [[https://qiita.com/n-i-e/items/35cba71d04b9123e676c|X.509証明書の検証手順とありがちな脆弱性]] == TLS/SSLネゴシエーション結果 == ネゴシエーションの結果については細かく調べると色々あるが、代表的なところは2つしかないので、その2つについて解説する。 {{{ : SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-SHA : }}} === プロトコルバージョン === プロトコルバージョンは「`Protocol`」行を見ると確認できる。これは以下の種類がある。 ※プロトコルに関するコメントは独断と偏見に満ちているので、異議は聞かない:-)。 ||<#FFFF00> プロトコルバージョン ||<#FFFF00> 運用ステータス ||<#FFFF00> 備考 || || SSLv2.0 || 完全に終了した。 || SSLv2 でネゴシエーションしようとするクライアントには死を。 || || SSLv3.0 || ほぼ終了した。 || 携帯キャリアもサポート切ったフューチャーフォンを相手する時くらい。 || || TLSv1.0 || 切りたいけどまだ現役。 || 数多くのクライアントが残ってるので切るに切れない状態:-)。 || || TLSv1.1 || 中途半端で普及せず || 中途半端ってこともなかったけど、普及する前に TLSv1.2 が出たので。 || || TLSv1.2 || 今ならこれにしとけ。 || SSLサーバー・クライアントともに 1.2 に対応すべし。 || || TLSv1.3 || 次世代として制定中 || 次世代。 || * ガチ新規クライアントをターゲットにするならTLSv1.2のみ対応で。 * ある種のガイドラインに沿って設定するならTLSv1.2+TLSv1.1の対応で(推奨)。 * ある程度広くサポートするならTLSv1.2+TLSv1.0。 * その上でプロトコルフォールバックのケアも考慮するならTLSv1.2+TLSv1.1+TLSv1.0。 * 古いクライアントをケアしないと行けないなら+SSL3.0といったところ。これはできれば止めた方がいい。 === 暗号スイート === 暗号スイートは「`Cipher`」行を見ると確認できる。 この暗号スイートは大枠で4つのパーツに分解できるので、組み合わせて使う。もちろんできない組み合わせもある。 とりあえず独断と偏見で現役と思われるアルゴリズムをリストアップしてみた。 改ざん検証アルゴリズムのSHA-1についてであるが、「[[https://blogs.technet.microsoft.com/jpsecurity/2015/11/02/faq-sha-1-sha-2/|SHA-1無くせ-!運動]]」で謳っているのがSSL証明書に関してのもので、こちらを明確に無くせと謳ってるのを見たことが無く、緩やかに退役していくものと思われる。 ||<#FFFF00> 鍵交換アルゴリズム ||<#FFFF00> 鍵暗号アルゴリズム ||<#FFFF00> 共有鍵暗号アルゴリズム ||<#FFFF00> 改ざん検証アルゴリズム || || ECDHE || RSA || AES || SHA || || ECDH || ECDSA || AES-CBC || SHA256 || || DHE || |||| AES-GCM-SHAxxx || || DH || || CAMELLIA || SHA386 || || RSA || || 3DES-EDE-CBC || || == SSL証明書の状態 == SSL証明書の状態については`SSL-Session`セクションの`Verify return code`行を見ると判別できる。 判別方法については個々に解説する。 === SSL証明書は正常 === {{{ Verify return code: 0 (ok) }}} === SSL証明書の署名検証に失敗 === {{{ Verify return code: 7 (certificate signature failure) }}} 本現象は以下のケースの時に発生する。 * SSL証明書が改ざんレベルで本当に壊れている場合(通常ありえない)。証明書のコピペミスの場合は書式エラーが発生するはずなのでry。いずれにせよ認証局から戻ってきた証明書の内容を確認すること。 * SSL証明書の署名アルゴリズムにOpenSSLが対応していない場合。 * CentOS4のOpenSSLが古くて、RSA2048bit/SHA256鍵(正確にはSHA256を知らない)に対応していないため発生したことがある。 * OpenSSLが対応していないということは、事実上、その環境ではどうしようも無いことを意味する。 === SSL証明書の有効期限切れ === {{{ Verify return code: 10 (certificate has expired) }}} 本現象は以下のケースの時に発生する。 * SSL証明書の更新忘れ。必要なら更新しよう。わかってるならスルーで。 * サーバー(この場合クライアントユースとしてのサーバー)の時刻発狂。古いサーバーでCMOSバッテリが消耗仕切ってサーバー時刻を維持できない状態で、リセット(は大丈夫なケースもあるが)や電源断で時刻が明後日の時間にリセットされた直後に起きる時がある。まず{{{date}}}コマンドを実行して、世間様一般の日時と合ってるか確認しよう。 * 実運用ではまずお目にかかることは無いが、希に世界的ニュースになることがある。 * [[http://techblog.yahoo.co.jp/maintenance/4/|WebAPIやOpenIDでSSLエラーが起きる現象につきまして]] * [[http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html|RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ]] === SSL証明書の認証チェインがたどれなかった場合 === {{{ Verify return code: 20 (unable to get local issuer certificate) }}} 本現象は以下のケースの時に発生する。 * 自己署名証明(俺々証明書)の場合。 * 運用の是非は兎も角、意図している場合は正常である。 * 俺々証明書なら{{{-CAfile 俺々証明書.crt}}}オプションを指定することで回避することが可能。むしろわかってる(ローカルに証明書がある)なら推奨。 * 中間証明書の指定が間違っている。 * 複数の中間証明書を使い分けてる認証局を使用している場合、どの中間証明書を使用しているのかイシュアを[[../x509|確認]]してから設定する。 * どこどこ認証局だから何々中間証明書ファイル、と油断していると、マジ背中を刺されるケース発生。 * ルート証明書が指定されていない場合。 * FreeBSD の場合、`ETCSYMLINK`オプション(デフォルト有効)付きで[[https://www.freshports.org/security/ca_root_nss/|ports/security/ca_root_nss/]]をインストールすること。 * FreeBSD 10.1-RELEASE 以下の場合、更に {{{-CAfile /usr/local/etc/ssl/cert.pem}}}オプションを指定すること。 * CentOS の場合、{{{-CAfile /etc/pki/tls/cert.pem}}}オプションを指定する。 * なおインストールしなくてもオプションを指定しなくても大丈夫な場合(しても結果が変わらない場合)、別のケースが考え得る。 * 世間的に大丈夫とわかってるサーバー相手に対照実験をしよう。 * ルート証明書ファイル中に含まれないルート証明書が使われている場合。 * まず実運用では発生しない。改ざんルート証明書を疑おう。 * 俺々ルート証明書を使う場合は、{{{/etc/ssl/cert.pem}}}の代わりに俺々ルート証明書の公開鍵を指定すること。 = コマンド(-CAfile オプション) = {{{ openssl s_client -connect wiki.ninth-nine.com:443 -CAfile /etc/ssl/cert.pem < /dev/null }}} ルート証明書(複数可)を収納したファイルを指定する。 このファイルにより証明書チェインをルートからたどれるようになる。 OSやバージョン、インストール状態によっては指定不要な場合もある。 == 実行結果例(-CAfile オプション) == `Verify return code`の結果が変わるかも知れない以外は、表示される内容は変わらないので省略する。 = コマンド(-cipher オプション) = サーバーが対応している暗号スイート(Cipher Suite)の洗い出し。 {{{ openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL' < /dev/null }}} コマンド実行後に得られる`SSL-Session`の`Cipher`を順次指定(封印)する。これ以上調停できなくなった時が、全てリストアップ仕切れたことを意味する(減算法)。 {{{ openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA!AES256-SHA256' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA!AES256-SHA256!AES256-SHA' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA!AES256-SHA256!AES256-SHA!CAMELLIA256-SHA' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA!AES256-SHA256!AES256-SHA!CAMELLIA256-SHA!ECDHE-RSA-AES128-GCM-SHA256' < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -cipher 'ALL!ECDHE-RSA-AES256-SHA!DHE-RSA-AES256-SHA256!DHE-RSA-AES256-SHA!DHE-RSA-CAMELLIA256-SHA!AES256-SHA256!AES256-SHA!CAMELLIA256-SHA!ECDHE-RSA-AES128-GCM-SHA256!ECDHE-RSA-AES128-SHA256' < /dev/null : }}} 各暗号アルゴリズム(スイート)は「:」で区切る。また「!」は「使用しない」を意味する。この手のプレフィックスには「+」と「-」もあるが、減算法では意味が無いので本ケースでは説明しない。「ぼくがかんがえたさいきょうの」暗号スイートを構築(デッキ?)したくて、ゼロからビルドアップしていく加算法では意味があるかも知れないが、お勧めしない。 == 実行結果例(-CAfile オプション) == `Cipher`の結果が変わるかも知れない以外は、表示される内容は変わらないので、封印しきった結果だけ表示する。 {{{ CONNECTED(00000004) 34379298392:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s23_clnt.c:757: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 285 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1462350857 Timeout : 300 (sec) Verify return code: 0 (ok) --- }}} = コマンド(-プロトコル/-no_プロトコル オプション) = 対応プロトコルを「個別」に調査する。実際のブラウザで見たときとは結果が違う場合があるので注意。これは非対応プロトコルのフォールバック方法の違いに起因する(詳細はめんどくさいの解説しない)。 {{{ openssl s_client -connect wiki.ninth-nine.com:443 -ssl2 -no_ssl3 -no_tls1 -no_tls1_1 -no_tls1_2 < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -no_ssl2 -ssl3 -no_tls1 -no_tls1_1 -no_tls1_2 < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -no_ssl2 -no_ssl3 -tls1 -no_tls1_1 -no_tls1_2 < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -no_ssl2 -no_ssl3 -no_tls1 -tls1_1 -no_tls1_2 < /dev/null openssl s_client -connect wiki.ninth-nine.com:443 -no_ssl2 -no_ssl3 -no_tls1 -no_tls1_1 -tls1_2 < /dev/null }}} * {{{-tls1_1}}}(TLS1.1), {{{-tls1_2}}}(TLS1.2)オプションはOS(OpenSSL)のバージョンにより使用できない場合がある。 * 実際、現時点(2016/05/03)で{{{-tls1_3}}}(TLS1.3)オプションは存在しないし、将来的には{{{-ssl2}}}(SSL2.0)オプションが無くなるかもしれない。 == 実行結果例(-プロトコル/-no_プロトコル オプション) == `Protocol`(場合によっては`Cipher`行も)の結果が変わるかも知れない以外は、表示される内容は変わらないので、封印した(SSLv3 のみなど)結果だけ表示する。 {{{ CONNECTED(00000004) 34379298392:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s3_pkt.c:1300:SSL alert number 40 34379298392:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:/usr/src/secure/lib/libssl/../../../crypto/openssl/ssl/s3_pkt.c:637: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 0 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : SSLv3 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1462351055 Timeout : 7200 (sec) Verify return code: 0 (ok) --- }}} = コマンド(-servername オプション) = Server Name Indication(SNI)の検証する。 {{{ openssl s_client -connect wiki.ninth-nine.com:443 -servername wiki.ninth-nine.com < /dev/null }}} == 実行結果例(-servername オプション) == 検証したサーバーでの結果に違いは無いのでここでは省略する。世間様一般で、面白いのを見つけたら紹介することにする。 = コマンド(-ign_eof オプション) = s_client はデフォルトで「R」で始まる行と「Q」で始まる行(リターンキーを押してから認識)があると、 それぞれ「R」enegotiate、「Q」uitが行われる。 これはTLSレイヤーでのプリミティブな振る舞いとなるので、上位のプロトコル(HTTP等)が解釈される前に実行される。 特にSMTPの検証中、「RCPT To: <...>」と入力したつもりが、サーバーに送られず、 いわゆる「クライアント始動セキュア再ネゴシエーション」機能が働く。 参考文献 = * [[https://www.ssllabs.com/ssltest/|SSL Server Test (Powered by Qualys SSL Labs)]] * [[https://cryptoreport.websecurity.symantec.com/checker/views/certCheck.jsp|Symantec SSL Cheker]] * [[https://blogs.technet.microsoft.com/jpsecurity/2015/11/02/faq-sha-1-sha-2/|FAQ: SHA-1 廃止/SHA-2 移行に関するマイクロソフトのポリシー]] * [[http://techblog.yahoo.co.jp/maintenance/4/|WebAPIやOpenIDでSSLエラーが起きる現象につきまして]] * [[http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html|RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ]]