From 3d6fd491795adb8a38493afe6c2968a46051d5ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20Kr=C3=BCger?= <andreas@kruger.nu>
Date: Thu, 15 Mar 2018 20:20:05 +0100
Subject: [PATCH] Added option for encrypting secrets to etcd v.2 (#2428)

* Added option for encrypting secrets to etcd

* Fix keylength to 32

* Forgot the default

* Rename secrets.yaml to secrets_encryption.yaml

* Fix static path for secrets file to use ansible variable

* Rename secrets.yaml.j2 to secrets_encryption.yaml.j2

* Base64 encode the token

* Fixed merge error

* Changed path to credentials dir

* Update path to secrets file which is now readable inside the apiserver container. Set better file permissions

* Add encryption option to k8s-cluster.yml
---
 inventory/sample/group_vars/k8s-cluster.yml           |  5 ++++-
 roles/kubernetes/master/defaults/main.yml             |  5 +++++
 roles/kubernetes/master/tasks/encrypt-at-rest.yml     | 10 ++++++++++
 roles/kubernetes/master/tasks/main.yml                |  3 +++
 .../master/templates/kubeadm-config.yaml.j2           |  3 +++
 .../templates/manifests/kube-apiserver.manifest.j2    |  3 +++
 .../master/templates/secrets_encryption.yaml.j2       | 11 +++++++++++
 7 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 roles/kubernetes/master/tasks/encrypt-at-rest.yml
 create mode 100644 roles/kubernetes/master/templates/secrets_encryption.yaml.j2

diff --git a/inventory/sample/group_vars/k8s-cluster.yml b/inventory/sample/group_vars/k8s-cluster.yml
index 128e8cc99..8f69afc25 100644
--- a/inventory/sample/group_vars/k8s-cluster.yml
+++ b/inventory/sample/group_vars/k8s-cluster.yml
@@ -111,7 +111,10 @@ kube_apiserver_insecure_port: 8080 # (http)
 
 # Kube-proxy proxyMode configuration.
 # Can be ipvs, iptables
-kube_proxy_mode: iptables 
+kube_proxy_mode: iptables
+
+## Encrypting Secret Data at Rest (experimental)
+kube_encrypt_secret_data: false
 
 # DNS configuration.
 # Kubernetes cluster name, also will be used as DNS domain
diff --git a/roles/kubernetes/master/defaults/main.yml b/roles/kubernetes/master/defaults/main.yml
index 59e528822..a1b506d4e 100644
--- a/roles/kubernetes/master/defaults/main.yml
+++ b/roles/kubernetes/master/defaults/main.yml
@@ -92,3 +92,8 @@ kube_kubeadm_scheduler_extra_args: {}
 
 ## Variable for influencing kube-scheduler behaviour
 volume_cross_zone_attachment: false
+
+## Encrypting Secret Data at Rest
+kube_encrypt_secret_data: false
+kube_encrypt_token: "{{ lookup('password', inventory_dir + '/credentials/kube_encrypt_token length=32 chars=ascii_letters,digits') }}"
+kube_encryption_algorithm: "aescbc" # Must be either: aescbc, secretbox or aesgcm
diff --git a/roles/kubernetes/master/tasks/encrypt-at-rest.yml b/roles/kubernetes/master/tasks/encrypt-at-rest.yml
new file mode 100644
index 000000000..2e569b08b
--- /dev/null
+++ b/roles/kubernetes/master/tasks/encrypt-at-rest.yml
@@ -0,0 +1,10 @@
+---
+- name: Write secrets for encrypting secret data at rest
+  template:
+    src: secrets_encryption.yaml.j2
+    dest: "{{ kube_config_dir }}/ssl/secrets_encryption.yaml"
+    owner: root
+    group: "{{ kube_cert_group }}"
+    mode: 0640
+  tags:
+    - kube-apiserver
diff --git a/roles/kubernetes/master/tasks/main.yml b/roles/kubernetes/master/tasks/main.yml
index 04ad307fd..daa10fd79 100644
--- a/roles/kubernetes/master/tasks/main.yml
+++ b/roles/kubernetes/master/tasks/main.yml
@@ -12,6 +12,9 @@
 - import_tasks: users-file.yml
   when: kube_basic_auth|default(true)
 
+- import_tasks: encrypt-at-rest.yml
+  when: kube_encrypt_secret_data
+
 - name: Compare host kubectl with hyperkube container
   command: "{{ docker_bin_dir }}/docker run --rm -v {{ bin_dir }}:/systembindir {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }} /usr/bin/cmp /hyperkube /systembindir/kubectl"
   register: kubectl_task_compare_result
diff --git a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
index ed1cc7add..cd266ed3d 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
@@ -52,6 +52,9 @@ apiServerExtraArgs:
 {%   if kube_oidc_groups_claim is defined %}
   oidc-groups-claim: {{ kube_oidc_groups_claim }}
 {%   endif %}
+{% endif %}
+{% if kube_encrypt_secret_data %}
+  experimental-encryption-provider-config: {{ kube_config_dir }}/ssl/secrets_encryption.yaml
 {% endif %}
   storage-backend: {{ kube_apiserver_storage_backend }}
 {% if kube_api_runtime_config is defined %}
diff --git a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
index 0dbe93cab..c1685410d 100644
--- a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
@@ -103,6 +103,9 @@ spec:
 {% if authorization_modes %}
     - --authorization-mode={{ authorization_modes|join(',') }}
 {% endif %}
+{% if kube_encrypt_secret_data %}
+    - --experimental-encryption-provider-config={{ kube_config_dir }}/ssl/secrets_encryption.yaml
+{% endif %}
 {% if kube_feature_gates %}
     - --feature-gates={{ kube_feature_gates|join(',') }}
 {% endif %}
diff --git a/roles/kubernetes/master/templates/secrets_encryption.yaml.j2 b/roles/kubernetes/master/templates/secrets_encryption.yaml.j2
new file mode 100644
index 000000000..84c6a4ea8
--- /dev/null
+++ b/roles/kubernetes/master/templates/secrets_encryption.yaml.j2
@@ -0,0 +1,11 @@
+kind: EncryptionConfig
+apiVersion: v1
+resources:
+  - resources:
+    - secrets
+    providers:
+    - {{ kube_encryption_algorithm }}:
+        keys:
+        - name: key
+          secret: {{ kube_encrypt_token | b64encode }}
+    - identity: {}
-- 
GitLab