Security¶
This section contains information about security for CloudNativePG,that are analyzed at 3 different layers: Code, Container and Cluster.
Warning
The information contained in this page must not exonerate you from performing regular InfoSec duties on your Kubernetes cluster. Please familiarize yourself with the Overview of Cloud Native Security page from the Kubernetes documentation.
Code¶
Source code of CloudNativePG is systematically scanned for static analysis purposes,including securityproblems , using a popular open-source linter for Go called GolangCI-Lint directly in the CI/CD pipeline.GolangCI-Lint can run several linters on the same source code.
One of these is Golang Security Checker , or simply gosec ,a linter that scans
the abstract syntactic tree of the source against a set of rules aimed
atthe discovery of well-known vulnerabilities, threats, and weaknesses
hidden inthe code such as hard-coded credentials, integer overflows and
SQL injections - to name a few.
Important
A failure in the static code analysis phase of the CI/CD pipeline is a blocker for the entire delivery of CloudNativePG, meaning that each commit is validated against all the linters defined by GolangCI-Lint.
Container¶
Every container image that is part of CloudNativePG is automatically built via CI/CD pipelines following every commit.Such images include not only the operator’s, but also the operands’ - specifically every supported PostgreSQL version.Within the pipelines, images are scanned with:
Important
All operand images are automatically rebuilt once a day by our pipelines in case of security updates at the base image and package level, providing patch level updates for the container images that EDB distributes.
The following guidelines and frameworks have been taken into account for container-level security:
Cluster¶
Security at the cluster level takes into account all Kubernetes components thatform both the control plane and the nodes, as well as the applications that run inthe cluster (PostgreSQL included).
Role Based Access Control (RBAC)¶
The operator interacts with the Kubernetes API server with a dedicated
serviceaccount called cnpg-manager . In Kubernetes this is
installedby default in the cnpg-system namespace, with a cluster
rolebinding between this service account and the cnpg-manager
cluster role which defines the set of rules/resources/verbs granted to
the operator.
Important
The above permissions are exclusively reserved for the operator’s service account to interact with the Kubernetes API server. They are not directly accessible by the users of the operator that interact only with Cluster , Pooler , Backup , and ScheduledBackup resources.
Below we provide some examples and, most importantly, the reasons whyCloudNativePG requires full or partial management of standard Kubernetesnamespaced resources.
configmaps : The operator needs to create and manage default config
maps for the Prometheus exporter monitoring metrics.
deployments : The operator needs to manage a PgBouncer connection
pooler using a standard Kubernetes Deployment resource.
jobs : The operator needs to handle jobs to manage different
Cluster ’s phases.
persistentvolumeclaims : The volume where the PGDATA resides is
the central element of a PostgreSQL Cluster resource; the operator
needs to interact with the selected storage class to dynamically
provision the requested volumes, based on the defined scheduling
policies.
pods : The operator needs to manage Cluster ’s instances.
secrets : Unless you provide certificates and passwords to your
Cluster objects, the operator adopts the “convention over
configuration” paradigm by self-provisioning random generated passwords
and TLS certificates, and by storing them in secrets.
serviceaccounts : The operator needs to create a service account
that enables the instance manager (which is the PID 1 process of the
container that controls the PostgreSQL server) to safely communicate
with the Kubernetes API server to coordinate actions and continuously
provide a reliable status of the Cluster .
services : The operator needs to control network access to the
PostgreSQL cluster (or the connection pooler) from applications, and
properly manage failover/switchover operations in an automated way (by
assigning, for example, the correct end-point of a service to the proper
primary PostgreSQL instance).
Pod Security Policies¶
A Pod Security Policy is the Kubernetes way to define security rules and specifications that a pod needs to meetto run in a cluster.For InfoSec reasons, every Kubernetes platform should implement them.
CloudNativePG does not require privileged mode for containers
execution.The PostgreSQL containers run as postgres system user. No
component whatsoever requires running as root .
Likewise, Volumes access does not require privileges mode or root
privileges either.Proper permissions must be properly assigned by the
Kubernetes platform and/or administrators.The PostgreSQL containers run
with a read-only root filesystem (i.e. no writable layer).
The operator explicitly sets the required security contexts.
Restricting Pod access using AppArmor¶
You can assign an Restricting Pod access using AppArmor profile tothe postgres , initdb
, join , full-recovery and bootstrap-controller containers
inside every Cluster pod through the
container.apparmor.security.beta.kubernetes.io annotation.
Warning
Using this kind of annotations can result in your cluster to stop working. If this is the case, the annotation can be safely removed from the Cluster .
The AppArmor configuration must be at Kubernetes node level, meaning that theunderlying operating system must have this option enable and properlyconfigured.
In case this is not the situation, and the annotations were added at the
Cluster creation time, pods will not be created. On the other hand,
if youadd the annotations after the Cluster was created the pods in
the cluster willbe unable to start and you will get an error like this:
metadata.annotations[container.apparmor.security.beta.kubernetes.io/postgres]: Forbidden: may not add AppArmor annotations]
In such cases, please refer to your Kubernetes administrators and ask for theproper AppArmor profile to use.
Network Policies¶
The pods created by the Cluster resource can be controlled by
Kubernetes Network Policies to enable/disable inbound and outbound network
access at IP and TCP level.
Important
The operator needs to communicate to each instance on TCP port 8000 to get information about the status of the PostgreSQL server. Please make sure you keep this in mind in case you add any network policy, and refer to the “Exposed Ports” section below for a list of ports used by CloudNativePG for finer control.
Network policies are beyond the scope of this document.Please refer to the Network Policies section of the Kubernetes documentation for further information.
Exposed Ports¶
CloudNativePG exposes ports at operator, instance manager and operandlevels, as listed in the table below:
System | Port number | Exposing | Name | Certificates |
Authentication:————— | :———– | :—————— | :—————— | :———— |
:————–operator | 9443 | webhook server | webhook-server | TLS |
Yesoperator | 8080 | metrics | metrics | no TLS | Noinstance
manager | 9187 | metrics | metrics | no TLS | Noinstance
manager | 8000 | status | status | no TLS | Nooperand | 5432
| PostgreSQL instance | postgresql | optional TLS | Yes
PostgreSQL¶
The current implementation of CloudNativePG automatically
createspasswords and .pgpass files for the postgres superuser
and the database owner.
As far as encryption of password is concerned, CloudNativePG followsthe
default behavior of PostgreSQL: starting from PostgreSQL 14,
password_encryption is by default set to scram-sha-256 , while
on earlierversions it is set to md5 .
Important
Please refer to the Username/Password authentication section in the PostgreSQL documentation for details.
You can disable management of the postgres user password via secrets
by setting enableSuperuserAccess to false .
Note
The operator supports toggling the enableSuperuserAccess option. When you disable it on a running cluster, the operator will ignore the content of the secret, remove it (if previously generated by the operator) and set the password of the postgres user to NULL (de facto disabling remote access through password authentication).
See the PgBouncerSecrets for more information.
You can use those files to configure application access to the database.
By default, every replica is automatically configured to connect in
physicalasyncstreamingreplication with the current primary instance,
with a specialuser called streaming_replica . The connection between
nodes is encrypted and authentication is via
TLSclientcertificates (please refer to the Client TLS/SSL Connections pagefor
details).
Currently, the operator allows administrators to add pg_hba.conf
lines directly in the manifestas part of the pg_hba section of the
postgresql configuration. The lines defined in themanifest are added
to a default pg_hba.conf .
For further detail on how pg_hba.conf is managed by the operator,
see the PostgreSQL Configuration of the documentation.
Important
Examples assume that the Kubernetes cluster runs in a private and secure network.