2024/12/06追加
本記事はsecretのtypeがopaqueであることについて限定して記述しています🙇
他のtypeについては適宜、公式ドキュメントを参考にしていただけると幸いです。
TL;DR
- 暗号方式や保管場所について、SecretとConfigMapに違いはない
- etcdに保存され、両方とも暗号化することができる
- RBACの制限もかけられる
- SecretやConfigMapの値を参照するPodにアクセスできる人を制限することができる
- RBACを管理しやすくするために、ConfigMapとSecretが分かれていると考えられる
初めに
「シークレットの値は環境変数に入れましょう!」
というのは、よく言われることですが、環境変数に入れてしまうということはそのDeploymentsやPodsが動いているホストにログインできる人はその値を見ることができてしまいます。
特に、SecretKeyRef
を使うことでSecretの値を環境変数に入れることができますが、これはSecretの中で隠れていたものを見えるようにしてしまうことと同じであるため、
結局ConfigMapと変わらないのではと感じることがあります。
secretkeyrefって変じゃね?
— Nozomi (@NozomiMaki2) November 23, 2024
secretで頑張って隠してたものを、大っぴらに環境変数で展開してるのに、configmapと同等扱いされてない訳で…
そこで、今回は上記の問題が本当かどうか、どれだけのリスクがあるのかを公式ドキュメントをもとに調査をしてみました。
Podから環境変数は見れるのか確認
まずは、Podから環境変数を見ることができるのかを確認してみました(詳細:makinzm/hajimeteno-terraform-with-secret )。
secretKeyRefやConfigMapKeyRefを使って環境変数を設定した場合(該当コード)、Podから環境変数を見ることができます。
CONFIG_***
がConfigMapから展開された環境変数で、SECRET_***
がSecretから展開された環境変数です。
> sh -c env
SECRET_PASSWORD=password
CONFIG_PASSWORD=myPassword
SECRET_USERNAME=user
CONFIG_USERNAME=myUser
こうなるとConfigMapとSecretは同じように見えます。
ConfigMap vs Secret
公式ドキュメントでConfigMapとSecretの違いを確認
公式ドキュメントを確認してみると、以下のように記載されていました。
Secrets are similar to ConfigMaps but are specifically intended to hold confidential data.
Secrets | Kubernetes より引用
ただ、この記載だけではSecretとConfigMapの違いがよくわかりません。
内部ロジックがどう違うのでしょうか。
なんの驚異からデータを守るためにSecretとConfigMapはわかれているのでしょうか。
kubectlで確認
ConfigMapとSecretを表示してみると以下のような形になっています。
まず、ConfigMapを表示してみます。
kubectl describe configmap my-config -n secret-test
Name: my-config
Namespace: secret-test
Labels: <none>
Annotations: <none>
Data
====
password:
----
myPassword
username:
----
myUser
BinaryData
====
Events: <none>
次に、Secretを表示してみます。
kubectl describe secret my-secret -n secret-test
Name: my-secret
Namespace: secret-test
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 8 bytes
user: 4 bytes
これを見ると、Secretについては値が表示されていない違いがあります。
保存場所
Secretはデフォルトではetcdに保存されます。
By default, Secret objects are stored unencrypted in etcd.
Good practices for Kubernetes Secrets | Kubernetes より
ConfigMapも同じくetcdに保存されるようです(公式ドキュメントに記載はありませんでしたが、Cluster Architecture | Kubernetesやkubernetes - Where does ConfigMap data gets stored? - Stack Overflowを参考にしています)。
そのため、SecretとConfigMapの保存場所は同じであるため、SecretとConfigMapの違いは保存場所にはないと考えられます。
保管方法
Secretはデフォルトでは、暗号化されていません。
Kubernetes Secrets are, by default, stored unencrypted in the API server's underlying data store (etcd).
Secrets | Kubernetes より
ただ、Encrypting Confidential Data at Rest | Kubernetesに記載の方法で、
クラスター全体でSecretを暗号化することができます(ただし、namespaceごとではなくクラスター全体での設定になることに注意してください)。
しかし、上記の設定値のresources
にconfigmaps
も含めることができるため、ConfigMapも暗号化することができるようです。
結局同じ?
私の調べた限りでは、kubectlでの表示のされ方以外については、SecretとConfigMapの違いはないように感じました。
一方で、KubernetesのResourceの区切りとして、SecretとConfigMapが分かれていることは、Kubernetesの利用者にとって使いやすいと感じました。
例えば、一律でRBACに指定できるresourceが一つだけだと、不便であることもあるように伺えます。
そのため、SecretとConfigMapが分かれているのは、Kubernetesの利用者が使いやすいように設計されているように思えました。
適宜、公式から出ているベストプラクティスを参考にしてください。
Good practices for Kubernetes Secrets | Kubernetes
Podにアクセスできることの驚異
Encrypting Confidential Data at Rest | Kubernetes から、
ConfigMapやSecretの内容はetcd内では、暗号化できることを確認しましたが、結局Podにアクセスできる人はその値を見ることができてしまいます。
ここの驚異に対しては、どのような対策があるのでしょうか。
これに対しては、先程のRBACの設定と同様に設定することができます。
resources: ["pods"]
Using RBAC Authorization | Kubernetes
Kubernetesで設定できるリソースは下記のページから見れますが、Secretと同様にPodに対しても制御を加えることができます。
よって、Podにアクセスできる人を制限することで、SecretやConfigMapの値を見ることを防ぐことができます。
ただ、EncryptionConfiguration
は key-value storeの暗号化にしか対応していないことに注意してください。
you can encrypt Secret objects, including the key-value data they contain.
Encrypting Confidential Data at Rest | Kubernetes より
余談 ~ etcdの暗号化は必要か? ~
etcdに保管する内容は暗号化する必要はあるのでしょうか?
というのも、そもそもk8sのクラスターにアクセスできる人だけがetcdにアクセスできるため、入られてしまったらもう手遅れなのではないかと思えるからです。
現状の調べをもとにセキュリティを頑丈にしても、etcdのアクセスについては、RBACと暗号化の両方ですが、PodはRBACのみです。
もし、Podの環境変数としてSecretの値が展開されている場合は、Podにアクセスされるとetcdの暗号化はほとんど意味がなくなってしまいます。
一方で、セキュリティのレイヤーは増やすことは悪いことではなく、その意味でetcdの暗号化は有用です。
You can enable etcd encryption for your cluster to provide an additional layer of data security.
Encrypting etcd data | Security and compliance | OpenShift Container Platform 4.9 より
Each layer adds another layer of security, so the more layers you have, the more difficult it will be for hackers to infiltrate your network.
Why it is important to use multi-layered security | LinkedIn | EmpowerIT.ca より
また、ここでは考慮しきれていない未知の脆弱性があるかもしれないため、セキュリティのレイヤーを増やすことが重要です。
無知の知を大切に、なるべく多くのセキュリティ対策を取ることが重要だと感じました。
注意書き
記事についてはすべて、2024/12/01時点にアクセスした内容です。