This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

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]
        componentcatalog[Component Catalog]
    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
    api <--> componentcatalog

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

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

This script (for Linux) 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-analyzer,\
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,\
DNS:${RELEASE}-enterprise-componentcatalog"
# 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(Certificate 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 mounts the secret at /home/anchore/certs/, and the server block under anchoreConfig applies to every service:

certStoreSecretName: anchore-tls-certs

anchoreConfig:
  internal_ssl_verify: false
  server:
    ssl_enable: true
    ssl_cert: /home/anchore/certs/internal-cert.pem
    ssl_key: /home/anchore/certs/internal-cert-key.pem

ui:
  ldapsRootCaCertName: ca.pem

To enable TLS for a single service rather than all of them, use the same server block under that service, for example anchoreConfig.apiext.server.

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 GUI then you will need to separate 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 for other reasons besides internal TLS
    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:
    - anchore-api.yourdomain.com

Add an ingress directly in kubernetes for the UI:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: anchore-ingress-ui
  annotations:
    # These are for other reasons besides internal TLS
    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-ui.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 config.yaml (apiext, catalog, simplequeue, analyzer, policy_engine, reports, reports_worker, notifications and data_syncer) can be configured to use transport level security. The component catalog is configured separately, in bootstrap_ng.yaml — see Component Catalog TLS below.

The TLS settings live in the service’s server block, while the address settings live directly on the service:

services:
  apiext:
    enabled: True
    endpoint_hostname: 'anchore-api.mydomain.com'
    listen: '0.0.0.0'
    port: 443
    server:
      ssl_enable: True
      ssl_cert: '/config/anchore-ex.crt'
      ssl_key: '/config/anchore-ex.key'
      ssl_chain: '/config/anchore-ex.crt'
SettingLevelNotes
enabledserviceIf the service is enabled
endpoint_hostnameserviceDNS name of service
listenserviceIP address of interface on which the service should listen (use ‘0.0.0.0’ for all - default)
portservicePort on which service should listen
ssl_enableserverEnable transport level security
ssl_certserverName, including full path, of the certificate file
ssl_keyserverName, including full path, of the private key file
ssl_chainserver[optional] Name, including full path, of the 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, add the root certificate for that CA to Anchore Enterprise as described in Custom Certificate Authority.

Alternatively, disable verification of internal service certificates by setting internal_ssl_verify to False. The setting defaults to True, which enables verification, so it must be set explicitly to turn verification off:

internal_ssl_verify: False

This is a top-level setting, not a per-service one, and it appears in both config.yaml and bootstrap_ng.yaml. Set it in both files if you supply your own, so that the component catalog and the other services agree.


Component Catalog TLS

The component catalog reads its service configuration from bootstrap_ng.yaml rather than config.yaml, so its TLS settings live there. The keys are the same, again nested under server:

services:
  component_catalog:
    endpoint_hostname: ${ANCHORE_ENDPOINT_HOSTNAME}
    port: ${ANCHORE_COMPONENT_CATALOG_PORT}
    server:
      ssl_enable: true
      ssl_cert: /path/to/cert.pem
      ssl_key: /path/to/key.pem
      ssl_chain: /path/to/chain.pem

When ssl_enable is true, both ssl_cert and ssl_key must be set. ssl_chain is optional.

For more on the component catalog configuration files and how to supply your own, see General Configuration.