はじめに
SPIRE では Node/Workload に対して、その Node/Workload の Identity となる SPIFFE ID が含まれた SVID を発行する機構があります。
Node Attestation を経て、Base SVID(SPIRE Agent が起動している Node に対して割り当てられる SVID)が Node に配布され、その Base SVID は SPIRE Agent が SPIRE Server に対して認証を行う際に利用され、認証に成功することで Workload Attestation の開始が可能になる流れは理解できていました。
しかし、Workload Attestation を経て、Workload に対して配布される SVID を使って行う Workload 間の認証(ないしは同じ PKIツリー 内のシステムとの認証)の流れを自分の中でイメージできていなかったので、今回はそれらの理解を深めるために SPIRE の仕様をおさらいしながら、Workload 間の認証の流れを整理していきたいと思います。
SVID を使った認証の流れをおさらい
Node/Workload Attestation に成功した Node/Workload は、自身の Identity となる SPIFFE ID が含まれた SVID と、それを検証するための Trust Bundle(SVID に署名を行った CA証明書)を取得することが可能になっています。
「Trust Bundle が SVID の検証に利用される」とは「Trust Bundle があることで通信相手となる Node/Workload の Identity である SPIFFE ID が信頼できるものか判断できる」ということになります。
そして、通信相手の SPIFFE ID がわかったところで、意図した通信相手であれば 認証OK という流れになるわけです。
openssl を使って手動で Workload の SVID の検証をやってみる
検証環境
spiffe/spire に含まれる Dockerイメージ を使って、コンテナでスタンドアローンな環境を構築して SVID の検証を行っていきます。なお、SPIRE のバージョンは 0.8.0 を利用します。
https://github.com/spiffe/spire/tree/0.8.0
前準備
以下に記載されている Walkthrough を最後まで実施して、ファイルとして X.509-SVID と Trust Bundle が作成できたら、前準備が完了となります。
https://github.com/spiffe/spire/blob/0.8.0/doc/SPIRE101.md
以下、例となります。
root@spire-dev:~/spire# mkdir certs
root@spire-dev:~/spire# su -c "./cmd/spire-agent/spire-agent api fetch x509 -write ./certs" workload
Received 1 bundle after 12.017658ms
SPIFFE ID: spiffe://example.org/workload
SVID Valid After: 2019-06-02 19:32:42 +0000 UTC
SVID Valid Until: 2019-06-02 20:32:20 +0000 UTC
Intermediate #1 Valid After: 2019-06-02 19:32:10 +0000 UTC
Intermediate #1 Valid Until: 2019-06-02 20:32:20 +0000 UTC
CA #1 Valid After: 2018-05-13 19:33:47 +0000 UTC
CA #1 Valid Until: 2023-05-12 19:33:47 +0000 UTC
Writing SVID #0 to file certs/svid.0.pem.
Writing key #0 to file certs/svid.0.key.
Writing bundle #0 to file certs/bundle.0.pem.
root@spire-dev:~/spire# ll certs/
total 12
drwxr-xr-x 5 root root 170 Jun 2 19:32 ./
drwxr-xr-x 44 root root 1496 Jun 2 19:32 ../
-rw-r--r-- 1 root root 684 Jun 2 19:32 bundle.0.pem
-rw-r--r-- 1 root root 241 Jun 2 19:32 svid.0.key
-rw-r--r-- 1 root root 1474 Jun 2 19:32 svid.0.pem
Node が取得した Base SVID
Base SVID( ./.data/agent_svid.der
) の証明書情報
Base SVID は X.509-SVID 形式となります。
openssl で Base SVID( ./.data/agent_svid.der
)の証明書情報を表示します。
Issuer, Subject, SAN(Subject Alternative Name) だけがわかれば良いので出力は一部抜粋しています。
root@spire-dev:~/spire# openssl x509 -text -noout -inform der -in ./.data/agent_svid.der
Certificate:
...
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
...
Subject: C=US, O=SPIRE
...
X509v3 extensions:
...
X509v3 Subject Alternative Name:
URI:spiffe://example.org/spire/agent/join_token/7287a190-f46f-45ed-b822-c13df57af498
...
全ての出力はこちら
root@spire-dev:~/spire# openssl x509 -text -noout -inform der -in ./.data/agent_svid.der
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
Validity
Not Before: Jun 2 19:32:27 2019 GMT
Not After : Jun 2 20:32:20 2019 GMT
Subject: C=US, O=SPIRE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:4d:94:1f:29:13:36:1f:64:7f:c4:28:c5:95:ec:
27:db:ee:57:92:c3:44:32:59:a1:33:cc:af:ac:eb:
74:f1:47:ac:75:ec:a9:af:1c:48:fc:cb:f5:2e:c7:
49:f2:88:02:e9:11:18:19:ca:5a:60:05:af:c3:3c:
7f:11:53:a5:e2
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
BE:19:33:D4:1D:9F:DD:92:0A:9B:33:C8:2E:00:4E:3F:EE:88:84:19
X509v3 Authority Key Identifier:
keyid:87:3C:F9:8B:43:80:8D:06:63:16:7A:EA:B2:10:D7:2B:4D:73:F4:A6
X509v3 Subject Alternative Name:
URI:spiffe://example.org/spire/agent/join_token/7287a190-f46f-45ed-b822-c13df57af498
Signature Algorithm: ecdsa-with-SHA384
30:66:02:31:00:d4:83:a4:08:cd:7f:73:31:d9:e9:49:b4:19:
ae:7f:d7:d3:61:56:56:90:76:17:d4:45:19:b2:74:f9:b9:51:
5f:b1:45:f2:db:cd:88:8a:ba:4b:e7:9f:c0:b2:9e:be:5b:02:
31:00:b9:b3:d4:97:72:f3:9b:c4:63:3b:08:ec:c6:e7:97:20:
24:55:7e:c7:d6:73:b8:96:ad:b2:f4:76:85:25:1b:11:32:ae:
0d:6b:0a:d6:5b:bf:5a:df:70:fe:56:0f:47:ee
Workload が取得した X.509-SVID
X.509-SVID( ./certs/svid.0.pem
) の実体
以下、2つのファイルで構成されていることがわかります。
- X.509-SVID(上)
- X.509-SVID を検証するための CA証明書(下)
"X.509-SVID を検証するための CA証明書" ですが、Walkthrough では PKIツリー における SPIRE Server の上段に ルートCA を配置する構成となっているので、UpstreamCA Plugin で指定した ルートCA によって署名された "中間CA証明書" となります。
https://github.com/spiffe/spire/blob/0.8.0/conf/server/server.conf#L38-L44
root@spire-dev:~/spire# cat ./certs/svid.0.pem
-----BEGIN CERTIFICATE-----
MIIB9TCCAXugAwIBAgIBBDAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UEChMGU1BJRkZFMB4XDTE5MDYwMjE5MzI0MloXDTE5MDYwMjIwMzIyMFowHTEL
MAkGA1UEBhMCVVMxDjAMBgNVBAoTBVNQSVJFMFkwEwYHKoZIzj0CAQYIKoZIzj0D
AQcDQgAEB6COJnwWjnZ25ZvLYm7m9K15F1t+6v+0Zs375BW9Ulbh3+gZ8ej5G+p+
pvHS+IsuMN/76Ukha2wfy9QBJymd8KOBqjCBpzAOBgNVHQ8BAf8EBAMCA6gwHQYD
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0O
BBYEFJYunZ7mxmetJ34QnAEg6d49o8nsMB8GA1UdIwQYMBaAFIc8+YtDgI0GYxZ6
6rIQ1ytNc/SmMCgGA1UdEQQhMB+GHXNwaWZmZTovL2V4YW1wbGUub3JnL3dvcmts
b2FkMAoGCCqGSM49BAMDA2gAMGUCMQCFeBWZzdiwJJCTZKZigS44Ymej23d9ozFZ
P8Q6jW1htyRpkHJyTZxv41+kGjqbyY4CMAiYZLlP3vrqN2sbpKY5dHiWCluKK4sn
stwQuxE5+qI767Ig5ZEQvBiA1f3IZa3izw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB7zCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UECgwGU1BJRkZFMB4XDTE5MDYwMjE5MzIxMFoXDTE5MDYwMjIwMzIyMFowHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAi
A2IABGHcciQK5m85Ukz9sDRbKoOpzt/6UVmXHl/Itb4U5OdgbsMglJUAuzqKX//x
geLV9mhlgoG3ZIYLrqGEwI9vUIGyhYIU/bsVTNN/iNKrev5mVmfP00b+sEptn4ZU
6iCW6qOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUhzz5i0OAjQZjFnrqshDXK01z9KYwHwYDVR0jBBgwFoAUh6XzV6LwNazA
+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYI
KoZIzj0EAwMDaQAwZgIxAMwETO7BX8ELJwWFFWctgzqqsdCnJwCB00201q+GvLPd
oYOcE6vqo7C+VNc8lhBwWAIxAPQSAoNUva4hTX31DRrtRC/3xhsXucMex91BWwzI
+ehylCfUCHN4BWNx9nliWoMCIA==
-----END CERTIFICATE-----
X.509-SVID( ./certs/svid.0.pem
) の証明書情報
openssl で X.509-SVID( ./certs/svid.0.pem
)の証明書情報を表示します。
Issuer, Subject, SAN(Subject Alternative Name) だけがわかれば良いので出力は一部抜粋しています。
root@spire-dev:~/spire# openssl crl2pkcs7 -nocrl -certfile ./certs/svid.0.pem | openssl pkcs7 -print_certs -text -noout
Certificate:
...
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
...
Subject: C=US, O=SPIRE
...
X509v3 extensions:
...
X509v3 Subject Alternative Name:
URI:spiffe://example.org/workload
...
Certificate:
...
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
...
Subject: C=US, O=SPIFFE
...
X509v3 extensions:
...
X509v3 Subject Alternative Name:
URI:spiffe://example.org
...
X.509-SVID の Issuer と 中間CA証明書 の Subject が同じことから、X.509-SVID は 中間CA証明書 から署名されていて PKIツリー における親子関係にある(openssl を使った厳格な検証はここから先の作業で実施)ことがわかります。また、SAN には SPIRE Server と Workload それぞれの SPIFFE ID が格納(SPIRE Server の SPIFFE ID は Trust Domain です)されていることがわかります。
Issuer と Subject が同じなので、中間CA証明書ではなく ルートCA証明書 なのでは?となりますが、Walkthrough で使われるルートCA証明書 の Subject と、SPIRE Server の config の Subject と同じなので、このような状況となっています。
- ルートCA証明書の Subject: https://github.com/spiffe/spire/blob/0.8.0/script/generate_dummy_ca.sh#L9
- 中間CA証明書の Subject: https://github.com/spiffe/spire/blob/0.8.0/conf/server/server.conf#L10-L14
全ての出力はこちら
root@spire-dev:~/spire# openssl crl2pkcs7 -nocrl -certfile ./certs/svid.0.pem | openssl pkcs7 -print_certs -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4 (0x4)
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
Validity
Not Before: Jun 2 19:32:42 2019 GMT
Not After : Jun 2 20:32:20 2019 GMT
Subject: C=US, O=SPIRE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:07:a0:8e:26:7c:16:8e:76:76:e5:9b:cb:62:6e:
e6:f4:ad:79:17:5b:7e:ea:ff:b4:66:cd:fb:e4:15:
bd:52:56:e1:df:e8:19:f1:e8:f9:1b:ea:7e:a6:f1:
d2:f8:8b:2e:30:df:fb:e9:49:21:6b:6c:1f:cb:d4:
01:27:29:9d:f0
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
96:2E:9D:9E:E6:C6:67:AD:27:7E:10:9C:01:20:E9:DE:3D:A3:C9:EC
X509v3 Authority Key Identifier:
keyid:87:3C:F9:8B:43:80:8D:06:63:16:7A:EA:B2:10:D7:2B:4D:73:F4:A6
X509v3 Subject Alternative Name:
URI:spiffe://example.org/workload
Signature Algorithm: ecdsa-with-SHA384
30:65:02:31:00:85:78:15:99:cd:d8:b0:24:90:93:64:a6:62:
81:2e:38:62:67:a3:db:77:7d:a3:31:59:3f:c4:3a:8d:6d:61:
b7:24:69:90:72:72:4d:9c:6f:e3:5f:a4:1a:3a:9b:c9:8e:02:
30:08:98:64:b9:4f:de:fa:ea:37:6b:1b:a4:a6:39:74:78:96:
0a:5b:8a:2b:8b:27:b2:dc:10:bb:11:39:fa:a2:3b:eb:b2:20:
e5:91:10:bc:18:80:d5:fd:c8:65:ad:e2:cf
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
Validity
Not Before: Jun 2 19:32:10 2019 GMT
Not After : Jun 2 20:32:20 2019 GMT
Subject: C=US, O=SPIFFE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:61:dc:72:24:0a:e6:6f:39:52:4c:fd:b0:34:5b:
2a:83:a9:ce:df:fa:51:59:97:1e:5f:c8:b5:be:14:
e4:e7:60:6e:c3:20:94:95:00:bb:3a:8a:5f:ff:f1:
81:e2:d5:f6:68:65:82:81:b7:64:86:0b:ae:a1:84:
c0:8f:6f:50:81:b2:85:82:14:fd:bb:15:4c:d3:7f:
88:d2:ab:7a:fe:66:56:67:cf:d3:46:fe:b0:4a:6d:
9f:86:54:ea:20:96:ea
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
87:3C:F9:8B:43:80:8D:06:63:16:7A:EA:B2:10:D7:2B:4D:73:F4:A6
X509v3 Authority Key Identifier:
keyid:87:A5:F3:57:A2:F0:35:AC:C0:F8:64:C4:54:E7:6E:D3:BA:39:C8:E8
X509v3 Subject Alternative Name:
URI:spiffe://example.org
Signature Algorithm: ecdsa-with-SHA384
30:66:02:31:00:cc:04:4c:ee:c1:5f:c1:0b:27:05:85:15:67:
2d:83:3a:aa:b1:d0:a7:27:00:81:d3:4d:b4:d6:af:86:bc:b3:
dd:a1:83:9c:13:ab:ea:a3:b0:be:54:d7:3c:96:10:70:58:02:
31:00:f4:12:02:83:54:bd:ae:21:4d:7d:f5:0d:1a:ed:44:2f:
f7:c6:1b:17:b9:c3:1e:c7:dd:41:5b:0c:c8:f9:e8:72:94:27:
d4:08:73:78:05:63:71:f6:79:62:5a:83:02:20
Workload が取得した Trust Bundle
Trust Bundle( ./certs/bundle.0.pem
) の実体
Trust Bundle の実体は、ルートCA証明書 となります。
root@spire-dev:~/spire# cat ./certs/bundle.0.pem
-----BEGIN CERTIFICATE-----
MIIBzDCCAVOgAwIBAgIJAJM4DhRH0vmuMAoGCCqGSM49BAMEMB4xCzAJBgNVBAYT
AlVTMQ8wDQYDVQQKDAZTUElGRkUwHhcNMTgwNTEzMTkzMzQ3WhcNMjMwNTEyMTkz
MzQ3WjAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMHYwEAYHKoZIzj0C
AQYFK4EEACIDYgAEWjB+nSGSxIYiznb84xu5WGDZj80nL7W1c3zf48Why0ma7Y7m
CBKzfQkrgDguI4j0Z+0/tDH/r8gtOtLLrIpuMwWHoe4vbVBFte1vj6Xt6WeE8lXw
cCvLs/mcmvPqVK9jo10wWzAdBgNVHQ4EFgQUh6XzV6LwNazA+GTEVOdu07o5yOgw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwGQYDVR0RBBIwEIYOc3Bp
ZmZlOi8vbG9jYWwwCgYIKoZIzj0EAwQDZwAwZAIwE4Me13qMC9i6Fkx0h26y09QZ
IbuRqA9puLg9AeeAAyo5tBzRl1YL0KNEp02VKSYJAjBdeJvqjJ9wW55OGj1JQwDF
D7kWeEB6oMlwPbI/5hEY3azJi16I0uN1JSYTSWGSqWc=
-----END CERTIFICATE-----
Trust Bundle( ./certs/bundle.0.pem
) の証明書情報
openssl で Trust Bundle( ./certs/bundle.0.pem
)の証明書情報を表示します。
Issuer, Subject, SAN(Subject Alternative Name) だけがわかれば良いので出力は一部抜粋しています。
root@spire-dev:~/spire# openssl x509 -text -noout -in ./certs/bundle.0.pem
Certificate:
...
Signature Algorithm: ecdsa-with-SHA512
Issuer: C=US, O=SPIFFE
...
Subject: C=US, O=SPIFFE
...
X509v3 extensions:
...
X509v3 Subject Alternative Name:
URI:spiffe://local
...
Issuer と Subject が同じことから、Trust Bundle は ルートCA証明書 であることがわかります。
全ての出力はこちら
root@spire-dev:~/spire# openssl x509 -text -noout -in ./certs/bundle.0.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 10608244402538346926 (0x93380e1447d2f9ae)
Signature Algorithm: ecdsa-with-SHA512
Issuer: C=US, O=SPIFFE
Validity
Not Before: May 13 19:33:47 2018 GMT
Not After : May 12 19:33:47 2023 GMT
Subject: C=US, O=SPIFFE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:5a:30:7e:9d:21:92:c4:86:22:ce:76:fc:e3:1b:
b9:58:60:d9:8f:cd:27:2f:b5:b5:73:7c:df:e3:c5:
a1:cb:49:9a:ed:8e:e6:08:12:b3:7d:09:2b:80:38:
2e:23:88:f4:67:ed:3f:b4:31:ff:af:c8:2d:3a:d2:
cb:ac:8a:6e:33:05:87:a1:ee:2f:6d:50:45:b5:ed:
6f:8f:a5:ed:e9:67:84:f2:55:f0:70:2b:cb:b3:f9:
9c:9a:f3:ea:54:af:63
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Subject Key Identifier:
87:A5:F3:57:A2:F0:35:AC:C0:F8:64:C4:54:E7:6E:D3:BA:39:C8:E8
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Alternative Name:
URI:spiffe://local
Signature Algorithm: ecdsa-with-SHA512
30:64:02:30:13:83:1e:d7:7a:8c:0b:d8:ba:16:4c:74:87:6e:
b2:d3:d4:19:21:bb:91:a8:0f:69:b8:b8:3d:01:e7:80:03:2a:
39:b4:1c:d1:97:56:0b:d0:a3:44:a7:4d:95:29:26:09:02:30:
5d:78:9b:ea:8c:9f:70:5b:9e:4e:1a:3d:49:43:00:c5:0f:b9:
16:78:40:7a:a0:c9:70:3d:b2:3f:e6:11:18:dd:ac:c9:8b:5e:
88:d2:e3:75:25:26:13:49:61:92:a9:67
openssl を使って手動で Workload の X.509-SVID の検証をやってみる
Workload が取得した X.509-SVID と Trust Bundle を使って、X.509-SVID の検証を行っていきます。
まず、検証を行う前に X.509-SVID と 中間CA証明書 が一緒になっていると困るので、以下のコマンドで分割します。
awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > c }' < ./certs/svid.0.pem
mv 1 ./certs/svid.pem
mv 2 ./certs/intermediate_ca.pem
次に 中間CA証明書 と ルートCA証明書 を1つの証明書バンドルにします。
cat ./certs/intermediate_ca.pem ./certs/bundle.0.pem > ./certs/ca_bundle.pem
完成したファイルはこちら。
# X.509-SVID
root@spire-dev:~/spire# cat ./certs/svid.pem
-----BEGIN CERTIFICATE-----
MIIB9TCCAXugAwIBAgIBBDAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UEChMGU1BJRkZFMB4XDTE5MDYwMjE5MzI0MloXDTE5MDYwMjIwMzIyMFowHTEL
MAkGA1UEBhMCVVMxDjAMBgNVBAoTBVNQSVJFMFkwEwYHKoZIzj0CAQYIKoZIzj0D
AQcDQgAEB6COJnwWjnZ25ZvLYm7m9K15F1t+6v+0Zs375BW9Ulbh3+gZ8ej5G+p+
pvHS+IsuMN/76Ukha2wfy9QBJymd8KOBqjCBpzAOBgNVHQ8BAf8EBAMCA6gwHQYD
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0O
BBYEFJYunZ7mxmetJ34QnAEg6d49o8nsMB8GA1UdIwQYMBaAFIc8+YtDgI0GYxZ6
6rIQ1ytNc/SmMCgGA1UdEQQhMB+GHXNwaWZmZTovL2V4YW1wbGUub3JnL3dvcmts
b2FkMAoGCCqGSM49BAMDA2gAMGUCMQCFeBWZzdiwJJCTZKZigS44Ymej23d9ozFZ
P8Q6jW1htyRpkHJyTZxv41+kGjqbyY4CMAiYZLlP3vrqN2sbpKY5dHiWCluKK4sn
stwQuxE5+qI767Ig5ZEQvBiA1f3IZa3izw==
-----END CERTIFICATE-----
# 証明書バンドル
root@spire-dev:~/spire# cat ./certs/ca_bundle.pem
-----BEGIN CERTIFICATE-----
MIIB7zCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UECgwGU1BJRkZFMB4XDTE5MDYwMjE5MzIxMFoXDTE5MDYwMjIwMzIyMFowHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAi
A2IABGHcciQK5m85Ukz9sDRbKoOpzt/6UVmXHl/Itb4U5OdgbsMglJUAuzqKX//x
geLV9mhlgoG3ZIYLrqGEwI9vUIGyhYIU/bsVTNN/iNKrev5mVmfP00b+sEptn4ZU
6iCW6qOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUhzz5i0OAjQZjFnrqshDXK01z9KYwHwYDVR0jBBgwFoAUh6XzV6LwNazA
+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYI
KoZIzj0EAwMDaQAwZgIxAMwETO7BX8ELJwWFFWctgzqqsdCnJwCB00201q+GvLPd
oYOcE6vqo7C+VNc8lhBwWAIxAPQSAoNUva4hTX31DRrtRC/3xhsXucMex91BWwzI
+ehylCfUCHN4BWNx9nliWoMCIA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBzDCCAVOgAwIBAgIJAJM4DhRH0vmuMAoGCCqGSM49BAMEMB4xCzAJBgNVBAYT
AlVTMQ8wDQYDVQQKDAZTUElGRkUwHhcNMTgwNTEzMTkzMzQ3WhcNMjMwNTEyMTkz
MzQ3WjAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMHYwEAYHKoZIzj0C
AQYFK4EEACIDYgAEWjB+nSGSxIYiznb84xu5WGDZj80nL7W1c3zf48Why0ma7Y7m
CBKzfQkrgDguI4j0Z+0/tDH/r8gtOtLLrIpuMwWHoe4vbVBFte1vj6Xt6WeE8lXw
cCvLs/mcmvPqVK9jo10wWzAdBgNVHQ4EFgQUh6XzV6LwNazA+GTEVOdu07o5yOgw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwGQYDVR0RBBIwEIYOc3Bp
ZmZlOi8vbG9jYWwwCgYIKoZIzj0EAwQDZwAwZAIwE4Me13qMC9i6Fkx0h26y09QZ
IbuRqA9puLg9AeeAAyo5tBzRl1YL0KNEp02VKSYJAjBdeJvqjJ9wW55OGj1JQwDF
D7kWeEB6oMlwPbI/5hEY3azJi16I0uN1JSYTSWGSqWc=
-----END CERTIFICATE-----
最後に openssl コマンドで X.509-SVID の検証を行います。
root@spire-dev:~/spire# openssl verify -CAfile ./certs/ca_bundle.pem ./certs/svid.pem
./certs/svid.pem: OK
X.509-SVID の検証に成功したので、この X.509-SVID に含まれる SPIFFE ID spiffe://example.org/workload
が信頼できることがわかりました。あとはその SPIFFE ID に対応する Workload が意図した通信相手かどうかをチェックする認証処理を行えば良いというわけです。
X.509-SVID であれ、JWT-SVID であれ、別の Workload と通信を行う際にリクエストと一緒に渡してクライアント認証を行う流れですね。
root@spire-dev:~/spire# openssl x509 -text -noout -in ./certs/svid.pem
Certificate:
...
Signature Algorithm: ecdsa-with-SHA384
...
X509v3 extensions:
...
X509v3 Subject Alternative Name:
URI:spiffe://example.org/workload
...
ここまでやって気付いたのですが、これ普通に TLS のクライアント認証ですね...。
なんか悲しい終わり方になりました...。
補足
SPIRE 0.8.0 以前のバージョンでは Trust Bundle は ルートCA証明書 と 中間CA証明書 で構成されていたのですが、0.8.0 で 中間CA証明書 が取り除かれて、Trust Bundle は本来の形である ルートCA証明書 のみとなったようです。
どのような経緯があったのか知りたい方は以下を参照ください。
0.7.1 で 0.6.x との互換性を保つために 中間CA証明書 が Trust Bundle に含まれるようになった。
0.8.0 で Trust Bundle が ルートCA証明書 のみの本来の形に戻った。
このままじゃ終われない...。
時間を掛けて書いた記事が悲しい終わり方になるのは辛すぎるので、ソースコードを眺めて SPIRE Server が SPIRE Agent から渡される Base SVID を使って、どのように認可を行うのかを追いかけていきたいと思います。
こちらはもう自己満足でしかないので興味あればどうぞ
Node Attestatin が完了して Node に SVID と Key と Trust Bundle が配布されるまで
spire-agent run
が開始される。
https://github.com/spiffe/spire/blob/0.8.0/cmd/spire-agent/main.go#L9-L11
https://github.com/spiffe/spire/blob/0.8.0/cmd/spire-agent/cli/cli.go#L32-L34
Node Attestation が開始される。
https://github.com/spiffe/spire/blob/0.8.0/cmd/spire-agent/cli/run/run.go#L113
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/agent.go#L66 (ここの直前で各 Plugins をロードする)
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/agent.go#L143-L156
ここまでは前処理でここからが Node Attestation の実処理。
ここの処理で Trust Bundle と SVID などの生成を行っている。SVID は X.509-SVID 固定の様子。
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/attestor/node/node.go#L61-L80
Node Attestation に成功したら、Cache Manager が Node のファイルシステムに SVID と Key と Trust Bundle が書き込み、SPIRE Server と通信して Registration Entry の同期を行う。
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/agent.go#L71
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/agent.go#L177
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/manager/manager.go#L81-L91
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/manager/sync.go#L26-L78
全ての処理が完了したら SPIRE Agent が起動する。
https://github.com/spiffe/spire/blob/0.8.0/pkg/agent/agent.go#L78-L82
SPIRE Server が SPIRE Agent から渡される Base SVID を使って認可を行う処理
spire-server run
で SPIRE Server が起動するまでの処理。
https://github.com/spiffe/spire/blob/0.8.0/cmd/spire-server/main.go#L10
https://github.com/spiffe/spire/blob/0.8.0/cmd/spire-server/cli/run/run.go#L126
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/server.go#L106-L201
SPIRE Server 起動中は、内部では SPIRE Agent と通信するための gRPC サーバーが起動し続けている状態。
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/server.go#L194
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/endpoints.go#L52
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/endpoints.go#L60
そして、その gRPC サーバーに対して SPIRE Agent がリクエストを行う際には認可の処理がなされる。
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/endpoints.go#L80
https://github.com/spiffe/spire/blob/0.8.0/pkg/common/auth/interceptors.go#L29-L39
どのように認可の処理が行われるかを追いかけていく。
https://github.com/spiffe/spire/blob/0.8.0/pkg/common/auth/interceptors.go#L46
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/node/handler.go#L386-L426
SPIRE Agent が Workload API を介して X.509-SVID, JWT-SVID を取得しようとすると、SPIRE Server が Base SVID のバリデーションを開始する。バリデーションは X.509-SVID 形式である Base SVID から SPIFFE ID を取得して、Attested Node の一覧に照合をかけるだけ。
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/node/handler.go#L391-L405
https://github.com/spiffe/spire/blob/0.8.0/pkg/server/endpoints/node/handler.go#L447-L480
認可の処理に成功することで、Workload は SVID を取得することが可能になる。
まとめ
Workload が SVID を得た後は、別の Workload に対して X.509証明書 または JWT を使ってクライアント認証を行い、リクエストを受けた Workload は SPIFFE ID の照合を行うことで意図した通信相手であるか確認ができるということがわかりました。あとは SPIFFE ID の照合までは行わずとも、SPIRE の Use cases にあるように同じ PKIツリー の中に属すシステム(e.g. Vault, Pinterest Knox)に対する認証に使用したりかなと思います。
当初自分が想定していた内容に比べて薄い内容となってしまい、少し残念な感じはありましたが、SVID の良い復習になったのと、ソースコードを追って少しだけ実処理を理解できたことは良かったかなと思っています。また、この記事を書き上げる中で spiffe/spire に PR を 2つ(#940, #941)投げることが出来たので、結果オーライだと思いたいです...!!!
今後も SPIRE を地道にやっていこうと思います、おしまい。
参考資料
- Trust Bundle の利用用途に関して
- openssl のチートシート
- openssl で証明書バンドル内のすべての証明書情報を表示する方法
- 証明書バンドルを分割する方法