TLS Configuration
TLS SSL client authentication mTLS client certificates securityBelow you can find some advanced TLS functionality you can enable.
TLS Client Authentication
Section titled “TLS Client Authentication”With TLS Client Authentication you can configure our platform to require clients to include a client certificate signed by a CA of your choosing. If the client doesn’t provide a certificate or the certificate isn’t signed by the correct CA the request will be denied. If the request includes a valid certificate the request will be forwarded to your service and will include information about the TLS configuration.
To configure TLS client authentication you can use the configuration below:
[[functions.resources.ingress]]fqdn = ["func.acme.com"]
[functions.resources.networking.ingresses.tls]clientCA = "{{ secrets.client_ca }}"Headers
Section titled “Headers”The following headers will be added to all successful requests:
ssl-client-cert: The client cetificate that was usedssl-client-issuer-dn: Client certificate’s issuer DNssl-client-subject-dn: Client certificate;s distinguished namessl-client-verify: Result of the operation. As we only forward requests on success the value should always beSUCCESS.
Here is a quick guide on how to enable TLS client authentication for the functions service using self-signed certificates.
Creating the CA
Section titled “Creating the CA”First we need to create a CA that will be used to sign and validate the client certificates.
Generate the CA private key
Section titled “Generate the CA private key”First, we need to create a private key for our Certificate Authority. We’ll use a 4096-bit RSA key for strong security.
openssl genrsa -aes256 -out ca.key 4096This command will prompt you to enter a passphrase to protect the CA private key. Make sure to choose a strong passphrase and keep it safe.
Create the CA certificate
Section titled “Create the CA certificate”Now that we have the private key, let’s create a self-signed CA certificate:
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crtThis command will prompt you for various details to include in the certificate. The most important field is the Common Name (CN), which should be a descriptive name for your CA.
The resulting ca.key file will be needed later to sign client certificates while the result ca.crt will be needed to validate them.
Creating client certificates
Section titled “Creating client certificates”Now we can proceed to create client certificats. You can repeat the steps below to create as many as you need.
Generate a private key for the client
Section titled “Generate a private key for the client”First, we’ll create a private key for the client certificate:
openssl genrsa -out client.key 2048Create a Certificate Signing Request (CSR) for the client
Section titled “Create a Certificate Signing Request (CSR) for the client”Now, we’ll create a CSR for the client certificate:
openssl req -new -key client.key -out client.csrFill in the prompted information. The Common Name (CN) should typically be the name of the client or user.
Create a configuration file for the client certificate
Section titled “Create a configuration file for the client certificate”Create a file named client.ext with the following content:
authorityKeyIdentifier=keyid,issuerbasicConstraints=CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentextendedKeyUsage = clientAuthThis configuration specifies that the certificate is for client authentication.
Generate the client certificate
Section titled “Generate the client certificate”Now, we’ll use our CA to sign the client certificate:
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256 -extfile client.extThis command will prompt you for the CA private key passphrase you set earlier.
The resulting client.key and client.crt files will be needed by the user to authenticate requests.
Configure your service
Section titled “Configure your service”With everything in place you can configure your service. Imagine we have an already deployed project and we want to enable this for all functions. First we will head to the dashboard -> project -> settings -> secrets and create a new secret named CLIENT_CA with the contents of the ca.crt file. Afterwards we will deploy the following configuration:
[[functions.resources.networking.ingresses]]fqdn = [ "functions.acme.com" ]
[functions.resources.networking.ingresses.tls]clientCA = "{{ secrets.CLIENT_CA }}"Profit
Section titled “Profit”Our project has a function that echoes back request parameters, including headers. We will use this to inspect the TLS headers added to the request and that you can use for further validation if you need it. First, we can query the function without passing any client certificate:
$ curl https://functions.acme.com/v1/echo<html><head><title>400 No required SSL certificate was sent</title></head><body><center><h1>400 Bad Request</h1></center><center>No required SSL certificate was sent</center><hr><center>nginx</center></body></html>As you can see the request was rejected. Now we can add a valid client certificate and the corresponding key to the request:
$ curl --cert client.crt --key client.key https://functions.acme.com/v1/echo | jq{ "headers": { "accept": "*/*", "ssl-client-cert": "-----BEGIN%20CERTIFICATE-----...ommitted for brevity...-----END%20CERTIFICATE-----%0A", "ssl-client-issuer-dn": "OU=IT,O=Acme Org.,L=Stockholm,ST=Stockholm,C=SE", "ssl-client-subject-dn": "emailAddress=jane@acme.org,OU=IT,O=Acme Org.,L=Sausalito,ST=California,C=US", "ssl-client-verify": "SUCCESS", "user-agent": "curl/8.7.1", "x-forwarded-for": "2001:8b1:8ac9:4100:46b1:3412:1342:9319", "x-forwarded-host": "functions.acme.com", "x-forwarded-port": "443", "x-forwarded-proto": "https", "x-forwarded-scheme": "https", "x-real-ip": "2001:8b1:8ac9:4100:46b1:3412:1342:9319", "x-request-id": "8f80c26ee873bfc9db7ce9073eecd17a", "x-scheme": "https", "content-length": 0 }, "query": {}, "node": "v20.17.0", "arch": "arm64"}With a valid certificate you can see the request went through and it includes the ssl-client-* headers providing additional information about it.