TLS / SSL

The following sections describe how to configure TLS for Anchore API and/or Anchore Enterprise Services. Please note that the UI service currently does not support listening via TLS.

Internal TLS for Anchore Enterprise Services Helm deployments

graph TB
    subgraph External Traffic
        user[User]
        kubernetes[Ingress Controller]
    end

    subgraph Services with Internal TLS
        api[API]
        policy[Policy]
        catalog[Catalog]
        analyzer[Analyzer]
        reports[Reports]
        reportsworker[Reports Worker]
        notifications[Notifications]
        dataSyncer[Data Syncer]
        simplequeue[Simple Queue]
    end

    subgraph Services Without TLS
        ui[UI]
    end

    user -- HTTP/HTTPS --> kubernetes
    kubernetes -- HTTPS --> api
    kubernetes -- HTTP --> ui

    api <--> policy
    api <--> catalog
    api <--> analyzer
    api <--> reports
    api <--> reportsworker
    api <--> notifications
    api <--> dataSyncer
    api <--> simplequeue

    policy <--> catalog
    catalog <--> analyzer
    analyzer <--> reports
    reports <--> reportsworker
    reportsworker <--> notifications
    notifications <--> dataSyncer
    dataSyncer <--> simplequeue

The following will configure Anchore Enterprise internal services to communicate with one another via TLS.

This script is provided as a demonstration of how to generate certificates (generate-anchore-tls-certs.sh):

#!/bin/bash
export NAMESPACE="$1";
export RELEASE="$2";
export SANS="DNS:*.${NAMESPACE}.svc.cluster.local,DNS:${RELEASE}-enterprise-api,DNS:${RELEASE}-enterprise-catalog,DNS:${RELEASE}-enterprise-notifications,DNS:${RELEASE}-enterprise-policy,DNS:${RELEASE}-enterprise-reports,DNS:${RELEASE}-enterprise-reportsworker,DNS:${RELEASE}-enterprise-simplequeue,DNS:${RELEASE}-enterprise-ui,DNS:${RELEASE}-enterprise-datasyncer"
# NOTE: This ends up being the filename of resulting certificates
SERVER_NAME="anchore"

ANCHORE_TLS=./anchore-tls
SCRIPT=$(readlink -f "$0")
DIR=$(dirname "$SCRIPT")

echo "Making ANCHORE_TLS dir..."
mkdir -p ${ANCHORE_TLS}
cd ${ANCHORE_TLS}

# Customize as needed
CORPORATION=Anchore
GROUP=K8S
CITY=Atlanta
STATE=Georgia
COUNTRY=US

CERT_AUTH_PASS=`openssl rand -base64 32`
echo $CERT_AUTH_PASS > cert_auth_password
CERT_AUTH_PASS=`cat cert_auth_password`

# create the certificate authority
openssl \
  req \
  -subj "/CN=$SERVER_NAME.ca/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
  -new \
  -x509 \
  -passout pass:$CERT_AUTH_PASS \
  -keyout ca-cert.key \
  -out ca-cert.crt \
  -days 3650

# create client private key (used to decrypt the cert we get from the CA)
openssl genrsa -out $SERVER_NAME.key

# create the CSR(Certitificate Signing Request)
openssl \
  req \
  -new \
  -nodes \
  -subj "/CN=$SERVER_NAME/OU=$GROUP/O=$CORPORATION/L=$CITY/ST=$STATE/C=$COUNTRY" \
  -sha256 \
  -extensions v3_req \
  -reqexts SAN \
  -key $SERVER_NAME.key \
  -out $SERVER_NAME.csr \
  -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=$SANS")) \
  -days 3650

# sign the certificate with the certificate authority
openssl \
  x509 \
  -req \
  -days 3650 \
  -in $SERVER_NAME.csr \
  -CA ca-cert.crt \
  -CAkey ca-cert.key \
  -CAcreateserial \
  -out $SERVER_NAME.crt \
  -extfile <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=$SANS")) \
  -extensions SAN \
  -passin pass:$CERT_AUTH_PASS

# Create key pem
cat $SERVER_NAME.key > $SERVER_NAME-key.pem

# Create cert pem
cat $SERVER_NAME.crt > $SERVER_NAME.pem
cat ca-cert.crt >> $SERVER_NAME.pem
cd ..
cat << EOF > anchore-tls-certs.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: anchore-tls-certs
  namespace: $NAMESPACE
type: Opaque
data:
  internal-cert.pem: $(base64 anchore-tls/$SERVER_NAME.pem --wrap 0)
  internal-cert-key.pem: $(base64 anchore-tls/$SERVER_NAME-key.pem --wrap 0)
  ca.pem: $(base64 anchore-tls/ca-cert.crt --wrap 0)
EOF
kubectl apply -n $NAMESPACE -f anchore-tls-certs.yaml

If Custom CA certificates are required for LDAP or Postgres be sure to append them to the anchore-tls/ca-cert.crt & anchore-tls/anchore.pem file.

The script can be called as follows:


chmod +x generate-anchore-tls-certs.sh
# Provide values for your kubernetes namespace containing anchore and your helm release
./generate-anchore-tls-certs.sh $NAMESPACE $RELEASE

Make the following adjustments in your helm values file:

certStoreSecretName: anchore-tls-certs

anchoreConfig:
  internalServicesSSL:
    enabled: true
    verifyCerts: false
    certSecretKeyFileName: internal-cert-key.pem
    certSecretCertFileName: internal-cert.pem

ui:
  ldapsRootCaCertName: ca.pem

You will need to perform a Helm install or upgrade to apply all the changes and restart all the pods.

If using an ingress controller see the next section.

Separating API & UI Ingress for Helm deployments

If you are using ingress to access Anchore Enterprise API & Anchore Enterprise UI then you will need to seperate the ingress configuration if you configure either External or Internal TLS. Since API supports TLS and UI does not once TLS is enabled for API the ingress controller will need to send encrypted traffic to API and unencrypted traffic to UI.

Make the following change to your helm values file to configure the ingress to use TLS to communicate with the API service:

ingress:
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    # These are optional
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '600'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '600'
  uiHosts: []

Add an ingress directly in kubernetes for the UI:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: anchore-ingress-ui
  annotations:
    # These are optional
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '600'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '600'
spec:
  ingressClassName: nginx # NOTE: This could be another value such as alb
  tls: []
  rules:
    - host: anchore.yourdomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: anchore-enterprise-ui # Ensure this matches the name of the Anchore UI service
                port:
                  number: 80

Apply UI Ingress changes:

kubectl apply -n $NAMESPACE -f anchore-ingress-ui.yaml

External TLS for Anchore Enterprise API Service

Please note that configuring Internal TLS above also includes External TLS. If you performed the steps above then this is not necessary.

In the following example the external API service is configured to listen on port 443 and is configured with a certificate for its external hostname anchore.example.com

Each service published in the Anchore Enterprise configuration (apiext, catalog, simplequeue, analyzer, policy_engine and kubernetes_webhook) can be configured to use transport level security.

services:
  apiext:
    enabled: True
    endpoint_hostname: 'anchore.example.com'
    listen: '0.0.0.0'
    port: 443
    ssl_enable: True
    ssl_cert: '/config/anchore-ex.crt'
    ssl_key: '/config/anchore-ex.key'
    ssl_chain: '/config/anchore-ex.crt'
SettingNotes
enabledIf the service is enabled
endpoint_hostnameDNS name of service
listenIP address of interface on which the service should listen (use ‘0.0.0.0’ for all - default)
portPort on which service should listen.
ssl_enableEnable transport level security
ssl_certname, including full path of private key file.
ssl_chain[optional] name, including full path of certificate chain

The certificate files should be placed on a path accessible to the Anchore Enterprise service, for example in the /config directory which is typically mapped as a volume into the container. Note that the location outside the container will depend on your configuration - for example if you are volume mounting ‘/path/to/aevolume/config/’ on the docker host to ‘/config’ within the container, you’ll need to place the ssl files in ‘/path/to/aevolume/config/’ on the docker host, so that they are accessible in ‘/config/’ inside the container, before starting the service.

The ssl_chain file is optional and may be required by some certificate authorities. If your certificate authority provides a chain certificate then include it within the configuration.

Note: While a certificate may be purchased from a well-known and trusted certificate authority in some cases the certificate is signed by an intermediate certificate which is not included within a TLS/SSL clients trust stores. In these cases the intermediate certificate is signed by the certificate authority however without the full ‘chain’ showing the provenance and integrity of the certificate the TLS/SSL client may not trust the certificate.

Any certificates used by the Anchore Enterprise services need to be trusted by all other Anchore Enterprise services.

If an internal certificate authority is used the root certificate for the internal CA can be added to the Anchore Enterprise using the following procedure or SSL verification can be disabled by setting the following parameter:

internal_ssl_verify: True

Last modified December 16, 2024