From 938ef30f3660ecf6817af0a9812f78f36e1c8bc5 Mon Sep 17 00:00:00 2001 From: Michele Cereda Date: Fri, 13 Sep 2024 08:06:44 +0200 Subject: [PATCH] chore(postgresql): add extensions section and postgresql_anonymizer --- knowledge base/postgresql.md | 77 +++++++++++++++++++++++++++++++++++- snippets/postgresql.sql | 40 +++++++++++++++++-- 2 files changed, 112 insertions(+), 5 deletions(-) diff --git a/knowledge base/postgresql.md b/knowledge base/postgresql.md index ea2b8bf..5f18a18 100644 --- a/knowledge base/postgresql.md +++ b/knowledge base/postgresql.md @@ -1,6 +1,9 @@ # PostgreSQL 1. [TL;DR](#tldr) +1. [Extensions of interest](#extensions-of-interest) + 1. [PostGIS](#postgis) + 1. [`postgresql_anonymizer`](#postgresql_anonymizer) 1. [Further readings](#further-readings) 1. [Sources](#sources) @@ -23,9 +26,12 @@ DB-specific roles). Extensions in PostgreSQL are managed per database. +
+ Setup + ```sh # Installation. -brew install 'postgresql@14' +brew install 'postgresql@16' sudo dnf install 'postgresql' 'postgresql-server' sudo zypper install 'postgresql15' 'postgresql15-server' @@ -48,6 +54,11 @@ user = master EOF ``` +
+ +
+ Usage + ```sh # Connect to servers via CLI client. # If not given: @@ -99,12 +110,73 @@ createuser 'dummyuser' -e --pwprompt && dropuser 'dummyuser' scram-sha-256 'mySecretPassword' ``` +```sql +-- Load extensions from the underlying operating system +-- They must be already installed on the instance +ALTER SYSTEM SET shared_preload_libraries = 'anon'; +ALTER DATABASE postgres SET session_preload_libraries = 'anon'; +``` + +
+ +## Extensions of interest + +### PostGIS + +TODO + +### `postgresql_anonymizer` + +Extension to mask or replace personally identifiable information or other sensitive data in a DB. + +Refer [`postgresql_anonymizer`][postgresql_anonymizer] and [An In-Depth Guide to Postgres Data Masking with Anonymizer]. + +Admins declare masking rules using the PostgreSQL Data Definition Language (DDL) and specify the anonymization strategy +inside each tables' definition. + +
+ Example + +```sh +docker run --rm -d -e 'POSTGRES_PASSWORD=postgres' -p '6543:5432' 'registry.gitlab.com/dalibo/postgresql_anonymizer' +psql -h 'localhost' -p '6543' -U 'postgres' -d 'postgres' -W +``` + +```sql +=# SELECT * FROM people LIMIT 1; + id | firstname | lastname | phone +----+-----------+----------+------------ + T1 | Sarah | Conor | 0609110911 + +-- 1. Activate the dynamic masking engine +=# CREATE EXTENSION IF NOT EXISTS anon CASCADE; +=# SELECT anon.start_dynamic_masking(); + +-- 2. Declare a masked user +=# CREATE ROLE skynet LOGIN PASSWORD 'skynet'; +=# SECURITY LABEL FOR anon ON ROLE skynet IS 'MASKED'; + +-- 3. Declare masking rules +=# SECURITY LABEL FOR anon ON COLUMN people.lastname IS 'MASKED WITH FUNCTION anon.fake_last_name()'; +=# SECURITY LABEL FOR anon ON COLUMN people.phone IS 'MASKED WITH FUNCTION anon.partial(phone,2,$$******$$,2)'; + +-- 4. Connect with the masked user and test masking +=# \connect - skynet +=# SELECT * FROM people LIMIT 1; + id | firstname | lastname | phone +----+-----------+----------+------------ + T1 | Sarah | Morris | 06******11 +``` + +
+ ## Further readings - [Docker image] - [Bidirectional replication in PostgreSQL using pglogical] - [What is the pg_dump command for backing up a PostgreSQL database?] - [How to SCRAM in Postgres with pgBouncer] +- [`postgresql_anonymizer`][postgresql_anonymizer] ### Sources @@ -114,6 +186,7 @@ scram-sha-256 'mySecretPassword' - [The password file] - [How to Generate SCRAM-SHA-256 to Create Postgres 13 User] - [PostgreSQL: Get member roles and permissions] +- [An In-Depth Guide to Postgres Data Masking with Anonymizer] +[an in-depth guide to postgres data masking with anonymizer]: https://thelinuxcode.com/postgresql-anonymizer-data-masking/ [bidirectional replication in postgresql using pglogical]: https://www.jamesarmes.com/2023/03/bidirectional-replication-postgresql-pglogical.html [connect to a postgresql database]: https://www.postgresqltutorial.com/connect-to-postgresql-database/ [how to generate scram-sha-256 to create postgres 13 user]: https://stackoverflow.com/questions/68400120/how-to-generate-scram-sha-256-to-create-postgres-13-user [how to scram in postgres with pgbouncer]: https://www.crunchydata.com/blog/pgbouncer-scram-authentication-postgresql +[postgresql_anonymizer]: https://postgresql-anonymizer.readthedocs.io/en/stable/ [postgresql: get member roles and permissions]: https://www.cybertec-postgresql.com/en/postgresql-get-member-roles-and-permissions/ [what is the pg_dump command for backing up a postgresql database?]: https://www.linkedin.com/advice/3/what-pgdump-command-backing-up-postgresql-ke2ef diff --git a/snippets/postgresql.sql b/snippets/postgresql.sql index 637424e..b3eeba4 100644 --- a/snippets/postgresql.sql +++ b/snippets/postgresql.sql @@ -18,6 +18,12 @@ SELECT version(); \conninfo +-- Load extensions globally in the instance +-- If supported (no RDS) +ALTER SYSTEM SET shared_preload_libraries = 'anon'; +ALTER DATABASE postgres SET session_preload_libraries = 'anon'; + + -- List databases \l \list+ @@ -62,8 +68,25 @@ DROP SCHEMA IF EXISTS mundane CASCADE; -- List tables \d +\dt \dt+ +-- Create tables +CREATE TABLE people ( + id char(2) PRIMARY KEY, + firstname varchar(40) NOT NULL, + lastname varchar(40) NOT NULL, + phone varchar(20) NOT NULL +); + +-- Show table structure +\d sales +\d+ clients + + +-- Insert data +INSERT INTO people(id,firstname,lastname,phone) VALUES ('T1','Sarah','Conor','0609110911'); + -- Revoke *default* privileges ALTER DEFAULT PRIVILEGES IN SCHEMA cache REVOKE select ON TABLES FROM sales; @@ -75,6 +98,8 @@ ALTER DEFAULT PRIVILEGES FOR ROLE juan IN SCHEMA cache REVOKE all ON TABLES FROM \du+ -- List users only SELECT usename FROM pg_catalog.pg_user; +-- List roles only +SELECT rolname FROM pg_catalog.pg_roles; -- Check the current user has SuperUser privileges SHOW is_superuser; @@ -85,7 +110,7 @@ SHOW is_superuser; -- Does *not* support IF NOT EXISTS CREATE ROLE miriam; CREATE ROLE miriam WITH LOGIN PASSWORD 'jw8s0F4' VALID UNTIL '2005-01-01'; -CREATE USER mike; +CREATE USER mike IN ROLE engineers; -- Grant roles SuperUser privileges -- The role granting privileges must be already SuperUser @@ -99,18 +124,22 @@ ALTER USER mark CREATEDB REPLICATION; ALTER ROLE miriam CREATEROLE CREATEDB; -- Change passwords +ALTER USER mike WITH PASSWORD NULL; ALTER USER jonathan WITH PASSWORD 'seagull5-pantomime-Resting'; ALTER ROLE samantha WITH PASSWORD 'Wing5+Trunks3+Relic2' VALID UNTIL 'August 4 12:00:00 2024 +1'; -- Change password's validity ALTER ROLE fred VALID UNTIL 'infinity'; --- Rename +-- Rename roles ALTER ROLE manager RENAME TO boss; -- Assign roles to users GRANT rds_superuser TO mike; +-- Remove role memberships from users +REVOKE engineers FROM mike; + -- Close the connection to the current DB \q @@ -121,10 +150,13 @@ GRANT rds_superuser TO mike; SELECT rolpassword from pg_authid where rolname = 'admin'; --- Show extensions +-- Show available extensions +SELECT name FROM pg_available_extensions ORDER BY name; + +-- Show installed extensions \dx SELECT * FROM pg_extension; -SELECT extname FROM pg_extension; +SELECT extname FROM pg_extension ORDER BY extname; -- Show extensions versions SELECT postgis_version(), postgis_full_version(), postgis_lib_version();