はじめに
今回は、Amazon EC2 インスタンスに SPIRE Server を構築した後に、SPIRE Agent を起動した別インスタンスから Node Attestation を行い、最後にそのインスタンス上で Workload(UNIX系OSで動作するプロセスを例として使います)を起動して Workload Attesttion を行うまでの一連の流れを説明していきたいと思います。SPIRE は 2019年4月23日現在の最新バージョン である 0.7.3
を利用します。
注意事項ですが、当記事では SPIFFE/SPIRE に関する詳細な説明は割愛します。SPIFFE/SPIRE が初めての方は、当記事をご覧頂く前に以下の記事に目を通して頂くと理解が進むかと思います。
上記に加えて、2019-05-14 (火) SPIFFFE Meetup Tokyo #1 で発表された内容も SPIFFE/SPIRE の理解を深めるのに非常に有用なので参考までにどうぞ。
環境構築
まず初めに環境構築を行います。
EC2インスタンスの起動と IAM User の作成
EC2インスタンスの起動
Ubuntu 16.04 のインスタンスを2台起動します。VPC、プライベートIP、リージョン、インスタンスタイプ、セキュリティグループなど、細かな設定は自由に設定して下さい。また、インスタンスを起動した後に ping
などで、各インスタンス同士で通信が行えることを確認しておいてください。
ホスト名 | プライベートIP | タグ | 起動させるもの |
---|---|---|---|
spire-server | 172.31.17.242 | name:spire-server | SPIRE Server |
spire-agent | 172.31.17.235 | name:spire-agent | SPIRE Agent |
ここからの説明では、各インスタンスを指す際に「 spire-server
ホストで ○○ を XX します」のようにホスト名を使います。説明しやすいようにホスト名をカスタムしておりますが、デフォルトの ip-xxx-xxx-xxx-xxx
のままでも問題はありません。
IAM User の作成
SPIRE Server の Node Attester Plugin "aws_iid" と Node Resolver Plugin "aws_iid" の設定を行う際に、各 Plugin が AWS に接続してインスタンス情報を取得するために Access Keys が必要となるので、各 Plugin のドキュメントに記載されている必要なポリシーを満たす IAM User の作成を行います。
Node Attester Plugin "aws_iid" に設定する IAM User のポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
}
Node Resolver Plugin "aws_iid" に設定する IAM User のポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"iam:GetInstanceProfile"
],
"Resource": "*"
}
]
}
上記のポリシーを持つ IAM User の作成時に表示される Access Keys は、設定時に使うのでメモしておいてください。
SPIRE Server の構築
spire-server
コマンドのインストール
spire-server
ホストに ubuntu ユーザーで接続してください。
ssh -i /path/to/key ubuntu@spire-server
SPIRE の Release をダウンロードして、中身を /opt/spire
に展開します。
※ 2019年4月23日現在の最新バージョン である 0.7.3
を利用
wget https://github.com/spiffe/spire/releases/download/0.7.3/spire-0.7.3-linux-x86_64-glibc.tar.gz
tar xf spire-0.7.3-linux-x86_64-glibc.tar.gz
sudo cp -r spire-0.7.3/. /opt/spire
spire-server
コマンドが使えるように /usr/local/bin 直下に symlink を作成します。
sudo ln -s /opt/spire/spire-server /usr/local/bin/spire-server
spire-server
コマンドが使えることを確認できたら OK です。
ubuntu@spire-server:~$ spire-server --version
0.7.3
sqlite3
コマンドのインストール
SPIRE Server の起動には不要ですが、説明の中で SQLite の中身を参照するのでインストールを行います。
apt-get
で sqlite3
をインストールします。
sudo apt-get update
sudo apt-get install -y sqlite3
sqlite3
コマンドが使えることを確認できたら OK です。
ubuntu@spire-server:~$ sqlite3 --version
3.11.0 2016-02-15 17:29:24 3d862f207e3adc00f78066799ac5a8c282430a5f
SPIRE Server で利用する Plugins の選定
Plugin Type | 利用するもの | 備考 |
---|---|---|
DataStore | sql | データベースには sqllite3 を設定 |
NodeAttestor | aws_iid | AWS Instance Identity document を使って Node の正当性を証明する |
NodeResolver | aws_iid | AWS Instance Identity document を使って Node の正当性を証明する |
KeyManager | disk |
memory だと確認が大変なので disk に書くように設定 |
UpstreamCA | disk | SPIRE Server 自体を RootCA とする設定 |
設定ファイルの準備
/opt/spire/conf/server/server.conf
の内容を以下に変更します。
- trust domain はデフォルトの
example.org
を利用 -
access_key_id
とsecret_access_key
を IAM User 作成時にメモしたものに変更すること - UpstreamCA Plugin で利用する CAキー と CA証明書 は SPIRE の Release に含まれているものを使用
※ SPIRE Server の設定の詳細は こちら を参照下さい
server {
bind_address = "0.0.0.0"
bind_port = "8081"
registration_uds_path = "/var/run/spire/spire-registration.sock"
trust_domain = "example.org"
data_dir = "/opt/spire/data"
log_level = "DEBUG"
upstream_bundle = true
svid_ttl = "1h"
ca_subject = {
Country = ["US"],
Organization = ["SPIFFE"],
CommonName = "",
}
}
plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/opt/spire/data/sqlite/datastore.sqlite3"
}
}
NodeAttestor "aws_iid" {
plugin_data {
access_key_id = "xxx"
secret_access_key = "xxx"
}
}
NodeResolver "aws_iid" {
plugin_data {
access_key_id = "xxx"
secret_access_key = "xxx"
}
}
KeyManager "disk" {
plugin_data = {
keys_path = "/opt/spire/data/keys"
}
}
UpstreamCA "disk" {
plugin_data {
ttl = "1h"
key_file_path = "/opt/spire/conf/server/dummy_upstream_ca.key"
cert_file_path = "/opt/spire/conf/server/dummy_upstream_ca.crt"
}
}
}
SPIRE Server の起動
起動に必要なディレクトリを作成します。
sudo mkdir -p /opt/spire/data/sqlite
sudo mkdir -p /var/run/spire
ログは標準出力に吐くようにして、フォアグラウンドでプロセスを起動します。
sudo spire-server run -config /opt/spire/conf/server/server.conf
起動時のログから、各 Plugin の初期化が行われていることがわかります。
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
WARN[0000] Current umask 0022 is too permissive; setting umask 0027.
INFO[0000] data directory: "/opt/spire/data"
INFO[0000] Starting plugin catalog subsystem_name=catalog
DEBU[0000] UpstreamCA(disk): configuring plugin subsystem_name=catalog
DEBU[0000] DataStore(sql): configuring plugin subsystem_name=catalog
INFO[0000] initializing database.
DEBU[0000] NodeAttestor(aws_iid): configuring plugin subsystem_name=catalog
DEBU[0000] NodeResolver(aws_iid): configuring plugin subsystem_name=catalog
DEBU[0000] KeyManager(disk): configuring plugin subsystem_name=catalog
INFO[0000] plugins started
DEBU[0000] Keypair set "A" does not exist subsystem_name=ca_manager
DEBU[0000] Keypair set "B" does not exist subsystem_name=ca_manager
DEBU[0000] Loaded keypair sets subsystem_name=ca_manager
DEBU[0000] Preparing keypair set "A" subsystem_name=ca_manager
DEBU[0000] Keypair set "A" will expire 2019-04-22T15:06:07Z subsystem_name=ca_manager
DEBU[0000] Activating keypair set "A" subsystem_name=ca_manager
DEBU[0000] Rotating server SVID subsystem_name=svid_rotator
DEBU[0000] Signed x509 SVID "spiffe://example.org/spire/server" (expires 2019-04-22T15:06:07Z) subsystem_name=ca_manager
DEBU[0000] Initializing API endpoints subsystem_name=endpoints
INFO[0000] Starting TCP server on [::]:8081 subsystem_name=endpoints
INFO[0000] Starting UDS server /var/run/spire/spire-registration.sock subsystem_name=endpoints
Registration API が UNIXドメインソケット で LISTEN を開始したことが確認できます。
ubuntu@spire-server:~$ ls -l /var/run/spire/spire-registration.sock
srwxrwx--- 1 root root 0 Apr 22 14:06 /var/run/spire/spire-registration.sock
データディレクトリには、以下のファイルが作成されます。
ubuntu@spire-server:~$ sudo ls -lR /opt/spire/data
/opt/spire/data:
total 12
-rw-r----- 1 root root 1557 Apr 22 14:06 certs.json
-rw-r----- 1 root root 489 Apr 22 14:06 keys
drwxr-xr-x 2 root root 4096 Apr 22 14:06 sqlite
/opt/spire/data/sqlite:
total 120
-rw-r----- 1 root root 4096 Apr 22 14:06 datastore.sqlite3
-rw-r----- 1 root root 32768 Apr 22 14:06 datastore.sqlite3-shm
-rw-r----- 1 root root 82432 Apr 22 14:06 datastore.sqlite3-wal
certs.json
と keys
の中身は以下のようになります。
ubuntu@spire-server:~$ sudo cat /opt/spire/data/certs.json
{
"certs": null,
"cas": {
"x509-CA-A": "MIIB7jCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMB4XDTE5MDQyMjE0MDU1N1oXDTE5MDQyMjE1MDYwN1owHjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPrt35IAbZBcifsvJMBbBa+A6hh2zL8nw/J9xLHGwN1WU21S0Py40/IqCEgPo0KB6qYmpgT5aVvDUe094hb6qLn237siKt+xpJ0dClSQhEd2YbeEKmciBqmreN9Bl2JsxaOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJhfWNfaOhZEa+QgvdrMfeaLkAcQwHwYDVR0jBBgwFoAUh6XzV6LwNazA+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYIKoZIzj0EAwMDaAAwZQIxAMyei6J1bkDP4b0/QDu0jmUG/CCM48lwokpx/b0C6xaHJkRHLyx9x56pD+AP0hwIPAIwJVGLn8bwGiyT5oLpRYcQbPiXnFnJ5RdLXk22UBy8CbeMt/QbPGk6OpuJOYBd4dDMMIIBzDCCAVOgAwIBAgIJAJM4DhRH0vmuMAoGCCqGSM49BAMEMB4xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKDAZTUElGRkUwHhcNMTgwNTEzMTkzMzQ3WhcNMjMwNTEyMTkzMzQ3WjAeMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGU1BJRkZFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEWjB+nSGSxIYiznb84xu5WGDZj80nL7W1c3zf48Why0ma7Y7mCBKzfQkrgDguI4j0Z+0/tDH/r8gtOtLLrIpuMwWHoe4vbVBFte1vj6Xt6WeE8lXwcCvLs/mcmvPqVK9jo10wWzAdBgNVHQ4EFgQUh6XzV6LwNazA+GTEVOdu07o5yOgwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwGQYDVR0RBBIwEIYOc3BpZmZlOi8vbG9jYWwwCgYIKoZIzj0EAwQDZwAwZAIwE4Me13qMC9i6Fkx0h26y09QZIbuRqA9puLg9AeeAAyo5tBzRl1YL0KNEp02VKSYJAjBdeJvqjJ9wW55OGj1JQwDFD7kWeEB6oMlwPbI/5hEY3azJi16I0uN1JSYTSWGSqWc="
},
"public_keys": {
"JWT-Signer-A": "ClswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARSUivCC3pPTrL2mRvosRyk625n7rosimxy96x/MRVtzjIN8OerLfl4cth3nE2ZzbH7KWpXTz4gaRdDePrySumOEiBiN3pwRU5wTXdKZHNVSmREZVI2c2tBckk2WUpvUDdMaBjfsPflBQ=="
}
}
ubuntu@spire-server:~$ sudo cat /opt/spire/data/keys
{
"keys": {
"JWT-Signer-A": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgrZgf1H6EZs6WxlcJ35TDENBAzYo0mOgA9mflyDbdGZOhRANCAARSUivCC3pPTrL2mRvosRyk625n7rosimxy96x/MRVtzjIN8OerLfl4cth3nE2ZzbH7KWpXTz4gaRdDePrySumO",
"x509-CA-A": "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBeZ59Jo0Z6a9J8akxi8RswjF2YdQr2dslmhb4ceYw7pf6tJ0d65JKaEabyZmiGpwehZANiAAT67d+SAG2QXIn7LyTAWwWvgOoYdsy/J8PyfcSxxsDdVlNtUtD8uNPyKghID6NCgeqmJqYE+Wlbw1HtPeIW+qi59t+7IirfsaSdHQpUkIRHdmG3hCpnIgapq3jfQZdibMU="
}
}
SQLite の中身を覗いてみると、以下のテーブルが作成されていることがわかります。
- attested_node_entries
- migrations
- bundles
- node_resolver_map_entries
- federated_registration_entries
- registered_entries
- join_tokens
- selectors
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .tables
attested_node_entries migrations
bundles node_resolver_map_entries
federated_registration_entries registered_entries
join_tokens selectors
各テーブルのレコードを確認すると、この時点では migrations
と bundles
以外はレコードなしの状態です。
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
# カラムを表示するためのおまじない
sqlite> .headers on
# attested_node_entries
sqlite> select * from attested_node_entries;
# migrations
sqlite> select * from migrations;
id|created_at|updated_at|version
1|2019-04-22 14:06:07.30985429+00:00|2019-04-22 14:06:07.30985429+00:00|5
# bundles
sqlite> select * from bundles;
id|created_at|updated_at|trust_domain|data
1|2019-04-22 14:06:07.363437704+00:00|2019-04-22 14:06:07.363437704+00:00|spiffe://example.org|
spiffe://example.org�
�0��0�t�0
*�H�=01
U 0 UUS10
190422150607Z01
U 0 UUS10
SPIFFE0v0*�H�=+�
# node_resolver_map_entries
sqlite> select * from node_resolver_map_entries;
# federated_registration_entries
sqlite> select * from federated_registration_entries;
# registered_entries
sqlite> select * from registered_entries;
# join_tokens
sqlite> select * from join_tokens;
# selectors
sqlite> select * from selectors;
各テーブルのカラムは、以下から確認できますので興味ある方はどうぞ。
https://github.com/spiffe/spire/blob/0.7.3/pkg/server/plugin/datastore/sql/models.go
registered_entries
が空なので、もちろんエントリーも空の状態となります。
ubuntu@spire-server:~$ sudo spire-server entry show -registrationUDSPath /var/run/spire/spire-registration.sock
Found 0 entries
専用のコマンドから Bundle が作成されたことも確認できます。
処理を詳しくは追えてませんが、実体は bundles
の文字化けしていたレコードなのかなと思っています。
ubuntu@spire-server:~$ sudo spire-server bundle show -registrationUDSPath /var/run/spire/spire-registration.sock
-----BEGIN CERTIFICATE-----
MIIB7jCCAXSgAwIBAgIBATAKBggqhkjOPQQDAzAeMQswCQYDVQQGEwJVUzEPMA0G
A1UECgwGU1BJRkZFMB4XDTE5MDQyMjE0MDU1N1oXDTE5MDQyMjE1MDYwN1owHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTB2MBAGByqGSM49AgEGBSuBBAAi
A2IABPrt35IAbZBcifsvJMBbBa+A6hh2zL8nw/J9xLHGwN1WU21S0Py40/IqCEgP
o0KB6qYmpgT5aVvDUe094hb6qLn237siKt+xpJ0dClSQhEd2YbeEKmciBqmreN9B
l2JsxaOBhTCBgjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUJhfWNfaOhZEa+QgvdrMfeaLkAcQwHwYDVR0jBBgwFoAUh6XzV6LwNazA
+GTEVOdu07o5yOgwHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5vcmcwCgYI
KoZIzj0EAwMDaAAwZQIxAMyei6J1bkDP4b0/QDu0jmUG/CCM48lwokpx/b0C6xaH
JkRHLyx9x56pD+AP0hwIPAIwJVGLn8bwGiyT5oLpRYcQbPiXnFnJ5RdLXk22UBy8
CbeMt/QbPGk6OpuJOYBd4dDM
-----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-----
証明書の中身はこのようになっております。
# 上記の結果を cert ファイルに書き込んだあとに実行
ubuntu@spire-server:~$ openssl x509 -text -noout -in cert
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: ecdsa-with-SHA384
Issuer: C=US, O=SPIFFE
Validity
Not Before: Apr 22 14:05:57 2019 GMT
Not After : Apr 22 15:06:07 2019 GMT
Subject: C=US, O=SPIFFE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:fa:ed:df:92:00:6d:90:5c:89:fb:2f:24:c0:5b:
05:af:80:ea:18:76:cc:bf:27:c3:f2:7d:c4:b1:c6:
c0:dd:56:53:6d:52:d0:fc:b8:d3:f2:2a:08:48:0f:
a3:42:81:ea:a6:26:a6:04:f9:69:5b:c3:51:ed:3d:
e2:16:fa:a8:b9:f6:df:bb:22:2a:df:b1:a4:9d:1d:
0a:54:90:84:47:76:61:b7:84:2a:67:22:06:a9:ab:
78:df:41:97:62:6c:c5
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:
26:17:D6:35:F6:8E:85:91:1A:F9:08:2F:76:B3:1F:79:A2:E4:01:C4
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:65:02:31:00:cc:9e:8b:a2:75:6e:40:cf:e1:bd:3f:40:3b:
b4:8e:65:06:fc:20:8c:e3:c9:70:a2:4a:71:fd:bd:02:eb:16:
87:26:44:47:2f:2c:7d:c7:9e:a9:0f:e0:0f:d2:1c:08:3c:02:
30:25:51:8b:9f:c6:f0:1a:2c:93:e6:82:e9:45:87:10:6c:f8:
97:9c:59:c9:e5:17:4b:5e:4d:b6:50:1c:bc:09:b7:8c:b7:f4:
1b:3c:69:3a:3a:9b:89:39:80:5d:e1:d0:cc
以上で、SPIRE Server の構築は完了です。
SPIRE Agent を起動するための前準備
spire-agent
コマンドのインストール
spire-agent
ホストに ubuntu ユーザーで接続してください。
ssh -i /path/to/key ubuntu@spire-agent
SPIRE の Release をダウンロードして、中身を /opt/spire
に展開します。
※ 2019年4月23日現在の最新バージョン である 0.7.3
を利用
wget https://github.com/spiffe/spire/releases/download/0.7.3/spire-0.7.3-linux-x86_64-glibc.tar.gz
tar xf spire-0.7.3-linux-x86_64-glibc.tar.gz
sudo cp -r spire-0.7.3/. /opt/spire
spire-agent
コマンドが使えるように /usr/local/bin 直下に symlink を作成します。
sudo ln -s /opt/spire/spire-agent /usr/local/bin/spire-agent
spire-agent
コマンドが使えることを確認できたら OK です。
ubuntu@spire-agent:~$ spire-agent --version
0.7.3
SPIRE Agent が使う設定ファイルの準備
SPIRE Agent で利用する Plugins の選定
Plugin Type | 利用するもの | 備考 |
---|---|---|
NodeAttestor | aws_iid | AWS Instance Identity document を使って Node の正当性を証明する |
KeyManager | disk |
memory だと確認が大変なので disk に書くように設定 |
Workload | unix | UNIXプロセスの情報から Selector を生成する |
設定ファイルの準備
/opt/spire/conf/agent/agent.conf
の内容を以下に変更します。
- trust domain はデフォルトの
example.org
を利用 - NodeAttestor Plugin "aws_iid" で使う設定値はデフォルト値を明示的に宣言
- trust_bundle_path で利用する CA証明書 は SPIRE の Release に含まれているものを使用
※ SPIRE Agent の設定の詳細は こちら を参照下さい。
agent {
data_dir = "/opt/spire/data"
log_level = "DEBUG"
server_address = "172.31.17.242"
server_port = "8081"
socket_path ="/var/run/spire/agent.sock"
trust_bundle_path = "/opt/spire/conf/agent/dummy_root_ca.crt"
trust_domain = "example.org"
}
plugins {
NodeAttestor "aws_iid" {
plugin_data {
identity_document_url = "http://169.254.169.254/latest/dynamic/instance-identity/document"
identity_signature_url = "http://169.254.169.254/latest/dynamic/instance-identity/signature"
}
}
KeyManager "disk" {
plugin_data = {
keys_path = "/opt/spire/data/keys"
}
}
WorkloadAttestor "unix" {
plugin_data {}
}
}
起動に必要なディレクトリを作成
sudo mkdir -p /var/run/spire
以上で、SPIRE Agent を起動するための前準備は完了です。
※ Node Attestation を体感するときに SPIRE Agent を起動するのでここまでの対応で OK
Workload Attestation の前準備
Workload Attestation に使う unix ユーザーを作成
今回は、Workload としてUNIX系OSで動作するプロセスを使うので、そのために必要な uid 10000 の valid-workload
ユーザーと uid 20000 の invalid-workload
ユーザーを作成します。
sudo useradd -u 10000 valid-workload
sudo useradd -u 20000 invalid-workload
各ユーザーが作成されていることが確認できたら OK です。
ubuntu@spire-agent:~$ id -u valid-workload
10000
ubuntu@spire-agent:~$ id -u invalid-workload
20000
以上で、環境構築は完了です。
Node Attestation を体感する
まずは SPIRE ドメインに参加するための Node 認証の仕組みである Node Attestation を体感していきます。
SPIRE Agent を起動して Node Attestation を行う
spire-agent
ホストに ubuntu ユーザーで接続してください。
ssh -i /path/to/key ubuntu@spire-agent
ログは標準出力に吐くようにして、フォアグラウンドでプロセスを起動します。
sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
ログの DEBU[0000] No pre-existing agent SVID found. Will perform node attestation subsystem_name=attestor
から Node Attestation が実行されたことがわかります。そして、Node Attestation に成功したことで SPIRE Agent が起動しています。
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
WARN[0000] Current umask 0022 is too permissive; setting umask 0027.
INFO[0000] data directory: "/opt/spire/data"
INFO[0000] Starting plugin catalog subsystem_name=catalog
DEBU[0000] NodeAttestor(aws_iid): configuring plugin subsystem_name=catalog
DEBU[0000] KeyManager(disk): configuring plugin subsystem_name=catalog
DEBU[0000] WorkloadAttestor(unix): configuring plugin subsystem_name=catalog
DEBU[0000] No pre-existing agent SVID found. Will perform node attestation subsystem_name=attestor
INFO[0000] Starting workload API subsystem_name=endpoints
突然 Node Attestation が成功したと言われても納得できないと思いますが、この後で SPIRE Server 側のログを確認しながら説明しますので、この時点ではなにげない理解で大丈夫です。
データディレクトリには、以下のファイルが作成されます。
ubuntu@spire-agent:~$ sudo ls -l /opt/spire/data
total 8
-rw------- 1 root root 1061 Apr 22 14:10 agent_svid.der
-rw------- 1 root root 962 Apr 22 14:10 bundle.der
spire-agent
ホストに紐づく SPIFFE ID の値を確認するために、spire-agent
ホストの Account ID、Region、Instance ID を確認します。
ubuntu@spire-agent:~$ curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | egrep 'accountId|instanceId|region'
"accountId" : "XXXXXXXXXXXX",
"instanceId" : "i-00fc2dca2309d04d7",
"region" : "ap-northeast-1"
※ http://169.254.169.254/latest/dynamic/instance-identity/document は インスタンスメタデータを取得するための URL
※ Account ID は意図的に伏せています
Account ID、Region、Instance ID は以下となりました。
プロパティ | 値 |
---|---|
Account ID | XXXXXXXXXXXX |
Region | ap-northeast-1 |
Instance ID | i-00fc2dca2309d04d7 |
SPIRE Server の Node Attester Plugin "aws_iid" では、 spiffe://example.org/spire/agent/aws_iid/ACCOUNT_ID/REGION/INSTANCE_ID
というルールで SPIFFE ID が登録される仕様のため、想定通りいけば spire-agent
ホストに紐づく SPIFFE ID は spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
となります。
SPIRE Server のログを確認してみる
SPIRE Server 側のログを確認してみます。
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
...
DEBU[0252] Signing CSR for Agent SVID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 subsystem_name=node_api
DEBU[0252] Signed x509 SVID "spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7" (expires 2019-04-22T15:06:07Z) subsystem_name=ca_manager
INFO[0252] Node attestation request from 172.31.17.235:33086 completed using strategy aws_iid subsystem_name=node_api
以下のログから、想定通り spire-agent
ホストに紐づく SPIFFE ID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
が登録されたことがわかります。
DEBU[0252] Signing CSR for Agent SVID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 subsystem_name=node_api
DEBU[0252] Signed x509 SVID "spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7" (expires 2019-04-22T15:06:07Z) subsystem_name=ca_manager
また、以下のログから spire-agent
ホストからの Node Attestation が完了したことがわかります。
INFO[0252] Node attestation request from 172.31.17.235:33086 completed using strategy aws_iid subsystem_name=node_api
SQLite の中身を確認してみる
Node Attestation 前後で変化があったテーブルは attested_node_entries
と node_resolver_map_entries
となります。
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
# カラムを表示するためのおまじない
sqlite> .headers on
# attested_node_entries
sqlite> select * from attested_node_entries;
id|created_at|updated_at|spiffe_id|data_type|serial_number|expires_at
1|2019-04-22 14:10:19.469466093+00:00|2019-04-22 14:10:19.469466093+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|2|2019-04-22 15:06:07+00:00
# node_resolver_map_entries
sqlite> select * from node_resolver_map_entries;
id|created_at|updated_at|spiffe_id|type|value
1|2019-04-22 14:10:19.468130215+00:00|2019-04-22 14:10:19.468130215+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|sg:id:sg-012874274efb978c7
2|2019-04-22 14:10:19.46821413+00:00|2019-04-22 14:10:19.46821413+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|sg:name:Ubuntu 16-04 LTS - Xenial -HVM--Ubuntu 16-04 LTS 20190212-AutogenByAWSMP-1
3|2019-04-22 14:10:19.468289052+00:00|2019-04-22 14:10:19.468289052+00:00|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|aws_iid|tag:name:spire-agent
各テーブルのレコードを詳しく見ていきましょう。
attested_node_entries
SPIRE Server のログにも出力されていたとおり Node Attestation に成功したホストの情報が書き込まれています。
id | spiffe_id | data_type | serial_number | expires_at |
---|---|---|---|---|
1 | spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 | aws_iid | 2 | 2019-04-22 15:06:07+00:00 |
※ 表が見づらくなるので timestamp 系のカラムは除いてます
node_resolver_map_entries
SPIRE Server の Node Resolver Plugin "aws_iid" では、以下4つの Selector が生成される仕様となっております。
- Instance Tag
- Security Group ID
- Security Group Name
- IAM Role
自分の環境だと IAM Role を設定していなかったので、3つの Selector が生成されました。
上から Security Group ID、Security Group Name、Instance Tag となります。
id | spiffe_id | type | value |
---|---|---|---|
1 | spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 | aws_iid | sg:id:sg-012874274efb978c7 |
2 | spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 | aws_iid | sg:name:Ubuntu 16-04 LTS - Xenial -HVM--Ubuntu 16-04 LTS 20190212-AutogenByAWSMP-1 |
3 | spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 | aws_iid | tag:name:spire-agent |
※ 表が見づらくなるので timestamp 系のカラムは除いてます
以上が、Node Attestation となります。
Workload Attestation を体感する
次に、任意の Workload から SVID を取得するための認証の仕組みである Workload Attestation を体感していきます。
SPIRE Server に Entry を登録する
spire-server
ホストに ubuntu ユーザーで接続してください。
ssh -i /path/to/key ubuntu@spire-server
spire-agent
ホスト上で uid 10000 の valid-workload
ユーザーから実行されるUNIXプロセスを認証を許可する Workload として Entry に登録します。ParentID には Node Attestation の際に登録された spire-agent
ホストの SPIFFEE ID を設定し、SPIFFE ID には Workload に紐付ける任意の SPIFFE ID を設定し、Selector には uid 10000 から実行されるプロセスが対象となるように値(Workload Attester Plugin "unix" の詳細は こちら)を設定します。
sudo spire-server entry create \
-registrationUDSPath /var/run/spire/spire-registration.sock \
-parentID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 \
-spiffeID spiffe://example.org/host/valid-workload \
-selector unix:uid:10000
以下のような実行結果となります。
ubuntu@spire-server:~$ sudo spire-server entry create \
> -registrationUDSPath /var/run/spire/spire-registration.sock \
> -parentID spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 \
> -spiffeID spiffe://example.org/host/valid-workload \
> -selector unix:uid:10000
Entry ID : 9d0d2673-bf2b-42d3-9235-2090e9050fb4
SPIFFE ID : spiffe://example.org/host/valid-workload
Parent ID : spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
TTL : 3600
Selector : unix:uid:10000
SPIRE Server のログにも Entry が登録され、SVID が発行されたログが出力されます。
ubuntu@spire-server:~$ sudo spire-server run -config /opt/spire/conf/server/server.conf
...
DEBU[3107] Signing SVID for spiffe://example.org/host/valid-workload on request by spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7 subsystem_name=node_api
DEBU[3107] Signed x509 SVID "spiffe://example.org/host/valid-workload" (expires 2019-04-22T15:36:07Z) subsystem_name=ca_manager
専用のコマンドから Entry が追加されたことも確認できました。
ubuntu@spire-server:~$ sudo spire-server entry show -registrationUDSPath /var/run/spire/spire-registration.sock
Found 1 entry
Entry ID : 9d0d2673-bf2b-42d3-9235-2090e9050fb4
SPIFFE ID : spiffe://example.org/host/valid-workload
Parent ID : spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7
TTL : 3600
Selector : unix:uid:10000
SQLite の中身を確認してみると registered_entries
と selectors
にレコードが追加されたことがわかります。
ubuntu@spire-server:~$ sudo sqlite3 /opt/spire/data/sqlite/datastore.sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
# カラムを表示するためのおまじない
sqlite> .headers on
# registered_entries
sqlite> select * from registered_entries;
id|created_at|updated_at|entry_id|spiffe_id|parent_id|ttl|admin
1|2019-04-22 14:57:52.177533369+00:00|2019-04-22 14:57:52.177533369+00:00|9d0d2673-bf2b-42d3-9235-2090e9050fb4|spiffe://example.org/host/valid-workload|spiffe://example.org/spire/agent/aws_iid/XXXXXXXXXXXX/ap-northeast-1/i-00fc2dca2309d04d7|3600|0
# selectors
sqlite> select * from selectors;
id|created_at|updated_at|registered_entry_id|type|value
1|2019-04-22 14:57:52.177715825+00:00|2019-04-22 14:57:52.177715825+00:00|1|unix|uid:10000
valid-workload ユーザーでプロセスを実行して Workload Attestation を行う
spire-agent
ホストに ubuntu ユーザーで接続してください。
ssh -i /path/to/key ubuntu@spire-agent
SVID を取得する際に Workload Attestation が必須となるので、SVID を取得するためのコマンドを uid 10000 の valid-workload
ユーザーで実行してみます。
sudo -u valid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
認証が許可された Workload として Entry に追加してあるので、Workload Attestation が成功して SVID の情報を取得することができました。
ubuntu@spire-agent:~$ sudo -u valid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
Received 1 bundle after 2.006431ms
SPIFFE ID: spiffe://example.org/host/valid-workload
SVID Valid After: 2019-04-22 14:57:44 +0000 UTC
SVID Valid Until: 2019-04-22 15:36:07 +0000 UTC
Intermediate #1 Valid After: 2019-04-22 14:35:57 +0000 UTC
Intermediate #1 Valid Until: 2019-04-22 15:36:07 +0000 UTC
CA #1 Valid After: 2019-04-22 14:05:57 +0000 UTC
CA #1 Valid Until: 2019-04-22 15:06:07 +0000 UTC
CA #2 Valid After: 2018-05-13 19:33:47 +0000 UTC
CA #2 Valid Until: 2023-05-12 19:33:47 +0000 UTC
CA #3 Valid After: 2019-04-22 14:35:57 +0000 UTC
CA #3 Valid Until: 2019-04-22 15:36:07 +0000 UTC
CA #4 Valid After: 2019-04-22 15:05:57 +0000 UTC
CA #4 Valid Until: 2019-04-22 16:06:07 +0000 UTC
以下のように -write
オプションで、SVID と Bundle をディスクに書き込むことも可能です。
sudo -u valid-workload spire-agent api fetch x509 \
-socketPath /var/run/spire/agent.sock -write /tmp
以下、例となります。
ubuntu@spire-agent:~$ sudo -u valid-workload spire-agent api fetch x509 \
> -socketPath /var/run/spire/agent.sock -write /tmp
Received 1 bundle after 1.660049ms
SPIFFE ID: spiffe://example.org/host/valid-workload
SVID Valid After: 2019-04-22 15:16:49 +0000 UTC
SVID Valid Until: 2019-04-22 15:36:07 +0000 UTC
Intermediate #1 Valid After: 2019-04-22 14:35:57 +0000 UTC
Intermediate #1 Valid Until: 2019-04-22 15:36:07 +0000 UTC
CA #1 Valid After: 2019-04-22 14:05:57 +0000 UTC
CA #1 Valid Until: 2019-04-22 15:06:07 +0000 UTC
CA #2 Valid After: 2018-05-13 19:33:47 +0000 UTC
CA #2 Valid Until: 2023-05-12 19:33:47 +0000 UTC
CA #3 Valid After: 2019-04-22 14:35:57 +0000 UTC
CA #3 Valid Until: 2019-04-22 15:36:07 +0000 UTC
CA #4 Valid After: 2019-04-22 15:05:57 +0000 UTC
CA #4 Valid Until: 2019-04-22 16:06:07 +0000 UTC
Writing SVID #0 to file /tmp/svid.0.pem.
Writing key #0 to file /tmp/svid.0.key.
Writing bundle #0 to file /tmp/bundle.0.pem.
# SVID と Bundle がディスクに書き込まれた
ubuntu@spire-agent:~$ ll /tmp/svid.0.pem
-rw-r--r-- 1 valid-workload valid-workload 1482 Apr 22 15:17 /tmp/svid.0.pem
ubuntu@spire-agent:~$ ll /tmp/svid.0.key
-rw-r--r-- 1 valid-workload valid-workload 241 Apr 22 15:17 /tmp/svid.0.key
ubuntu@spire-agent:~$ ll /tmp/bundle.0.pem
-rw-r--r-- 1 valid-workload valid-workload 2875 Apr 22 15:17 /tmp/bundle.0.pem
SPIRE Agent のログからは Workload Attestation を行おうとした Workload の Selector 情報が確認できます。この出力された Selector 情報が Entry で追加したものと一致するため、Workload Attestation が成功となったわけです。
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
...
DEBU[3606] PID 2082 attested to have selectors [type:"unix" value:"uid:10000" type:"unix" value:"user:valid-workload" type:"unix" value:"gid:10000" type:"unix" value:"group:valid-workload" ] subsystem_name=workload_api
invalid-workload ユーザーでプロセスを実行して Workload Attestation が失敗するか確認する
Workload Attestation が成功するパターンは確認できたので、次は失敗するパターンを試してみます。
Entry に登録されていない uid 20000 の invalid-workload
ユーザーで SVID の取得を行おうとすると、Permission Denied なエラー終了となります。
ubuntu@spire-agent:~$ sudo -u invalid-workload spire-agent api fetch x509 -socketPath /var/run/spire/agent.sock
rpc error: code = PermissionDenied desc = no identity issued
SPIRE Agent のログからは Workload Attestation を行おうとした Workload の Selector 情報が確認できます。この出力された Selector 情報が許可された Workload として Entry に存在しないため、Workload Attestation が失敗となりました。
ubuntu@spire-agent:~$ sudo spire-agent run -config /opt/spire/conf/agent/agent.conf
...
DEBU[4228] PID 2137 attested to have selectors [type:"unix" value:"uid:20000" type:"unix" value:"user:invalid-workload" type:"unix" value:"gid:20000" type:"unix" value:"group:invalid-workload" ] subsystem_name=workload_api
以上が、Workload Attestation となります。
補足
Node Attestation について
今回は AWS 上での Node Attestation となりましたが、インスタンスの正当性を証明するための Node Attester(Server/Agent 両方)があれば、任意のプラットフォームで Node Attestation を行うことが可能です。SPIRE に Built-in されているものだと以下があります。
プラットフォーム | Server plugin | Agent plugin | 備考 |
---|---|---|---|
Azure | azure_msi | azure_msi | Azure MSI token を使う |
GCP | gcp_iit | gcp_iid | GCP Instance Identity Token を使う |
Kubernetes | k8s_sat | k8s_sat | Kubernetes Service Account token を使う |
どこでも使える | join_token | join_token | SPIRE Server からワンタイムトークンを発行して SPIRE Agent 起動時に渡す |
どこでも使える | x509pop | x509_pop | X.509 証明書を使う |
また、OSS としても公開されているものもあります。
プラットフォーム | Server plugin | Agent plugin | 備考 |
---|---|---|---|
OpenStack | openstack_iid | openstack_iid | OpenStack InstanceID を使う |
Workload Attestation について
今回は UNIXプロセスを Workload として使いましたが、Workload から任意のルールで Selector を発行できる Workload Attester があれば、任意の Workload で Workload Attestation を行うことが可能です。SPIRE に Built-in されているものだと以下があります。
Workload | Plugin | 備考 |
---|---|---|
Kubernetes Resource | k8s | Namespace と Service Account を Selector として発行します |
Docker Container | docker | Label と Image ID を Selector として発行します |
さいごに
今回は、AWS を使って SPIRE の Node Attestation と Workload Attestation を体感する流れを紹介しました。各処理を実行しながら、ログを確認したり、どのようなデータが保存されるかを追いかけたりと、冗長な流れとなってしまいましたが、参考程度に活用頂けたらと思います。
Node Attestation、Workload Attestation を経て、最終的に Workload が SVID と Bundle が取得できる(Workload が Node 上にファイルとして書き込むことも可能)ことを理解頂いたと思いますが、その SVID と Bundle を用いたユースケースとして SPIRE の公式ページでは以下が紹介されております。
- サービス間の安全な認証
- Vault と Knox からのシークレット取得
- Envoy などのサービスメッシュ内のサイドカープロキシを識別するための基盤としてのIDプロビジョニング
- 分散システムの認証に使用する PKI のプロビジョニングとローテーション
上記のユースケースも踏まえて、SPIFFE/SPIRE は今後より盛り上がってくる OSS だと思いますので、引き続き情報を追いかけていきたいと思います。