Continuum AI is now public. Try out the most secure GenAI service!
Blog
And get memory and storage encryption for free
Otto Bittner
Kubernetes is the most popular cloud orchestration platform, making it simple to deploy and manage containerized and distributed applications.
Constellation is the most secure Kubernetes distribution, providing full encryption of data through confidential computing technology. For this reason, we recently set up a Mattermost on Constellation.
Mattermost is an open-source, self-hostable online project management software with file sharing, search, and other integrations. It is designed as an internal chat for organizations and companies and it is an open-source alternative to Slack and Microsoft Teams.
In this post, we will showcase how you can deploy Mattermost, a PostgreSQL cluster, and MinIO object storage on our confidential Kubernetes distribution Constellation; including database and object storage setup. The repo for this deployment also includes CI/CD pipelines, automatic SQL backups, and a backup restore pipeline. You can find it on GitHub. So, feel free to follow along and discover how to set this up for yourself!
Most components in the repo are deployed via Helm charts. There are two charts in the repo, mm-infra and mm-app. mm-infra bundles charts that need to be deployed once per cluster, like operators and CSI drivers. mm-app bundles charts that are deployed once per environment (e.g., staging, dev, prod). An environment in this context is a namespace. Consequently, changes to the mm-infra deployment affect all environments. If you have higher requirements for stability than us, you might want to deploy mm-infra once per environment or use separate clusters for each environment altogether.
Operators
The mm-infrachart deploys multiple operators and allows you to configure which ones are deployed when you run helm upgrade. Deploying all charts at once can be done by selecting "all" when running the GitHub Actions workflow included in the repository.
The following are all the operators deployed as part of mm-infra, as well as the commands to deploy them:
Zalando's postgres-operator and its web UI for SQL cluster creation/management:
helm upgrade psql-op --install --atomic --set postgresOperator.enabled=true -- create-namespace --namespace psql-op mm-infra
cert-manager for automatic Let's Encrypt certificates. This automatically also deploys external-dns for automatic creation of DNS entries:
helm upgrade cert-manager --install --set certManager.enabled=true --create- namespace --namespace cert-manager mm-infra
To setup access to your DNS provider for external-dns you need to create a secret:
kubectl create secret generic godaddy-access --from-env-file=./godaddy_creds - n external-dns
ingress-nginx for traffic routing/TLS:
helm upgrade nginx-ingress --install --atomic --set ingressNginx.enabled=true --create-namespace --namespace storage mm-infra
azuredisk-csi-driverand the respective storage class for transparent disk encryption. We also have the analogous GCP driver:
helm upgrade storage --install --atomic --set azurediskCsiDriver.enabled=true --create-namespace --namespace storage mm-infra
mattermost-operator for the mattermost deployment:
helm upgrade mm-op --install --atomic --set mattermostOperator.enabled=true --create-namespace --namespace mm-op mm-infra
Lastly, the minio-operator needs to be deployed. However, this is done via a kubectl plugin like so:
wget -q https://github.com/minio/operator/releases/latest/download/kubectl-minio_linux_amd64.zip sudo unzip -o kubectl-minio_linux_amd64.zip sudo chmod +x ./kubectl-minio export PATH=$PATH:$PWD kubectl minio init
Apps
After installing the operators, you can deploy the mattermost app to different environments. Each deployment includes:
SQL Backups
The postgres-operator manages backups for us. It will create a new backup once per day and save it to a separate bucket in MinIO using a dedicated user account. To configure backup creation, this ConfigMap is used. Backup creation is a feature of Spilo, an individual project the postgres-operator relies on. Therefore, reading about Spilo's environment variables is helpful if you want to modify the backup config.
The ConfigMap for backup configuration is available as environment variables in the pods through the postgres-operator. The relevant field of the postgres-operator is the pod_environment_configmap.
Restoring backups is configured in the postgresql resource by setting the clone key. If the clone key is present, data from the configured backup location is automatically put into the database.
Backup Quirk
While the database is correctly restored by adding the clone key, in our case, Mattermost needed some convincing until it accepted the backup. During regular operation, the postgres connection string is put into an environment variable called MM_CONFIG inside the Mattermost pod. When the pod starts for the first time, it will use the value of MM_CONFIG to connect to the DB. However, once it is successfully connected to the DB, it will read the settings for the mattermost-server from the DB. These settings also include a postgres connection string. At this point, the value in MM_CONFIG is no longer used by the mattermost-server. The connection string from the DB is used instead. Therefore, if the backup you just restored used different credentials for the database or the database was hosted under a different address, the connection will not work.
The simplest solution for our case was to ensure the address stays the same between backups. Unfortunately, passwords change since the postgres-operator creates new users every time a new cluster is created. Therefore, you can't set the password externally. To update the password, we manually read the settings for the mattermost-server from the DB after a backup was restored. Then, we update the password of the respective PostgreSQL user to match the password from the settings string.
So now, to initiate a backup restore, you can use one of the pipelines that we included as part of the repo.
CI/CD Pipelines
The repository includes GitHub Actions workflows to automate deployments and partially automate backup restoration. If you fork the repo, you can run these after updating the secrets. Three pipelines are relevant for managing the app:
Encryption
Deploying chat applications in the public cloud requires careful data security and privacy considerations. Enabling e2e message encryption for Mattermost's chat via available plugins is essential in securing communication. However, these plugins don't address infrastructure-based threats. With the rise of cloud computing, attacks coming through the infrastructure are alarmingly becoming more and more numerous. For example, researchers discovered alarming cross-tenant vulnerabilities in Microsoft Azure. The Cybersecurity Insiders 2020 Cloud Security Report also found that organizations ranked malicious insiders (36%) among the top 10 cloud security threats. And supply chain attacks are a rapidly emerging threat, with a recorded 742% increase in volume over the past three years.
In the case of the e2e encryption plugin, the authors describe an example of how a privileged attacker with access to the infrastructure might break e2e encryption by serving malicious JavaScript to break encryption.
Constellation alleviates this problem by encrypting data in transport, at rest, and in use, relying solely on widely known projects and technologies to implement these features:
Lastly, possibly the most crucial feature: the cluster's identity, integrity, and encryption are verifiable using remote attestation. That means we can trust our cluster and, consequently, our Mattermost deployment because we can verify it.
Combining these features allows us to run completely isolated, private, and always-encrypted Mattermost deployments in the public cloud while protecting against cross-tenant, malicious CSP insider, and supply chain attacks. In this way, we can be sure our internal communications are private and stay private!
This post outlined how to set up a Mattermost deployment on Constellation, a confidential Kubernetes distribution. The setup we showcased works as-is but can be adapted to fit your needs. Furthermore, while the setup is built on Constellation, it can be easily deployed on any Kubernetes cluster. In that case, however, you will lose the cluster VPN, storage encryption, memory encryption, and remote attestation.
Let us know what you would like us to deploy on confidential Kubernetes next!
Author: Otto Bittner