diff --git a/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml b/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml index 58eaaa66f..83bfbb22a 100644 --- a/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml +++ b/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml @@ -9,6 +9,10 @@ - {src: apiserver-key.pem, dest: apiserver.key} - {src: ca.pem, dest: ca.crt} - {src: ca-key.pem, dest: ca.key} + - {src: front-proxy-ca.pem, dest: front-proxy-ca.crt} + - {src: front-proxy-ca-key.pem, dest: front-proxy-ca.key} + - {src: front-proxy-client.pem, dest: front-proxy-client.crt} + - {src: front-proxy-client-key.pem, dest: front-proxy-client.key} - {src: service-account-key.pem, dest: sa.pub} - {src: service-account-key.pem, dest: sa.key} register: kubeadm_copy_old_certs diff --git a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 index 687ca415d..e0054686a 100644 --- a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 +++ b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 @@ -111,7 +111,7 @@ spec: - --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kube_version | version_compare('v1.9', '>=') %} - - --requestheader-client-ca-file={{ kube_cert_dir }}/ca.pem + - --requestheader-client-ca-file={{ kube_cert_dir }}/front-proxy-ca.pem - --requestheader-allowed-names=front-proxy-client - --requestheader-extra-headers-prefix=X-Remote-Extra- - --requestheader-group-headers=X-Remote-Group diff --git a/roles/kubernetes/secrets/defaults/main.yml b/roles/kubernetes/secrets/defaults/main.yml index f0d10711d..cda85eeb2 100644 --- a/roles/kubernetes/secrets/defaults/main.yml +++ b/roles/kubernetes/secrets/defaults/main.yml @@ -1,3 +1,4 @@ --- kube_cert_group: kube-cert kube_vault_mount_path: kube +front_proxy_vault_mount_path: front-proxy diff --git a/roles/kubernetes/secrets/files/make-ssl.sh b/roles/kubernetes/secrets/files/make-ssl.sh index 1c34fc69d..2a4b930ea 100755 --- a/roles/kubernetes/secrets/files/make-ssl.sh +++ b/roles/kubernetes/secrets/files/make-ssl.sh @@ -72,6 +72,15 @@ else openssl req -x509 -new -nodes -key ca-key.pem -days 36500 -out ca.pem -subj "/CN=kube-ca" > /dev/null 2>&1 fi +# Front proxy client CA +if [ -e "$SSLDIR/front-proxy-ca-key.pem" ]; then + # Reuse existing front proxy CA + cp $SSLDIR/{front-proxy-ca.pem,front-proxy-ca-key.pem} . +else + openssl genrsa -out front-proxy-ca-key.pem 2048 > /dev/null 2>&1 + openssl req -x509 -new -nodes -key front-proxy-ca-key.pem -days 36500 -out front-proxy-ca.pem -subj "/CN=front-proxy-ca" > /dev/null 2>&1 +fi + gen_key_and_cert() { local name=$1 local subject=$2 @@ -80,6 +89,14 @@ gen_key_and_cert() { openssl x509 -req -in ${name}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out ${name}.pem -days 36500 -extensions v3_req -extfile ${CONFIG} > /dev/null 2>&1 } +gen_key_and_cert_front_proxy() { + local name=$1 + local subject=$2 + openssl genrsa -out ${name}-key.pem 2048 > /dev/null 2>&1 + openssl req -new -key ${name}-key.pem -out ${name}.csr -subj "${subject}" -config ${CONFIG} > /dev/null 2>&1 + openssl x509 -req -in ${name}.csr -CA front-proxy-ca.pem -CAkey front-proxy-ca-key.pem -CAcreateserial -out ${name}.pem -days 36500 -extensions v3_req -extfile ${CONFIG} > /dev/null 2>&1 +} + # Admins if [ -n "$MASTERS" ]; then @@ -105,7 +122,7 @@ if [ -n "$MASTERS" ]; then # kube-controller-manager gen_key_and_cert "kube-controller-manager" "/CN=system:kube-controller-manager" # metrics aggregator - gen_key_and_cert "front-proxy-client" "/CN=front-proxy-client" + gen_key_and_cert_front_proxy "front-proxy-client" "/CN=front-proxy-client" for host in $MASTERS; do cn="${host%%.*}" diff --git a/roles/kubernetes/secrets/tasks/check-certs.yml b/roles/kubernetes/secrets/tasks/check-certs.yml index 07820edf7..110ffa898 100644 --- a/roles/kubernetes/secrets/tasks/check-certs.yml +++ b/roles/kubernetes/secrets/tasks/check-certs.yml @@ -48,6 +48,8 @@ '{{ kube_cert_dir }}/kube-scheduler-key.pem', '{{ kube_cert_dir }}/kube-controller-manager.pem', '{{ kube_cert_dir }}/kube-controller-manager-key.pem', + '{{ kube_cert_dir }}/front-proxy-ca.pem', + '{{ kube_cert_dir }}/front-proxy-ca-key.pem', '{{ kube_cert_dir }}/front-proxy-client.pem', '{{ kube_cert_dir }}/front-proxy-client-key.pem', '{{ kube_cert_dir }}/service-account-key.pem', @@ -72,6 +74,7 @@ {% for cert in ['apiserver.pem', 'apiserver-key.pem', 'kube-scheduler.pem','kube-scheduler-key.pem', 'kube-controller-manager.pem','kube-controller-manager-key.pem', + 'front-proxy-ca.pem','front-proxy-ca-key.pem', 'front-proxy-client.pem','front-proxy-client-key.pem', 'service-account-key.pem'] -%} {% set cert_file = "%s/%s.pem"|format(kube_cert_dir, cert) %} diff --git a/roles/kubernetes/secrets/tasks/gen_certs_script.yml b/roles/kubernetes/secrets/tasks/gen_certs_script.yml index c39f606ad..72ff6b469 100644 --- a/roles/kubernetes/secrets/tasks/gen_certs_script.yml +++ b/roles/kubernetes/secrets/tasks/gen_certs_script.yml @@ -73,6 +73,8 @@ 'kube-scheduler-key.pem', 'kube-controller-manager.pem', 'kube-controller-manager-key.pem', + 'front-proxy-ca.pem', + 'front-proxy-ca-key.pem', 'front-proxy-client.pem', 'front-proxy-client-key.pem', 'service-account-key.pem', @@ -85,6 +87,8 @@ 'admin-{{ inventory_hostname }}-key.pem', 'apiserver.pem', 'apiserver-key.pem', + 'front-proxy-ca.pem', + 'front-proxy-ca-key.pem', 'front-proxy-client.pem', 'front-proxy-client-key.pem', 'service-account-key.pem', diff --git a/roles/kubernetes/secrets/tasks/gen_certs_vault.yml b/roles/kubernetes/secrets/tasks/gen_certs_vault.yml index cc16b749b..05afdfcf8 100644 --- a/roles/kubernetes/secrets/tasks/gen_certs_vault.yml +++ b/roles/kubernetes/secrets/tasks/gen_certs_vault.yml @@ -98,6 +98,8 @@ - include_tasks: ../../../vault/tasks/shared/issue_cert.yml vars: issue_cert_common_name: "front-proxy-client" + issue_cert_copy_ca: "{{ item == kube_front_proxy_clients_certs_needed|first }}" + issue_cert_ca_filename: front-proxy-ca.pem issue_cert_alt_names: "{{ kube_cert_alt_names }}" issue_cert_file_group: "{{ kube_cert_group }}" issue_cert_file_owner: kube @@ -115,7 +117,7 @@ issue_cert_path: "{{ item }}" issue_cert_role: front-proxy-client issue_cert_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}" - issue_cert_mount_path: "{{ kube_vault_mount_path }}" + issue_cert_mount_path: "{{ front_proxy_vault_mount_path }}" with_items: "{{ kube_front_proxy_clients_certs_needed|d([]) }}" when: inventory_hostname in groups['kube-master'] notify: set secret_changed diff --git a/roles/kubernetes/secrets/tasks/sync_kube_master_certs.yml b/roles/kubernetes/secrets/tasks/sync_kube_master_certs.yml index 02c512a4e..50e1a01e7 100644 --- a/roles/kubernetes/secrets/tasks/sync_kube_master_certs.yml +++ b/roles/kubernetes/secrets/tasks/sync_kube_master_certs.yml @@ -44,6 +44,18 @@ set_fact: sync_file_results: [] +- include_tasks: ../../../vault/tasks/shared/sync_file.yml + vars: + sync_file: front-proxy-ca.pem + sync_file_dir: "{{ kube_cert_dir }}" + sync_file_group: "{{ kube_cert_group }}" + sync_file_hosts: "{{ groups['kube-master'] }}" + sync_file_owner: kube + +- name: sync_kube_master_certs | Unset sync_file_results after front-proxy-ca.pem + set_fact: + sync_file_results: [] + - include_tasks: ../../../vault/tasks/shared/sync_file.yml vars: sync_file: "{{ item }}" diff --git a/roles/vault/defaults/main.yml b/roles/vault/defaults/main.yml index 8e5ad08a0..f19c73438 100644 --- a/roles/vault/defaults/main.yml +++ b/roles/vault/defaults/main.yml @@ -97,6 +97,11 @@ vault_ca_options: format: pem ttl: "{{ vault_max_lease_ttl }}" exclude_cn_from_sans: true + front_proxy: + common_name: front-proxy + format: pem + ttl: "{{ vault_max_lease_ttl }}" + exclude_cn_from_sans: true vault_client_headers: Accept: "application/json" @@ -164,11 +169,18 @@ vault_pki_mounts: allow_any_name: true enforce_hostnames: false organization: "system:node-proxier" + front_proxy: + name: front-proxy + default_lease_ttl: "{{ vault_default_lease_ttl }}" + max_lease_ttl: "{{ vault_max_lease_ttl }}" + description: "Kubernetes Front Proxy CA" + cert_dir: "{{ vault_kube_cert_dir }}" + roles: - name: front-proxy-client group: k8s-cluster - password: "{{ lookup('password', inventory_dir + '/credentials/vault/kube-proxy.creds length=15') }}" + password: "{{ lookup('password', inventory_dir + '/credentials/vault/front-proxy-client.creds length=15') }}" policy_rules: default role_options: allow_any_name: true enforce_hostnames: false - organization: "system:front-proxy" + organization: "system:front-proxy" \ No newline at end of file diff --git a/roles/vault/tasks/cluster/create_mounts.yml b/roles/vault/tasks/cluster/create_mounts.yml index c6e075698..087430942 100644 --- a/roles/vault/tasks/cluster/create_mounts.yml +++ b/roles/vault/tasks/cluster/create_mounts.yml @@ -6,8 +6,9 @@ create_mount_max_lease_ttl: "{{ item.max_lease_ttl }}" create_mount_description: "{{ item.description }}" create_mount_cert_dir: "{{ item.cert_dir }}" - create_mount_config_ca_needed: item.name != vault_pki_mounts.kube.name + create_mount_config_ca_needed: item.name != vault_pki_mounts.kube.name and item.name != vault_pki_mounts.front_proxy.name with_items: - "{{ vault_pki_mounts.vault }}" - "{{ vault_pki_mounts.etcd }}" - "{{ vault_pki_mounts.kube }}" + - "{{ vault_pki_mounts.front_proxy }}" diff --git a/roles/vault/tasks/cluster/main.yml b/roles/vault/tasks/cluster/main.yml index 65b9dae9b..7f535d068 100644 --- a/roles/vault/tasks/cluster/main.yml +++ b/roles/vault/tasks/cluster/main.yml @@ -35,6 +35,14 @@ gen_ca_copy_group: "kube-master" when: inventory_hostname in groups.vault +- include_tasks: ../shared/gen_ca.yml + vars: + gen_ca_cert_dir: "{{ vault_pki_mounts.front_proxy.cert_dir }}" + gen_ca_mount_path: "{{ vault_pki_mounts.front_proxy.name }}" + gen_ca_vault_headers: "{{ vault_headers }}" + gen_ca_vault_options: "{{ vault_ca_options.front_proxy }}" + when: inventory_hostname in groups.vault + - include_tasks: ../shared/auth_backend.yml vars: auth_backend_description: A Username/Password Auth Backend primarily used for services needing to issue certificates @@ -47,6 +55,7 @@ - "{{ vault_pki_mounts.vault }}" - "{{ vault_pki_mounts.etcd }}" - "{{ vault_pki_mounts.kube }}" + - "{{ vault_pki_mounts.front_proxy }}" loop_control: loop_var: mount when: inventory_hostname in groups.vault diff --git a/roles/vault/tasks/shared/issue_cert.yml b/roles/vault/tasks/shared/issue_cert.yml index 1ba90ea77..36a42efaa 100644 --- a/roles/vault/tasks/shared/issue_cert.yml +++ b/roles/vault/tasks/shared/issue_cert.yml @@ -6,6 +6,7 @@ # issue_cert_alt_name: Requested Subject Alternative Names, in a list. # issue_cert_common_name: Common Name included in the cert # issue_cert_copy_ca: Copy issuing CA cert needed +# issue_cert_ca_filename: Filename for copied issuing CA cert (default ca.pem) # issue_cert_dir_mode: Mode of the placed cert directory # issue_cert_file_group: Group of the placed cert file and directory # issue_cert_file_mode: Mode of the placed cert file @@ -100,7 +101,7 @@ - name: issue_cert | Copy issuing CA cert copy: content: "{{ issue_cert_result['json']['data']['issuing_ca'] }}\n" - dest: "{{ issue_cert_path | dirname }}/ca.pem" + dest: "{{ issue_cert_path | dirname }}/{{ issue_cert_ca_filename | default('ca.pem') }}" group: "{{ issue_cert_file_group | d('root' )}}" mode: "{{ issue_cert_file_mode | d('0644') }}" owner: "{{ issue_cert_file_owner | d('root') }}"