postgres
========
+Relational database.
+
Files
-----
|-> 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
-------
# - 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)
# - 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'