クライアント認証
Apache は https でのクライアント認証に対応しています.
普段利用する https の場合は,サーバから送られてきたサーバ証明書を証明書をクライアント側で確認します.
クライアント認証の場合は,https で接続してきた端末(クライアント)から送られてきたクライアント証明書を使用して,サーバ側で認証をおこないます.
証明書の送信
ServerHello, Certificate, ServerKeyExchange の次に CertificateRequest が送信されてきます.
CertificateRquest には certificate_types と certificate_authorities の 2 つが含まれています.
設定
- /etc/httpd/conf/httpd.conf の編集
ServerName www.example.com:80
- /etc/httpd/conf.d/ssl.conf の編集(下記の内容に変更します)
## サーバ証明書 SSLCertificateFile /etc/pki/tls/certs/server.crt ## サーバ証明書とペアの秘密鍵 SSLCertificateKeyFile /etc/pki/tls/private/server.key ## 中間証明書(あれば設定する) SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt ## クライアント認証時にクライアント証明書を検証する CA 証明書(ca.crt には PEM 形式の証明書を複数枚格納することが可能です) SSLCACertificateFile /etc/pki/tls/certs/ca.crt ## クライアント証明書検証のタイプ SSLVerifyClient require
- ssl.conf で指定した証明書を格納する
- 本番環境であればサーバ証明書は正規の認証局から買いましょう
- テスト環境であれば,サーバ証明書を発行したオレオレ CA 証明書をクライアントにインストールして信頼しておきます
httpd を起動させる
# service httpd start
https://www.example.com へアクセス
今回はテスト用なので hosts に www.example.com をあらかじめ書いておきました.
無効なクライアント証明書による接続
期限切れのクライアント証明書を使用してみました.
無効なクライアント証明書を選択する以外は,上記の 有効なクライアント証明書による接続 と手順は同じです.
接続エラーになりました.
パケット
パケットは,Wireshark で取得しています.
CertificateRequest.
CertificateRequest 周りを見ています.
SSLv3 Record Layer: Handshake Protocol: Server Key Exchange Content Type: Handshake (22) Version: SSL 3.0 (0x0300) Length: 525 Handshake Protocol: Server Key Exchange Handshake Type: Server Key Exchange (12) Length: 521 SSLv3 Record Layer: Handshake Protocol: Multiple Handshake Messages Content Type: Handshake (22) Version: SSL 3.0 (0x0300) Length: 107 Handshake Protocol: Certificate Request Handshake Type: Certificate Request (13) Length: 99 Certificate types count: 6 Certificate types (6 types) Certificate type: RSA Fixed DH (3) Certificate type: DSS Fixed DH (4) Certificate type: Unknown (5) Certificate type: Unknown (6) Certificate type: RSA Sign (1) Certificate type: DSS Sign (2) Distinguished Names Length: 90 Distinguished Names (90 bytes) Distinguished Name Length: 28 Distinguished Name: (id-at-commonName=ca1.example.com) RDNSequence item: 1 item (id-at-commonName=ca1.example.com) RelativeDistinguishedName item (id-at-commonName=ca1.example.com) Id: 2.5.4.3 (id-at-commonName) DirectoryString: uTF8String (4) uTF8String: ca1.example.com Distinguished Name Length: 28 Distinguished Name: (id-at-commonName=ca2.example.com) RDNSequence item: 1 item (id-at-commonName=ca2.example.com) RelativeDistinguishedName item (id-at-commonName=ca2.example.com) Id: 2.5.4.3 (id-at-commonName) DirectoryString: uTF8String (4) uTF8String: ca2.example.com Distinguished Name Length: 28 Distinguished Name: (id-at-commonName=ca3.example.com) RDNSequence item: 1 item (id-at-commonName=ca3.example.com) RelativeDistinguishedName item (id-at-commonName=ca3.example.com) Id: 2.5.4.3 (id-at-commonName) DirectoryString: uTF8String (4) uTF8String: ca3.example.com Handshake Protocol: Server Hello Done Handshake Type: Server Hello Done (14) Length: 0
- Certificate types として下記の 6 つがクライアントに送られています
- RSA Fixed DH (3)
- DSS Fixed DH (4)
- Unknown (5)
- Unknown (6)
- RSA Sign (1)
- DSS Sign (2)
- Distinguished Names が容認する認証局の DN のリストです(今回は ca.crt に 3 枚の CA 証明書を格納しています)
- id-at-commonName=ca1.example.com
- id-at-commonName=ca2.example.com
- id-at-commonName=ca3.example.com
ClientCertificate
サーバからの CertificateRequest を受けて,ブラウザ上で選択したクライアント証明書の送信の部分を少しだけ見てみます.
SSLv3 Record Layer: Handshake Protocol: Multiple Handshake Messages Content Type: Handshake (22) Version: SSL 3.0 (0x0300) Length: 1239 Handshake Protocol: Certificate Handshake Type: Certificate (11) Length: 839 Certificates Length: 836 Certificates (836 bytes) Certificate Length: 833 Certificate (id-at-commonName=user03@example.org) signedCertificate version: v3 (2) serialNumber: 1 signature (shaWithRSAEncryption) Algorithm Id: 1.2.840.113549.1.1.5 (shaWithRSAEncryption) issuer: rdnSequence (0) rdnSequence: 1 item (id-at-commonName=ca3.example.com) RDNSequence item: 1 item (id-at-commonName=ca3.example.com) RelativeDistinguishedName item (id-at-commonName=ca3.example.com) Id: 2.5.4.3 (id-at-commonName) DirectoryString: uTF8String (4) uTF8String: ca3.example.com validity notBefore: utcTime (0) utcTime: 10-09-20 15:00:00 (UTC) notAfter: utcTime (0) utcTime: 13-01-20 15:00:00 (UTC) subject: rdnSequence (0) rdnSequence: 1 item (id-at-commonName=user03@example.org) RDNSequence item: 1 item (id-at-commonName=user03@example.org) RelativeDistinguishedName item (id-at-commonName=user03@example.org) Id: 2.5.4.3 (id-at-commonName) DirectoryString: uTF8String (4) uTF8String: user03@example.org subjectPublicKeyInfo algorithm (rsaEncryption) Algorithm Id: 1.2.840.113549.1.1.1 (rsaEncryption) Padding: 0 subjectPublicKey: 3082010a0282010100c322c4b058adee5342f5b7f6799800... extensions: 5 items Extension (id-ce-basicConstraints) Extension Id: 2.5.29.19 (id-ce-basicConstraints) critical: True BasicConstraintsSyntax Extension (id-ce-authorityKeyIdentifier) Extension Id: 2.5.29.35 (id-ce-authorityKeyIdentifier) AuthorityKeyIdentifier Extension (id-ce-subjectKeyIdentifier) Extension Id: 2.5.29.14 (id-ce-subjectKeyIdentifier) SubjectKeyIdentifier: 67d149c911412b2da2254fe94377e7e9c66a7b28 Extension (id-ce-extKeyUsage) Extension Id: 2.5.29.37 (id-ce-extKeyUsage) KeyPurposeIDs: 1 item KeyPurposeId: 1.3.6.1.5.5.7.3.2 (id-kp-clientAuth) Extension (id-ce-cRLDistributionPoints) Extension Id: 2.5.29.31 (id-ce-cRLDistributionPoints) CRLDistPointsSyntax: 1 item DistributionPoint distributionPoint: fullName (0) fullName: 1 item GeneralName: uniformResourceIdentifier (6) uniformResourceIdentifier: http://example.com:9292/crl/example.crl algorithmIdentifier (shaWithRSAEncryption) Algorithm Id: 1.2.840.113549.1.1.5 (shaWithRSAEncryption) Padding: 0 encrypted: ccb3a0a79dbca91c1d02331798d2cbed32c50bc409e1539e... Handshake Protocol: Client Key Exchange Handshake Type: Client Key Exchange (16) Length: 130
- 下記の dn のクライアント証明書を送信しています
- id-at-commonName=user03@example.org
- id-ce-extKeyUsage には id-kp-clientAuth を付けています
この後はサーバからの ChangeCipherSpec と Finished が続きます.
SSLv3 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec Content Type: Change Cipher Spec (20) Version: SSL 3.0 (0x0300) Length: 1 Change Cipher Spec Message SSLv3 Record Layer: Handshake Protocol: Encrypted Handshake Message Content Type: Handshake (22) Version: SSL 3.0 (0x0300) Length: 64 Handshake Protocol: Encrypted Handshake Message
有効ではないクライアント証明書による接続
ブラウザには SSL 接続 エラー と表示されました.
サーバは,クライアント証明書を検証して有効ではないと判定して ChangeCipherSpec, Finished ではなく,Alert をクライアントへ返しています.
TLSv1 Record Layer: Alert (Level: Fatal, Description: Certificate Expired) Content Type: Alert (21) Version: TLS 1.0 (0x0301) Length: 2 Alert Message Level: Fatal (2) Description: Certificate Expired (45)
今回は,有効期限が切れているクライアント証明書をサーバへ送ったため Certificate Expired がきちんと返ってきています.
所感
- Apache のクライアント認証の設定はそれほど難しくはない
- 証明書の管理ができれば,期限付きでアクセスする権限を与えることが簡単にできそう
- クライアント証明書を検証する CA 証明書は複数枚設定することが可能なので,ある程度いい加減な管理でも良さそう(CA の期限が切れる前に追加すればいいので)