The Cluster requires a main TLS certificate, issued by a public certificate authority such as Let's Encrypt, to serve the Cluster's public Services (read more about public BeyondCorp Services here) and anonymous Services (read more here) over the internet. Such Services include the Cluster's own Services such as the API Server and the AuthServer. Therefore, you should issue and set the Cluster TLS certificate as soon as you install the Cluster to begin using octelium and octeliumctl commands, and log in via the web portal of the AuthServer.
The Cluster installs an initial self-signed TLS certificate during the Cluster installation. You can use the octelium and octeliumctl commands before setting your real Cluster certificate, issued by a real CA such as Let's Encrypt, by setting OCTELIUM_INSECURE_TLS or OCTELIUM_DEV environment variables to true before using the octelium or octeliumctl commands.
Regardless of the certificate authority you use or the method you use to issue the TLS certificate, you will need to provide the issued certificate to the Cluster through a Kubernetes TLS secret with the name cert-cluster in the Kubernetes namespace octelium as shown in detail here.
Cluster Domain Certificate
The Cluster certificate needs to include the following domains in the SAN list:
- The Cluster domain
<DOMAIN>. - The wildcard domain
*.<DOMAIN>. - The wildcard domains
*.local.<DOMAIN>and*.default.local.<DOMAIN>.
Issuing the Certificate
There is no one canonical way to issue your Cluster certificate by a certificate authority. You can use Let's Encrypt via Certbot, for example, to issue a certificate for your Cluster domain for free.
Certbot
Here is an example of issuing the certificate using the certbot CLI tool via a DNS challenge:
sudo certbot certonly --email <YOUR_EMAIL> --agree-tos --cert-name <DOMAIN> -d "<DOMAIN>,*.<DOMAIN>,*.local.<DOMAIN>" --manual --preferred-challenges dns# Your certificate is stored by default in /etc/letsencrypt/live/<DOMAIN>/
cert-manager
In a production environment, it is recommended to automate the process of issuing and rotating the Cluster certificate. You can also use a Kubernetes-based open source solution such as cert-manager. The following example shows the ClusterIssuer and Certificate cert-manager resources needed for a certificate that uses Let's Encrypt and Cloudflare.
The ClusterIssuer should look as follows:
1apiVersion: cert-manager.io/v12kind: ClusterIssuer3metadata:4name: letsencrypt-cloudflare5spec:6acme:7server: https://acme-v02.api.letsencrypt.org/directory8email: contact-acme@<DOMAIN>.com9privateKeySecretRef:10name: letsencrypt-cloudflare-account11solvers:12- dns01:13cloudflare:14email: cloudflare-account@<DOMAIN>15apiTokenSecretRef:16name: cloudflare-api-token-secret17key: api-key18selector: {}
The Certificate should look like this:
1apiVersion: cert-manager.io/v12kind: Certificate3metadata:4name: octelium-cluster5namespace: octelium6spec:7secretName: cert-cluster8issuerRef:9name: letsencrypt-cloudflare10kind: ClusterIssuer11commonName: <DOMAIN>12dnsNames:13- <DOMAIN>14- '*.<DOMAIN>'15- '*.local.<DOMAIN>'
Manually Setting the Certificate
Once you issue the certificate, you can manually provide it to the Cluster by creating a Kubernetes secret with the name cert-cluster in the namespace octelium. You can use the kubectl create secret tls command as follows:
kubectl create secret tls cert-cluster -n octelium --key </PATH/TO/PRIVATE_KEY.PEM> --cert </PATH/TO/CERT_CHAIN.PEM>
Alternatively, you can use the octops cert command to provide the same functionality as the kubectl create/update secret tls command above as follows:
octops cert <DOMAIN> --key </PATH/TO/PRIVATE_KEY.PEM> --cert </PATH/TO/CERT_CHAIN.PEM> --kubeconfig </PATH/TO/KUBECONFIG>
The Cluster watches for that specific Kubernetes secret and once it is created or updated, it is synchronized into an Octelium Secret resource.
Namespace Certificates
As shown above, the Cluster TLS certificate only serves for direct subdomains of the Cluster domain. This makes it only useful for Services belonging to the default Namespace (read more about Namespaces here). If you want to enable public/BeyondCorp access (i.e. via isPublic) or/and just TLS over the client-based access (i.e. isTLS field), you will have to issue a TLS certificate that uses the wildcard domains *.<NAMESPACE>.local.<DOMAIN> and *.<NAMESPACE>.<DOMAIN>. You can set/rotate a Namespace certificate via the octops cert command via --namespace field. For example, if the Namespace is production, then the octops cert command is used as follows:
octops cert <DOMAIN> --key </PATH/TO/PRIVATE_KEY.PEM> --cert </PATH/TO/CERT_CHAIN.PEM> --kubeconfig </PATH/TO/KUBECONFIG> --namespace production
You can also directly use Kubernetes commands (e.g. kubectl create secret) or via the SDKs. The name of the Kubernetes secret needs to be cert-ns-<NAMESPACE>. For example, if the Namespace is production, then the kubectl create secret command is used as follows:
kubectl create secret tls cert-ns-production -n octelium --key </PATH/TO/PRIVATE_KEY.PEM> --cert </PATH/TO/CERT_CHAIN.PEM>