Home > front end >  Terraform self signed certificate results in "Dial x509: certificate signed by unknown authorit
Terraform self signed certificate results in "Dial x509: certificate signed by unknown authorit

Time:01-23

I'm generating a self signed certificate to secure a Redis container connection in a testing environment in Terraform:

Here are my resources:

resource "tls_private_key" "private_key" {
  algorithm = "RSA"
}

resource "tls_self_signed_cert" "signed_cert" {
  private_key_pem       = tls_private_key.private_key.private_key_pem
  ip_addresses          = ["0.0.0.0", "127.0.0.1"]
  validity_period_hours = 6
  early_renewal_hours   = 1

  subject {
    organization = "example"
  }

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

Here is my Dockerfile:

FROM redis:alpine

RUN apk update && apk add ca-certificates && update-ca-certificates

COPY ./redis.conf /etc/redis.conf

COPY ./redis.crt /redis.crt

COPY ./redis.key /redis.key

CMD ["redis-server", "/etc/redis.conf"]

And here is my redis.conf file:

requirepass "password"
port 0
tls-port 6379
tls-cert-file /redis.crt
tls-ca-cert-file /redis.crt
tls-key-file /redis.key

I use the same file for tls-ca-cert-file and tls-cert-file because this is a self signed certificate, and redis requires the tls-ca-cert-file to be set.

Now when I try to login with redli I have the following error:

$ redli -a "password" --tls
... Dial x509: certificate signed by unknown authority

What am I missing?

I have also tried to use the --skipverify flag of redli with no results:

$ redli -a password --tls --skipverify
... Dial remote error: tls: certificate required

CodePudding user response:

It turns out that Redis by default accepts only mutual authentication.

In order to fix this, I added tls-auth-clients no to my redis.conf file.

I also updated how the certificates are generated from Terraform:

resource "tls_private_key" "ca_private_key" {
  algorithm = "RSA"
}

resource "tls_private_key" "cert_private_key" {
  algorithm = "RSA"
}

resource "tls_self_signed_cert" "ca_cert" {
  # Five days should be enough for a PR
  validity_period_hours = 120
  early_renewal_hours   = 1
  is_ca_certificate     = true
  private_key_pem       = tls_private_key.ca_private_key.private_key_pem

  allowed_uses = [
    "cert_signing",
    "digital_signature"
  ]

  subject {
    common_name  = "previews_ca"
    organization = "Example"
  }
}

resource "tls_cert_request" "cert_request" {
  private_key_pem = tls_private_key.cert_private_key.private_key_pem
  ip_addresses    = ["0.0.0.0", "127.0.0.1"]
  dns_names       = ["*.${var.region}.compute.amazonaws.com"]

  subject {
    common_name  = "previews"
    organization = "Example"
  }
}

resource "tls_locally_signed_cert" "cert" {
  # Five days should be enough for a PR
  validity_period_hours = 120
  early_renewal_hours   = 1
  cert_request_pem      = tls_cert_request.cert_request.cert_request_pem
  ca_private_key_pem    = tls_private_key.ca_private_key.private_key_pem
  ca_cert_pem           = tls_self_signed_cert.ca_cert.cert_pem

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

locals {
  tls_cert_private_key = tls_private_key.cert_private_key.private_key_pem
  tls_cert             = tls_locally_signed_cert.cert.cert_pem
  tls_ca_cert          = ls_self_signed_cert.ca_cert.cert_pem
}

Now I can correctly connect with redli:

$ redli -a password  --tls --skipverify -h foo.eu-west-1.compute.amazonaws.com
Connected to 7.0.8
> ping
PONG

Please look at the --skipverify flag. It is needed because of the ca authority:

$ redli -a passwowrd  --tls -h foo.eu-west-1.compute.amazonaws.com
2023/01/20 14:15:11 Dial x509: certificate signed by unknown authority

If I want to accept the ca authority I have to run:

# trust anchor ca.crt

But this in my Arch Linux, in your machine it could be something else.

In my case I generate one certificate for each EC2 generated by a github action that runs when a PR is opened. So I won't be able to add each certificate to the trusted store.

My docker-compose.yaml file:

services:
  redis:
      container_name: preview_redis
      image: redis:alpine
      command: /etc/redis.conf
      volumes:
        - ./tls:/tls
        - ./redis.conf:/etc/redis.conf
      ports:
        - 6379:6379

My redis.conf file:

requirepass "password"
port 0
tls-port 6379
tls-cert-file /tls/redis.crt
tls-key-file /tls/redis.key
tls-ca-cert-dir /tls/ca.crt
tls-auth-clients no
  • Related