From 6e8f0f9a1da81f2caf930d138dc5b2bfa8901a69 Mon Sep 17 00:00:00 2001 From: Dalton Hubble Date: Tue, 6 Jun 2017 17:46:44 -0700 Subject: [PATCH] Generate on-host etcd CA, client, and peer TLS cert/key pairs --- README.md | 2 +- assets.tf | 10 ++ .../bootstrap-apiserver.yaml | 3 + resources/manifests/kube-apiserver.yaml | 3 + terraform.tfvars.example | 2 +- tls-etcd.tf | 124 ++++++++++++++++++ tls.tf => tls-k8s.tf | 0 7 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tls-etcd.tf rename tls.tf => tls-k8s.tf (100%) diff --git a/README.md b/README.md index a9534b5..791d20b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Render bootkube assets directly with bootkube v0.4.2. #### On-host etcd ```sh -bootkube render --asset-dir=assets --api-servers=https://node1.example.com:443 --api-server-alt-names=DNS=node1.example.com --etcd-servers=http://127.0.0.1:2379 +bootkube render --asset-dir=assets --api-servers=https://node1.example.com:443 --api-server-alt-names=DNS=node1.example.com --etcd-servers=https://node1.example.com:2379 ``` Compare assets. The only diffs you should see are TLS credentials. diff --git a/assets.tf b/assets.tf index 7086078..9f94ff3 100644 --- a/assets.tf +++ b/assets.tf @@ -10,6 +10,11 @@ resource "template_dir" "bootstrap-manifests" { cloud_provider = "${var.cloud_provider}" pod_cidr = "${var.pod_cidr}" service_cidr = "${var.service_cidr}" + + # TODO: Enable TLS for self-hosted etcd and remove these variables + etcd_ca_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-cafile=/etc/kubernetes/secrets/etcd-ca.crt"}" + etcd_client_cert_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-certfile=/etc/kubernetes/secrets/etcd-client.crt"}" + etcd_client_key_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key"}" } } @@ -33,6 +38,11 @@ resource "template_dir" "manifests" { apiserver_cert = "${base64encode(tls_locally_signed_cert.apiserver.cert_pem)}" serviceaccount_pub = "${base64encode(tls_private_key.service-account.public_key_pem)}" serviceaccount_key = "${base64encode(tls_private_key.service-account.private_key_pem)}" + + # TODO: Enable TLS for self-hosted etcd and remove these variables + etcd_ca_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-cafile=/etc/kubernetes/secrets/etcd-ca.crt"}" + etcd_client_cert_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-certfile=/etc/kubernetes/secrets/etcd-client.crt"}" + etcd_client_key_flag = "${var.experimental_self_hosted_etcd ? "# etcd TLS not supported" : "- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key"}" } } diff --git a/resources/bootstrap-manifests/bootstrap-apiserver.yaml b/resources/bootstrap-manifests/bootstrap-apiserver.yaml index 6586471..3ac6874 100644 --- a/resources/bootstrap-manifests/bootstrap-apiserver.yaml +++ b/resources/bootstrap-manifests/bootstrap-apiserver.yaml @@ -21,6 +21,9 @@ spec: - --bind-address=0.0.0.0 - --client-ca-file=/etc/kubernetes/secrets/ca.crt - --etcd-servers=${etcd_servers} + ${etcd_ca_flag} + ${etcd_client_cert_flag} + ${etcd_client_key_flag} - --insecure-port=0 - --kubelet-client-certificate=/etc/kubernetes/secrets/apiserver.crt - --kubelet-client-key=/etc/kubernetes/secrets/apiserver.key diff --git a/resources/manifests/kube-apiserver.yaml b/resources/manifests/kube-apiserver.yaml index 6bc72b3..9492504 100644 --- a/resources/manifests/kube-apiserver.yaml +++ b/resources/manifests/kube-apiserver.yaml @@ -33,6 +33,9 @@ spec: - --authorization-mode=RBAC - --bind-address=0.0.0.0 - --client-ca-file=/etc/kubernetes/secrets/ca.crt + ${etcd_ca_flag} + ${etcd_client_cert_flag} + ${etcd_client_key_flag} - --cloud-provider=${cloud_provider} - --etcd-servers=${etcd_servers} - --insecure-port=0 diff --git a/terraform.tfvars.example b/terraform.tfvars.example index 68abb7d..2360356 100644 --- a/terraform.tfvars.example +++ b/terraform.tfvars.example @@ -1,5 +1,5 @@ cluster_name = "example" api_servers = ["node1.example.com"] -etcd_servers = ["http://127.0.0.1:2379"] +etcd_servers = ["https://node1.example.com:2379"] asset_dir = "/home/core/clusters/mycluster" experimental_self_hosted_etcd = false diff --git a/tls-etcd.tf b/tls-etcd.tf new file mode 100644 index 0000000..99e7604 --- /dev/null +++ b/tls-etcd.tf @@ -0,0 +1,124 @@ +# etcd-ca.crt +resource "local_file" "etcd_ca_crt" { + content = "${tls_self_signed_cert.etcd-ca.cert_pem}" + filename = "${var.asset_dir}/tls/etcd-ca.crt" +} + +# etcd-client.crt +resource "local_file" "etcd_client_crt" { + content = "${tls_locally_signed_cert.client.cert_pem}" + filename = "${var.asset_dir}/tls/etcd-client.crt" +} + +# etcd-client.key +resource "local_file" "etcd_client_key" { + content = "${tls_private_key.client.private_key_pem}" + filename = "${var.asset_dir}/tls/etcd-client.key" +} + +# etcd-peer.crt +resource "local_file" "etcd_peer_crt" { + content = "${tls_locally_signed_cert.peer.cert_pem}" + filename = "${var.asset_dir}/tls/etcd-peer.crt" +} + +# etcd-peer.key +resource "local_file" "etcd_peer_key" { + content = "${tls_private_key.peer.private_key_pem}" + filename = "${var.asset_dir}/tls/etcd-peer.key" +} + +# certificates and keys + +resource "tls_private_key" "etcd-ca" { + algorithm = "RSA" + rsa_bits = "2048" +} + +resource "tls_self_signed_cert" "etcd-ca" { + key_algorithm = "${tls_private_key.etcd-ca.algorithm}" + private_key_pem = "${tls_private_key.etcd-ca.private_key_pem}" + + subject { + common_name = "etcd-ca" + organization = "etcd" + } + + is_ca_certificate = true + validity_period_hours = 8760 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "cert_signing", + ] +} + +resource "tls_private_key" "client" { + algorithm = "RSA" + rsa_bits = "2048" +} + +resource "tls_cert_request" "client" { + key_algorithm = "${tls_private_key.client.algorithm}" + private_key_pem = "${tls_private_key.client.private_key_pem}" + + subject { + common_name = "etcd" + organization = "etcd" + } + + dns_names = ["${var.etcd_servers}"] +} + +resource "tls_locally_signed_cert" "client" { + cert_request_pem = "${tls_cert_request.client.cert_request_pem}" + + ca_key_algorithm = "${join(" ", tls_self_signed_cert.etcd-ca.*.key_algorithm)}" + ca_private_key_pem = "${join(" ", tls_private_key.etcd-ca.*.private_key_pem)}" + ca_cert_pem = "${join(" ", tls_self_signed_cert.etcd-ca.*.cert_pem)}" + + validity_period_hours = 8760 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + "client_auth", + ] +} + +resource "tls_private_key" "peer" { + algorithm = "RSA" + rsa_bits = "2048" +} + +resource "tls_cert_request" "peer" { + key_algorithm = "${tls_private_key.peer.algorithm}" + private_key_pem = "${tls_private_key.peer.private_key_pem}" + + subject { + common_name = "etcd" + organization = "etcd" + } + + dns_names = ["${var.etcd_servers}"] +} + +resource "tls_locally_signed_cert" "peer" { + cert_request_pem = "${tls_cert_request.peer.cert_request_pem}" + + ca_key_algorithm = "${join(" ", tls_self_signed_cert.etcd-ca.*.key_algorithm)}" + ca_private_key_pem = "${join(" ", tls_private_key.etcd-ca.*.private_key_pem)}" + ca_cert_pem = "${join(" ", tls_self_signed_cert.etcd-ca.*.cert_pem)}" + + validity_period_hours = 8760 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + "client_auth", + ] +} + diff --git a/tls.tf b/tls-k8s.tf similarity index 100% rename from tls.tf rename to tls-k8s.tf