]> git.ekhem.eu.org Git - server.git/commitdiff
[postgres] Enable remote connections with certificates.
authorJakub Czajka <jakub@ekhem.eu.org>
Sun, 29 Jan 2023 13:20:35 +0000 (14:20 +0100)
committerJakub Czajka <jakub@ekhem.eu.org>
Sun, 3 Dec 2023 21:03:23 +0000 (22:03 +0100)
Client can authenticate with certificates generated by a new
certificate authority.

postgres/README
postgres/pg_hba.conf
postgres/postgresql.conf

index 05b88ca9d14556090851e5e24364a9bff4fff162..ada20c23259c24c042a0e7073cc55cf5da0c3359 100644 (file)
@@ -1,6 +1,8 @@
 postgres
 ========
 
+Relational database.
+
 Files
 -----
 
@@ -9,6 +11,72 @@ postgres
 |-> pg_hba.conf     -- /etc/postgresql/$(version)/main/
 `-> postgresql.conf -- /etc/postgresql/$(version)/main/
 
+DNS
+---
+
+Set up <domain> and psql.<domain>.
+
+<domain>      A     <IPv4 address>
+<domain>      AAAA  <IPv6 address>
+psql.<domain> CNAME <domain>
+
+SSL
+---
+
+Postgres uses both server- and client-side certificates. Whenever a client tries
+to connect, verifies server's certificate and then presents their certificate.
+
+SSL (server)
+------------
+
+Obtain a certificate with `certbot`.
+
+```
+$ certbot certonly --standalone -d psql.<domain>
+```
+
+Copy the certificate to a directory owned by `postgres`. Change its ownership and
+permissions.
+
+```
+$ mkdir /etc/postgresql/<version>/main/private
+$ chmod 700 /etc/postgresql/<version>/main/private
+$ cp /etc/letsencrypt/live/psql.<domain>/{fullchain.pem,privkey.pem} \
+  /etc/postgresql/<version>/main/private/
+$ chmod 600 /etc/postgresql/<version>/main/private/{fullchain.pem,privkey.pem}
+$ chown postgres:postgres -R /etc/postgresql/<version>/main/private
+```
+
+SSL (client)
+------------
+
+Obtain a certificate with `openssl`. <user> must contain the name of a postgres
+account for which the certificate is issued.
+
+```
+openssl req -newkey rsa:4096 -x509 -sha512 \
+  -days 365 -nodes -out <out>.crt -keyout <out>.key \
+  -subj "/C=<country>/ST=<state>/L=<location>/O=<organization>/CN=<user>"
+```
+
+Append the certificate to the list of valid certificates.
+
+```
+$ mkdir /etc/postgresql/<version>/main/private
+$ chmod 700 /etc/postgresql/<version>/main/private
+$ cp psql.crt /etc/postgresql/<version>/main/private/
+$ chmod 600 /etc/postgresql/<version>/main/private/psql.crt
+$ chown postgres:postgres /etc/postgresql/<version>/main/private/psql.crt
+```
+
+Present the certificate when connecting.
+
+```
+psql "host=psql.<domain> sslcert=<out>.crt sslkey=<out>.key user=<user> \
+  dbname=<db_name> sslrootcert=/etc/ssl/certs/ca-certificates.crt \
+  sslmode=verify-full"
+```
+
 Install
 -------
 
index 81e567041140b84c62193d9efa0705254b90d41c..1b94e9ccb0b62c90b2ba2063b6e7805d8f49d281 100644 (file)
@@ -105,3 +105,4 @@ host    all             all             ::1/128                 md5
 local   replication     all                                     peer
 host    replication     all             127.0.0.1/32            md5
 host    replication     all             ::1/128                 md5
+hostssl all             postgres        0.0.0.0/0               cert
index e8adb8256d9cccc3a393b74061b59e4c965da572..bfe0d767840b5874f8f84286c5d71b3e299797c8 100644 (file)
@@ -57,7 +57,7 @@ external_pid_file = '/var/run/postgresql/13-main.pid'                 # write an extra PID fil
 
 # - Connection Settings -
 
-#listen_addresses = 'localhost'                # what IP address(es) to listen on;
+listen_addresses = '*'                  # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
@@ -99,10 +99,10 @@ unix_socket_directories = '/var/run/postgresql'     # comma-separated list of direct
 # - SSL -
 
 ssl = on
-#ssl_ca_file = ''
-ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
+ssl_ca_file = '/etc/postgresql/13/main/private/psql.crt'
+ssl_cert_file = '/etc/postgresql/13/main/private/fullchain.pem'
 #ssl_crl_file = ''
-ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
+ssl_key_file = '/etc/postgresql/13/main/private/privkey.pem'
 #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
 #ssl_prefer_server_ciphers = on
 #ssl_ecdh_curve = 'prime256v1'