Skip to content

Commit

Permalink
secure etcd
Browse files Browse the repository at this point in the history
  • Loading branch information
pstadler committed Dec 20, 2018
1 parent d122c62 commit 347818e
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 14 deletions.
15 changes: 9 additions & 6 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,13 @@ module "etcd" {
module "kubernetes" {
source = "./service/kubernetes"

count = "${var.node_count}"
connections = "${module.provider.public_ips}"
cluster_name = "${var.domain}"
vpn_interface = "${module.wireguard.vpn_interface}"
vpn_ips = "${module.wireguard.vpn_ips}"
etcd_endpoints = "${module.etcd.endpoints}"
count = "${var.node_count}"
connections = "${module.provider.public_ips}"
cluster_name = "${var.domain}"
vpn_interface = "${module.wireguard.vpn_interface}"
vpn_ips = "${module.wireguard.vpn_ips}"
etcd_endpoints = "${module.etcd.endpoints}"
etcd_ca_certificate = "${module.etcd.ca_certificate}"
etcd_client_certificate = "${module.etcd.client_certificate}"
etcd_client_key = "${module.etcd.client_key}"
}
233 changes: 233 additions & 0 deletions service/etcd/certs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
variable "certificates_validity_hours" {
default = 87600 # 10 years
}

variable "certificates_directory" {
default = "/etc/etcd"
}

locals {
ca_certificate = "${var.certificates_directory}/etcd-ca.pem"
client_certificate = "${var.certificates_directory}/client.pem"
client_key = "${var.certificates_directory}/client.key"
server_certificate = "${var.certificates_directory}/server.pem"
server_key = "${var.certificates_directory}/server.key"
peer_certificate = "${var.certificates_directory}/peer.pem"
peer_key = "${var.certificates_directory}/peer.key"

ip_addresses = ["127.0.0.1", "${var.vpn_ips}"]
dns_names = ["localhost", "${var.hostnames}"]
}

resource "null_resource" "etcd-certs" {
count = "${var.count}"

connection {
host = "${element(var.connections, count.index)}"
user = "root"
agent = true
}

provisioner "remote-exec" {
inline = [
"mkdir -p ${var.certificates_directory}",
]
}

provisioner "file" {
content = "${tls_self_signed_cert.etcd-ca.cert_pem}"
destination = "${local.ca_certificate}"
}

provisioner "file" {
content = "${tls_locally_signed_cert.client.cert_pem}"
destination = "${local.client_certificate}"
}

provisioner "file" {
content = "${tls_private_key.client.private_key_pem}"
destination = "${local.client_key}"
}

provisioner "file" {
content = "${tls_locally_signed_cert.server.cert_pem}"
destination = "${local.server_certificate}"
}

provisioner "file" {
content = "${tls_private_key.server.private_key_pem}"
destination = "${local.server_key}"
}

provisioner "file" {
content = "${tls_locally_signed_cert.peer.cert_pem}"
destination = "${local.peer_certificate}"
}

provisioner "file" {
content = "${tls_private_key.peer.private_key_pem}"
destination = "${local.peer_key}"
}

provisioner "remote-exec" {
inline = [
"chmod -R 600 ${var.certificates_directory}/*.key",
]
}
}

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 = "${var.certificates_validity_hours}"

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-client"
organization = "etcd"
}

ip_addresses = ["${local.ip_addresses}"]
dns_names = ["${local.dns_names}"]
}

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 = "${var.certificates_validity_hours}"

allowed_uses = [
"key_encipherment",
"digital_signature",
"client_auth",
]
}

resource "tls_private_key" "server" {
algorithm = "RSA"
rsa_bits = "2048"
}

resource "tls_cert_request" "server" {
key_algorithm = "${tls_private_key.server.algorithm}"
private_key_pem = "${tls_private_key.server.private_key_pem}"

subject {
common_name = "etcd-server"
organization = "etcd"
}

ip_addresses = ["${local.ip_addresses}"]
dns_names = ["${local.dns_names}"]
}

resource "tls_locally_signed_cert" "server" {
cert_request_pem = "${tls_cert_request.server.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 = "${var.certificates_validity_hours}"

allowed_uses = [
"key_encipherment",
"digital_signature",
"client_auth",
"server_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-peer"
organization = "etcd"
}

ip_addresses = ["${local.ip_addresses}"]
dns_names = ["${local.dns_names}"]
}

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 = "${var.certificates_validity_hours}"

allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
"client_auth",
]
}

output "ca_certificate" {
value = "${local.ca_certificate}"
}

output "client_certificate" {
value = "${local.client_certificate}"
}

output "client_key" {
value = "${local.client_key}"
}

output "server_certificate" {
value = "${local.server_certificate}"
}

output "server_key" {
value = "${local.server_key}"
}

output "peer_certificate" {
value = "${local.peer_certificate}"
}

output "peer_key" {
value = "${local.peer_key}"
}
18 changes: 12 additions & 6 deletions service/etcd/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ variable "version" {
}

resource "null_resource" "etcd" {
count = "${var.count}"
depends_on = ["null_resource.etcd-certs"]
count = "${var.count}"

triggers = {
template = "${join("", data.template_file.etcd-service.*.rendered)}"
Expand Down Expand Up @@ -59,10 +60,15 @@ data "template_file" "etcd-service" {

vars {
hostname = "${element(var.hostnames, count.index)}"
intial_cluster = "${join(",", formatlist("%s=http://%s:2380", var.hostnames, var.vpn_ips))}"
listen_client_urls = "http://${element(var.vpn_ips, count.index)}:2379"
advertise_client_urls = "http://${element(var.vpn_ips, count.index)}:2379"
listen_peer_urls = "http://${element(var.vpn_ips, count.index)}:2380"
intial_cluster = "${join(",", formatlist("%s=https://%s:2380", var.hostnames, var.vpn_ips))}"
listen_client_urls = "https://${element(var.vpn_ips, count.index)}:2379"
advertise_client_urls = "https://${element(var.vpn_ips, count.index)}:2379"
listen_peer_urls = "https://${element(var.vpn_ips, count.index)}:2380"
ca_certificate = "${local.ca_certificate}"
server_certificate = "${local.server_certificate}"
server_key = "${local.server_key}"
peer_certificate = "${local.peer_certificate}"
peer_key = "${local.peer_key}"
vpn_unit = "${var.vpn_unit}"
}
}
Expand All @@ -79,7 +85,7 @@ data "null_data_source" "endpoints" {
depends_on = ["null_resource.etcd"]

inputs = {
list = "${join(",", formatlist("http://%s:2379", var.vpn_ips))}"
list = "${join(",", formatlist("https://%s:2379", var.vpn_ips))}"
}
}

Expand Down
10 changes: 9 additions & 1 deletion service/etcd/templates/etcd.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ After=network.target ${vpn_unit}
Type=notify
ExecStart=/opt/etcd/etcd --name ${hostname} \
--data-dir /var/lib/etcd \
--listen-client-urls "${listen_client_urls},http://localhost:2379" \
--listen-client-urls "${listen_client_urls},https://localhost:2379" \
--advertise-client-urls "${advertise_client_urls}" \
--listen-peer-urls "${listen_peer_urls}" \
--initial-cluster "${intial_cluster}" \
--initial-advertise-peer-urls "${listen_peer_urls}" \
--client-cert-auth=true \
--trusted-ca-file="${ca_certificate}" \
--cert-file="${server_certificate}" \
--key-file="${server_key}" \
--peer-client-cert-auth=true \
--peer-trusted-ca-file="${ca_certificate}" \
--peer-cert-file="${peer_certificate}" \
--peer-key-file="${peer_key}" \
--heartbeat-interval 200 \
--election-timeout 5000
Restart=always
Expand Down
17 changes: 16 additions & 1 deletion service/kubernetes/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ variable "etcd_endpoints" {
type = "list"
}

variable "etcd_ca_certificate" {
type = "string"
}

variable "etcd_client_certificate" {
type = "string"
}

variable "etcd_client_key" {
type = "string"
}

variable "overlay_interface" {
default = "weave"
}
Expand Down Expand Up @@ -72,8 +84,11 @@ data "template_file" "master-configuration" {

vars {
api_advertise_addresses = "${element(var.vpn_ips, 0)}"
etcd_endpoints = "- ${join("\n - ", var.etcd_endpoints)}"
cert_sans = "- ${element(var.connections, 0)}"
etcd_endpoints = "- ${join("\n - ", var.etcd_endpoints)}"
etcd_ca_certificate = "${var.etcd_ca_certificate}"
etcd_client_certificate = "${var.etcd_client_certificate}"
etcd_client_key = "${var.etcd_client_key}"
}
}

Expand Down
3 changes: 3 additions & 0 deletions service/kubernetes/templates/master-configuration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ etcd:
external:
endpoints:
${etcd_endpoints}
caFile: ${etcd_ca_certificate}
certFile: ${etcd_client_certificate}
keyFile: ${etcd_client_key}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
Expand Down

0 comments on commit 347818e

Please sign in to comment.