のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

kubesec で AWS KMS のキーを使って Secret を暗号化・復号してみる

Kubernetes の Secret リソースでマニフェストで作成するとき、Secret として秘匿したいデータを Base 64 でエンコードして指定します。

ただ、Base 64は単なるエンコードなので、そのままでマニフェストを保存することは、セキュリティ上避けたいですよね。そのため、Secret のデータの暗号化や復号を行う kubesecSealedSecrets などのツールが提供されています。

これまで「kubesecとか使えば暗号化や復号はできるよね」と頭でしか理解してなかったんですが、kubesec を実際に触ってみようと思い立ったので、そのときのメモをここに書いておきたいと思います。

なお、今回は 下図のように AWS KMS のキーを使用して暗号化・復号する前提とします。


目次

  1. AWS KMS のキーの作成
  2. kubesec のインストール
  3. Secret のマニフェストの暗号化
  4. Secret のマニフェストの復号
  5. 今回の所感

1. AWS KMS のキーの作成

今回、暗号化や復号に必要なキーを AWS KMS を使用して生成しますので、AWS KMSにアクセスできるようにする必要があります。そのため、使用しているAWS IAM のユーザーまたはロールに、AWS IAM のポリシーを設定します。

今回は、使用している AWS IAM のユーザーに AWSKeyManagementServicePowerUser という管理ポリシーを設定する前提としますが、実際に使用する際は最小権限の原則に基づいて設定して下さい。

AWS KMS を操作する上での AWS IAM のポリシーについては次のドキュメントに例があるので参考にしましょう。

docs.aws.amazon.com

AWS KMS キーの作成は AWS マネジメントコンソールからでも行えますが、今回は AWS CLI のコマンドで作成してみます。

aws kms create-key  --description "demo for kubesec"

--description オプションで指定する文字列の値は任意です。

キー作成が完了すると、次のような 出力が表示されるので、この中の Arn の値をメモしておきましょう。

{
    "KeyMetadata": {
        "AWSAccountId": "000000000000",
        "KeyId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "Arn": "arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "CreationDate": "2023-03-25T09:31:57.061000+00:00",
        "Enabled": true,
        "Description": "demo for kubesec",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER",
        "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
        "KeySpec": "SYMMETRIC_DEFAULT",
        "EncryptionAlgorithms": [
            "SYMMETRIC_DEFAULT"
        ],
        "MultiRegion": false
    }
}

2. kubesec のインストール

kubesec のインストール方法などについては、下記を参考にしました。

github.com

今回は Linux の環境にインストールしますので、次のコマンドを実行します。

curl -sSL https://github.com/shyiko/kubesec/releases/download/0.9.2/kubesec-0.9.2-linux-amd64 \
  -o kubesec && chmod a+x kubesec && sudo mv kubesec /usr/local/bin/  

その後、確認のため次のコマンドを実行します。

kubesec --version

0.9.2 のようにバージョン ID が出力されれば OK です。


3. Secret のマニフェストの暗号化

ではいよいよ、Secret のマニフェストを暗号化してみます。

今回は、次の内容を secret.yaml として保存して使用します。

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4xMjM0

kubesec で AWS KMS のキーを使用して暗号化するときは、--key オプションに キーの ARN を指定します。

次の例では、secret.yaml を暗号化したマニフェスト標準出力 に表示します。

kubesec encrypt --key=aws:<ARN of AWS KMS key> secret.yaml

実行すると次のような内容が表示されます。

apiVersion: v1
data:
  password: (暗号化された値)
  username:  (暗号化された値)
kind: Secret
metadata:
  name: my-secret
type: Opaque
# kubesec:v:3
# kubesec:aws:arn:aws:kms:ap-northeast-1:0000000000001:key/xxxxx
# kubesec:mac:xxxxx

data: 以下の usernamepassword の値が暗号化されていることを確認できました。

また、-i オプションを付けると、指定したマニフェストファイルに暗号化した値を直接変更します。

kubesec encrypt -i  --key=aws:<ARN of AWS KMS key> secret.yaml

上記を実行すると、secret.yamldata: 以下の usernamepassword の値が直接変更されたことが確認できます。


4. Secret のマニフェストの復号

暗号化されたマニフェストを復号する場合は、decrypt を使用します。

次の例では、暗号化されている secret.yaml を復号して標準出力に表示します。

kubesec decrypt secret.yaml 

実行すると次のような内容が表示されます。

apiVersion: v1
data:
  password: YWRtaW4xMjM0
  username: YWRtaW4=
kind: Secret
metadata:
  name: my-secret
type: Opaque

また、暗号化と同じように -i オプションを付けると、暗号化されたファイルに復号した値を直接変更します。

kubesec decrypt -i  secret.yaml 

上記を実行すると、暗号化された secret.yamldata: 以下の usernamepassword の値が直接変更されたことが確認できます。


5.今回の所感

kubesec と AWS KMS のキーを使用して Secret の値を暗号化・復号する仕組み自体は、とてもシンプルです。

GitOps のように Kubernetesマニフェストを Git リポジトリに保存・管理してデプロイする場合は、Secret は kubesec のようなツールを使い、暗号化して保存し、Kubernetes クラスタに適用する際に自動的に復号するような仕組みを考えたいと思いました。

一方で、AWS KMS のキーの権限の管理は厳格に行う必要があります。キーを作成できる権限、キーを使用して暗号化・復号できる権限などは IAMのユーザーまたはロールごとに最小権限の原則に基づいて設定する必要があるので、その管理や運用を漏れなく実施する必要性を強く感じました。

今回は 暗号化・復号のツールとして kubesec を使ってみましたが、他にも SealedSecrets といった便利なツールもあるので、また別の機会に触ってみたいです!


/* -----codeの行番号----- */