Skip to content

Instantly share code, notes, and snippets.

@timflannagan
Last active June 28, 2019 14:25
Show Gist options
  • Save timflannagan/5b9cd5425eb5c4b85c804f034f7da9ea to your computer and use it in GitHub Desktop.
Save timflannagan/5b9cd5425eb5c4b85c804f034f7da9ea to your computer and use it in GitHub Desktop.
Configuring Presto to work with TLS Authentication

Overview of Process:

In able to enable Presto to work with TLS and authentication, we first need to create server, client, and CA certificates and keys. Then, we need to create multiple secrets locally that store these certificates and keys. Once that is done we can move on to configuring our k8s resources and custom MeteringConfig resource.

Setup metering namespace:

export METERING_NAMESPACE="your namespace"

Creating the necessary certificates

Generate our RSA private key for root CA:

openssl genrsa -out ca.key 2048

Generate our root CA certificate:

openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/C=US/ST=Massachusetts/L=Lowell/O=Presto /OU=Presto Test/CN=Root Presto CA" 

The command will prompt us to provide some information, most importantly is the CN. Here is a snippet of the output from openssl x509 -noout -text -in ca.crt of my local root CA:

Issuer: C = US, ST = Massachusetts, L = Lowell, O = Presto, OU = Presto Test, CN = Root Presto CA
Validity
   Not Before: Jun  6 22:01:36 2019 GMT
   Not After : Jun  5 22:01:36 2020 GMT
Subject: C = US, ST = Massachusetts, L = Lowell, O = Presto, OU = Presto Test, CN = Root Presto CA

You can configure the distinguished name to be whatever you want, or model it after the output of the snippet above.

Generate RSA private key for server:

openssl genrsa -out server.key 2048

Now that we have a server private key, we can generate a certificate signing request (CSR):

openssl req -new -key server.key -out server.csr -subj "/C=US/ST=Massachusetts/L=Boston/O=Red Hat/OU=Presto/CN=*.presto-nodes" 

Again, we will need to fill out some information. Configure the CN to be *.presto-nodes. Here is the subject of my local server.csr:

Subject: C = US, ST = Massachusetts, L = Boston, O = Red Hat, OU = Presto, CN = *.presto-nodes

Again, you can configure the principal however you want, just make note that the CN needs to be *.presto-nodes.

We now need to create a configuration file for the server so we can define the SAN extensions, which are needed in the server certificate:

# save this as "server.conf"
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alternate_names

[alternate_names]
DNS.2 = *.presto-nodes.$METERING_NAMESPACE.svc.cluster.local
DNS.3 = presto
DNS.4 = *.presto-nodes

Generate a server certificate based on the server.csr:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile server.conf

Generate client certificates (this is based on https://gist.github.com/mtigas/952344#create-the-client-key-and-csr):

CLIENT_ID="01-coordinator"
CLIENT_SERIAL=01

openssl genrsa -out ${CLIENT_ID}.key 2048

Generate ${CLIENT_ID}.csr:

openssl req -new -key ${CLIENT_ID}.key -out ${CLIENT_ID}.csr -subj "/CN=coordinator.presto-nodes" 

Note that the common name (CN) doesn't have to match the CN of the root CA or server certificate, so you can make it something like coordinator or worker.presto-nodes to distinguish from other client certificates.

Generate ${CLIENT_ID}.crt:

openssl x509 -req -days 365 -in ${CLIENT_ID}.csr -CA ca.crt -CAkey ca.key -set_serial ${CLIENT_SERIAL} -out ${CLIENT_ID}.crt

Now, we should have a directory full of server.crt, server.key, ca.crt, ca.key, ${CLIENT_ID}.crt. and ${CLIENT_ID}.key (excluding the configuration files and CSRs)

Manually create the client certificates

kubectl create ns $METERING_NAMESPACE
# note that the current implementation was based on a TLS secret - which requires having a tls.key/tls.crt naming convention, but running this command is easier
kubectl -n $METERING_NAMESPACE create secret generic presto-tls --from-file=ca.crt=ca.crt --from-file=tls.crt=server.crt --from-file=tls.key=server.key
kubectl -n $METERING_NAMESPACE create secret generic presto-client-tls --from-file=tls.key=${CLIENT_ID}.key --from-file=tls.crt=${CLIENT_ID}.crt --from-file=ca.crt=ca.crt

Configure your meteringconfig to configure tls/auth:

cp manifests/metering-config/default.yaml metering-custom.yaml
export METERING_CR_FILE="metering-custom.yaml"

Here is the local version of my metering-custom.yaml

apiVersion: metering.openshift.io/v1alpha1
kind: MeteringConfig
metadata:
  name: "operator-metering"
spec:
  tls:
   enabled: false
 
  reporting-operator:
    spec:
      # note: the reporting operator and ansible operator images have been updated in master
      config:
        presto:
         tls:
           createSecret: false
           # this contains the server cert/key and ca cert
           secretName: presto-tls
         auth:
           enabled: true
           secretName: presto-client-tls
  presto:
    spec:
      presto:
        worker:
          replicas: 1
        config:
          tls:
            createSecret: false
            secretName: presto-tls
          auth:
            createSecret: false
            secretName: presto-client-tls

After copying my custom metering config, run this command to apply the changes:

kubectl -n $METERING_NAMESPACE apply -f metering-custom.yaml

Verifying everything works when TLS is enabled, but auth is disabled:

Need to change the two authentication fields controlling whether or not it's enabled so set presto.config.auth.enabled: false, and reporting-operator.spec.config.prestoAuth.enabled = false. We then need to re-apply the MeteringConfig:

kubectl -n $METERING_NAMESPACE apply -f metering-custom.yaml

Then, we need to update the resources:

./hack/openshift-install.sh

In order to verify that TLS works, I'd recommend checking the logs of the presto-coordinator-0 and reporting-operator* pods to ensure that there's no errors in the logs.

Verifying everything works when TLS and auth are enabled:

We can definitely tell that authentication is working properly if you try to view the presto UI on your browser and get a 401 (unauthorized error)

kubectl port-forward svc/presto 8080:8080

As that command is running, try to visit https://presto:8080

@pruan-rht
Copy link

We can avoid prompts with the -subj option like openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/C=US/ST=CA/L=Sunnvyale/O=RedHat/CN=*.presto-nodes"

@timflannagan
Copy link
Author

good idea - I'll update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment