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