Carpe Diem

備忘録

HashiCorp VaultのPKI(公開鍵基盤)でルート証明書・中間証明書・サーバ証明書を発行

概要

HashiCorp VaultにはPKI(公開鍵基盤)の機能もあります。
これを使って

  • ルートCA
  • 中間CA

を用意し、

を作成します。

環境

  • Vault 0.10.3

ルートCA〜サーバ証明書について

TLS周りの知識がフワフワしてる方はまずこちらをどうぞ

christina04.hatenablog.com

VaultでPKI

ルートCA

pkiをマウント

では実際にVaultでPKIを構築します。pkiを有効化します。

$ vault secrets enable -path=pki_root pki
Success! Enabled the pki secrets engine at: pki_root/

デフォルトのTTLは30日と短いので、1年に延長します。

$ vault secrets tune -max-lease-ttl=8760h pki_root
Success! Tuned the secrets engine at: pki_root/

ルート証明書の作成

ルートCA及びルート証明書を作成します。

$ vault write pki_root/root/generate/internal \
    common_name="My Root CA" \
    ttl=8760h

Key              Value
---              -----
certificate      -----BEGIN CERTIFICATE-----
MIIDGzCCAgOgAwIBAgIUNI6RFfJRnwlrIb+nq6jqOtmZE+cwDQYJKoZIhvcNAQEL
...
K/5o1Pw6oA0tPt+z0jrfwB7ySVppTJCX9c/tm1Ceng==
-----END CERTIFICATE-----
expiration       1563294645
issuing_ca       -----BEGIN CERTIFICATE-----
MIIDGzCCAgOgAwIBAgIUNI6RFfJRnwlrIb+nq6jqOtmZE+cwDQYJKoZIhvcNAQEL
...
K/5o1Pw6oA0tPt+z0jrfwB7ySVppTJCX9c/tm1Ceng==
-----END CERTIFICATE-----
serial_number    34:8e:91:15:f2:51:9f:09:6b:21:bf:a7:ab:a8:ea:3a:d9:99:13:e7

ルートCAの証明書は自己証明書なので、certificateissuing_caが同じになります。

証明書の確認

BEGIN CERTIFICATEEND CERTIFICATEroot.crtというファイルに保存してopensslで検証します。

$ openssl x509 -in root.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            34:8e:91:15:f2:51:9f:09:6b:21:bf:a7:ab:a8:ea:3a:d9:99:13:e7
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=My Root CA
        Validity
            Not Before: Jul 16 16:30:15 2018 GMT
            Not After : Jul 16 16:30:45 2019 GMT
        Subject: CN=My Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9f:a1:f4:5a:ce:91:cd:ce:04:b4:cc:a9:5e:5d:
                    a0:1c:2f:e0:17:ac:8a:f7:e1:05:38:2d:8a:fe:14:
                    b5:e6:1a:06:b8:cb:74:5b:90:08:76:ae:ec:0d:54:
                    ec:ba:96:30:72:b0:81:78:16:21:60:e9:8d:9d:97:
...

CN(Common Name)が設定されているっことが確認できます。
また自己証明書なのでIssuerSubjectが同じになっています。

各URLの設定

issuing certificate endpointsCRL distribution pointsを設定します。
ルートCAのVaultサーバのドメインを指定します。

$ vault write pki_root/config/urls \
    issuing_certificates="http://root-ca.vault.com:8200/v1/pki/ca" \
    crl_distribution_points="http://root-ca.vault.com:8200/v1/pki/crl"

中間CA

同じ要領で中間CAを用意していきます。

$ vault secrets enable -path=pki_int pki
Success! Enabled the pki secrets engine at: pki_int/

期限を延ばします。ルートCAの半分にしておきます。

$ vault secrets tune -max-lease-ttl=4380h pki_int
Success! Tuned the secrets engine at: pki_int/

CSR(証明書リクエスト)の作成

$ vault write pki_int/intermediate/generate/internal \
    common_name="Intermediate Authority" \
    ttl=4380h

Key    Value
---    -----
csr    -----BEGIN CERTIFICATE REQUEST-----
MIICZjCCAU4CAQAwITEfMB0GA1UEAxMWSW50ZXJtZWRpYXRlIEF1dGhvcml0eTCC
...
gH09CamC/4dEShn91Brd/iOW82n/49f7YsWoMsrKzpfwQJhjUCJBbUni
-----END CERTIFICATE REQUEST-----

CSRをルートCAに署名してもらって中間証明書を作成

先程のValueinter.csrとして保存します。

$ vault write pki_root/root/sign-intermediate \
    csr=@inter.csr \
    format=pem_bundle

Key              Value
---              -----
certificate      -----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIUd9XKLsmrIoOZpVVyddV4kklfMucwDQYJKoZIhvcNAQEL
...
+wRayg5fLCsFbkMxUJAAErb+1w==
-----END CERTIFICATE-----
expiration       1534525389
issuing_ca       -----BEGIN CERTIFICATE-----
MIIDGzCCAgOgAwIBAgIUNI6RFfJRnwlrIb+nq6jqOtmZE+cwDQYJKoZIhvcNAQEL
...
K/5o1Pw6oA0tPt+z0jrfwB7ySVppTJCX9c/tm1Ceng==
-----END CERTIFICATE-----
serial_number    77:d5:ca:2e:c9:ab:22:83:99:a5:55:72:75:d5:78:92:49:5f:32:e7

今度はcertificateは中間CAのものですが、issuing_caはルートCAのものだと分かります。

証明書の確認

$ openssl x509 -in inter.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            77:d5:ca:2e:c9:ab:22:83:99:a5:55:72:75:d5:78:92:49:5f:32:e7
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=My Root CA
        Validity
            Not Before: Jul 16 17:02:39 2018 GMT
            Not After : Aug 17 17:03:09 2018 GMT
        Subject: CN=Intermediate Authority
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c5:33:1f:5d:9f:7d:08:cd:27:e6:00:e5:6a:7b:
                    e3:d3:99:fc:a2:03:b1:f4:a4:67:c5:2a:b1:1c:4a:
...
            Authority Information Access: 
                CA Issuers - URI:http://root-ca.vault.com:8200/v1/pki/ca

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://root-ca.vault.com:8200/v1/pki/crl
...

Subjectは中間CAで、IssuerがルートCAだと分かります。
またルートCAのCRLのアドレスなども記載されています。

中間証明書の登録

ルートCAに署名してもらったので中間証明書を登録します。これ以降サーバ証明書の発行が可能となります。

$ vault write pki_int/intermediate/set-signed certificate=@inter.crt
Success! Data written to: pki_int/intermediate/set-signed

各URLの設定

issuing certificate endpointsCRL distribution pointsを設定します。
中間CAのVaultサーバのドメインを指定します。

$ vault write pki_int/config/urls \
    issuing_certificates="http://inter-ca.vault.com:8200/v1/pki/ca" \
    crl_distribution_points="http://inter-ca.vault.com:8200/v1/pki/crl"

サーバ証明書

ロールの作成

最後にサーバ証明書を発行します。

中間CAでロールを用意します。例としてexample.comを使っていますが、自分のドメインにしてください。
allow_subdomainsサブドメインを許可しています。

$ vault write pki_int/roles/example-dot-com \
    allowed_domains=example.com \
    allow_subdomains=true max_ttl=72h

サーバ証明書の作成

example.comサブドメインをOKにしたので、www.example.comサーバ証明書を作成します。

$ vault write pki_int/issue/example-dot-com \
    common_name=www.example.com

Key                 Value
---                 -----
ca_chain            [-----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIUd9XKLsmrIoOZpVVyddV4kklfMucwDQYJKoZIhvcNAQEL
...
+wRayg5fLCsFbkMxUJAAErb+1w==
-----END CERTIFICATE-----]
certificate         -----BEGIN CERTIFICATE-----
MIID3DCCAsSgAwIBAgIUBhstXQzjn/12ZTgomdDqeTD/hn8wDQYJKoZIhvcNAQEL
...
R7xrTmNE/aGiRJ0H6uvbPW8Lwb/b7UhRO1rfGymf7wM=
-----END CERTIFICATE-----
issuing_ca          -----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIUd9XKLsmrIoOZpVVyddV4kklfMucwDQYJKoZIhvcNAQEL
...
+wRayg5fLCsFbkMxUJAAErb+1w==
-----END CERTIFICATE-----
private_key         -----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxiL4/O5Ajx11IGXRC/jnqIacfFWobq9qDudtO+9mhiovnFoB
...
m1/8UrALKZK6dYAAwoLB/pZexzzN+fpQYjVRzAaMyzRW8jOEMZaI9g==
-----END RSA PRIVATE KEY-----
private_key_type    rsa
serial_number       06:1b:2d:5d:0c:e3:9f:fd:76:65:38:28:99:d0:ea:79:30:ff:86:7f

certificateサーバ証明書です。issuing_caca_chainは中間証明書です。
private_keyサーバ証明書秘密鍵です。サーバ証明書・中間証明書と一緒にサーバにインストールします。

証明書の確認

$ openssl x509 -in server.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            06:1b:2d:5d:0c:e3:9f:fd:76:65:38:28:99:d0:ea:79:30:ff:86:7f
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Intermediate Authority
        Validity
            Not Before: Jul 16 17:45:23 2018 GMT
            Not After : Jul 19 17:45:52 2018 GMT
        Subject: CN=www.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c6:22:f8:fc:ee:40:8f:1d:75:20:65:d1:0b:f8:
                    e7:a8:86:9c:7c:55:a8:6e:af:6a:0e:e7:6d:3b:ef:
...
            Authority Information Access: 
                CA Issuers - URI:http://inter-ca.vault.com:8200/v1/pki/ca

            X509v3 Subject Alternative Name: 
                DNS:www.example.com
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://inter-ca.vault.com:8200/v1/pki/crl
...

Subjectはサーバドメインwww.example.comで、Issuerが中間CAだと分かります。
また中間CAのCRLのアドレスなども記載されています。

証明書のRevokeとCRL

証明書の秘密鍵が漏れたり、間違って発行されたといったときのためにRevokeがあります。
そしてRevokeするとCRLのリストに載ります。

試しに中間CAの秘密鍵が漏れたと仮定して、中間証明書をrevokeしてみます。
証明書の指定にはserial_numberを使います。

$ vault write pki_root/revoke serial_number=77:d5:ca:2e:c9:ab:22:83:99:a5:55:72:75:d5:78:92:49:5f:32:e7
Key                        Value
---                        -----
revocation_time            1531763765
revocation_time_rfc3339    2018-07-16T17:56:05.593925043Z

CRLを確認します。

$ vault read pki_root/cert/crl
Key                Value
---                -----
certificate        -----BEGIN X509 CRL-----
MIIBrDCBlQIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpNeSBSb290IENB
Fw0xODA3MTYxNzU2MDVaFw0xODA3MTkxNzU2MDVaMCcwJQIUd9XKLsmrIoOZpVVy
ddV4kklfMucXDTE4MDcxNjE3NTYwNVqgIzAhMB8GA1UdIwQYMBaAFNzNSXr5Mk0H
++90n4tK2dvYeN81MA0GCSqGSIb3DQEBCwUAA4IBAQCclh1G1A0qh1s/To5yTpxE
Q8xVftUe6a5wy0tBlaTW7diPBqxnN0wqgMg1BacOF31kVwLYaml0pOArjYKlgCVn
feHltYcDkvmMTpaOmI3Bw5UUHv82v7U85S6XwjVh+8wTXZoVLbuCKcGzj0aaWkYh
bUdCon2drH38nbOQOJ5DwW05uFUs80fJSYMEbq654puOgrsZDaOX4yBsTn+nuGkN
dkuJYu6b2Z3hdvSN1qGu4OtPAJ7UhgrzNXHcS5KEVys11TDgR8uaudwyx7wISFGH
1TRW7PyWthlpPLAjqlWHhveOmImnGu+IKmWPfSu8GeCZ0zZyG5svZYjJ1t9Z4tKK
-----END X509 CRL-----
revocation_time    0

中身をroot.crlとし、opensslコマンドで中身を確認します。

$ openssl crl -in root.crl -text 
Certificate Revocation List (CRL):
        Version 2 (0x1)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: /CN=My Root CA
        Last Update: Jul 16 17:56:05 2018 GMT
        Next Update: Jul 19 17:56:05 2018 GMT
        CRL extensions:
            X509v3 Authority Key Identifier: 
                keyid:DC:CD:49:7A:F9:32:4D:07:FB:EF:74:9F:8B:4A:D9:DB:D8:78:DF:35

Revoked Certificates:
    Serial Number: 77D5CA2EC9AB228399A5557275D57892495F32E7
        Revocation Date: Jul 16 17:56:05 2018 GMT
    Signature Algorithm: sha256WithRSAEncryption
         9c:96:1d:46:d4:0d:2a:87:5b:3f:4e:8e:72:4e:9c:44:43:cc:
         55:7e:d5:1e:e9:ae:70:cb:4b:41:95:a4:d6:ed:d8:8f:06:ac:
         67:37:4c:2a:80:c8:35:05:a7:0e:17:7d:64:57:02:d8:6a:69:

確かにRevokeされていることが確認できました。
ちなみに1つもない場合はNo Revoked Certificates.と表示されます。

クライアントは定期的にこのCRLをダウンロードし、妥当なサーバなのか、revokeされたサーバかどうかをチェックします。
今回だと中間証明書自体がrevokeされたので、この中間CAで発行された全てのサーバ証明書が失効することになります。

まとめ

VaultのPKIを使って各種証明書を発行しました。

ソース