Securing Postgres backup API
Suggest editsOverview
This guide covers the steps necessary to enable secure remote access to Postgres backup API. This is achieved by installing Apache HTTP Server and configuring it to proxy traffic to Postgres backup API. Apache HTTP Server will also handle the following:
- TLS termination, so that all connections between the Barman server and the outside world are encrypted.
- Certificate authentication, so that only clients with authorized keys and certificates can access Postgres backup API.
Once completed you will be able to use a client key and certificate to authenticate to Postgres backup API over an encrypted TLS connection.
Prerequisites
You must already have installed Barman and Postgres backup API via your system package manager.
Installing Apache HTTP Server
The first step is to install Apache HTTP Server on the server where Barman and Postgres backup API are installed.
Debian/Ubuntu
sudo apt-get install apache2
RHEL
sudo yum install httpd mod_ssl
SLES
sudo zypper install apache2
Initial Apache HTTP Server configuration
Once installed you should stop Apache HTTP Server from listening on port 80 and carry out platform-specific configuration tasks.
Debian/Ubuntu
Stop Apache HTTP Server from listening on port 80:
sudo sed -i 's/^Listen 80$/#Listen 80/' /etc/apache2/ports.conf
Enable the ssl, proxy and proxy_http modules in the correct order and restart Apache HTTP Server:
sudo a2enmod ssl sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl restart apache2
Enable the Apache HTTP Server service so that is started automatically on reboot:
sudo systemctl enable apache2
RHEL
Stop Apache HTTP Server from listening on port 80:
sudo sed -i 's/^Listen 80$/#Listen 80/' /etc/httpd/conf/httpd.conf
Restart Apache HTTP Server:
sudo systemctl restart httpd
Enable the Apache HTTP Server service so that is started automatically on reboot:
sudo systemctl enable httpd
SLES
Stop Apache HTTP Server from listening on port 80 and start listening on 443 instead:
sudo sed -i 's/^Listen 80$/Listen 443/' /etc/apache2/listen.conf
Enable the proxy and proxy_http modules in the correct order:
sudo a2enmod proxy sudo a2enmod proxy_http
Restart Apache HTTP Server:
sudo systemctl restart apache2
Enable the Apache HTTP Server service so that is started automatically on reboot:
sudo systemctl enable apache2
Obtaining server and client certificates
In order to configure Apache HTTP Server for TLS encryption you will need a private key and a certificate signed by a trusted certificate authority (CA). You will also need a client certificate which has been signed by the same CA which signed the server certificate.
Note
You are of course free to use certificates obtained via other means and configure them however you like. For example your organization may have an internal CA you can use, or you may wish to use a third party CA. Such configurations are not covered by this guide.
In the following steps a number of placeholder variables are used:
$ORGANIZATION_NAME
: The organization name for your certificates.$SERVER_FQDN
: The fully qualified domain name of the Barman server.$ADMIN_EMAIL_ADDRESS
: The e-mail address used in theemailAddress
x509 attribute.$CLIENT_CN
: The x509 common name for the client application / host.
Note
On Ubuntu 18.04 only you will need to comment out RANDFILE
in /etc/ssl/openssl.cnf
to avoid errors relating to the use of a $HOME/.rnd
file.
This can be achieved with sudo sed -i -e s/^RANDFILE/#RANDFILE/ /etc/ssl/openssl.cnf
.
Firstly, generate a self-signed CA as follows:
sudo openssl req -nodes -new -x509 -days 999 \ -keyout /root/ca.key -out /root/ca.cert \ -subj "/O=$ORGANIZATION_NAME/CN=root.$SERVER_FQDN/emailAddress=$ADMIN_EMAIL_ADDRESS"
This will generate a CA key and self-signed certificate which will be stored in the /root
directory on the Barman server.
Now you can create a server key and use it to obtain a certificate signed by the CA you just created. Firstly create the key:
sudo openssl genrsa -out /root/server.key 2048
Create a certificate signing request using the newly generated key:
sudo openssl req -new \ -key /root/server.key -out /root/server.csr \ -subj "/O=$ORGANIZATION_NAME/CN=$SERVER_FQDN/emailAddress=$ADMIN_EMAIL_ADDRESS"
Create the server certificate from the certificate request using the CA:
sudo openssl x509 -req \ -in /root/server.csr -CA /root/ca.cert -CAkey /root/ca.key \ -CAcreateserial -out /root/server.cert -days 999 -sha256
Now we repeat the process to generate the client key and certificate:
sudo openssl genrsa -out /root/client.key 2048 sudo openssl req -new \ -key /root/client.key -out /root/client.csr \ -subj "/O=$ORGANIZATION_NAME/CN=$CLIENT_CN/emailAddress=$ADMIN_EMAIL_ADDRESS" sudo openssl x509 -req \ -in /root/client.csr -CA /root/ca.cert -CAkey /root/ca.key \ -CAcreateserial -out /root/client.cert -days 999 -sha256
Note
The certificates in this guide, including the self-signed CA, are all configured with a lifetime of 999 days.
If necessary this can be changed by replacing the -days 999
argument above.
Finally, move the CA certificate, the server key and server certificate to a location accessible by the Apache HTTP Server user and ensure correct permissions on the server key:
sudo mkdir -p /usr/local/lib/pgbapi sudo mv /root/ca.cert /root/server.key /root/server.cert /usr/local/lib/pgbapi sudo chmod 600 /usr/local/lib/pgbapi/server.key
Setting ownership differs by platform because each Linux distribution flavor runs Apache HTTP Server under a different account.
Debian/Ubuntu
sudo chown -R www-data /usr/local/lib/pgbapi
RHEL
sudo chown -R apache:apache /usr/local/lib/pgbapi
If SELinux is enabled you will also need to reset the security context for these files:
sudo restorecon -RvF /usr/local/lib/pgbapi
SLES
sudo chown -R wwwrun /usr/local/lib/pgbapi
Adding a VirtualHost definition for Postgres backup API
Add a file called pgbapi.conf
to the Apache HTTP configuration directory which defines the VirtualHost
which will act as a proxy.
The exact location of the file for the target system is given in the following table:
OS | Apache HTTP configuration dir |
---|---|
Debian/Ubuntu | /etc/apache2/sites-enabled/ |
RHEL | /etc/httpd/conf.d/ |
SLES | /etc/apache2/conf.d/ |
The contents of pgbapi.conf
should be as follows:
<VirtualHost *:443> ServerName $SERVER_FQDN SSLEngine on SSLCertificateFile /usr/local/lib/pgbapi/server.cert SSLCertificateKeyFile /usr/local/lib/pgbapi/server.key SSLCACertificateFile /usr/local/lib/pgbapi/ca.cert SSLVerifyClient require SSLVerifyDepth 1 ProxyPass "/" "http://localhost:7480/" ProxyPassReverse "/" "http://localhost:7480/" </VirtualHost>
Note that the CA certificate, server certificate and server key are expected to be available in /usr/local/lib/pgabi
.
If your key and certificates are located elsewhere then update the SSL certificate paths as required.
Be sure to change $SERVER_FQDN
to its actual value.
Finally, reload the Apache HTTP Server config.
Debian/Ubuntu and SLES
sudo systemctl reload apache2
RHEL
sudo systemctl reload httpd
If SELinux is enabled you will also need to allow Apache HTTP Server to connect to pg-backup-api:
sudo setsebool -P httpd_can_network_connect on
Client configuration
Postgres backup API is now configured for secure remote access.
The CA certificate, client certificate and client key created earlier will all be required by the client application so that it can connect and authenticate.
The files /root/ca.cert
, /root/client.key
and /root/client.cert
should therefore be copied securely to the client so that the client can be configured to use them.
As an example, curl can be configured to authenticate with a Postgres backup API instance running at pgbapi.example.com
as follows:
curl --cacert /usr/local/lib/pgbapi/ca.cert \ --cert /root/client.cert \ --key /root/client.key \ https://pgbapi.example.com/status
Could this page be better? Report a problem or suggest an addition!