diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index b92750f4..ff07a48e 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -90,6 +90,7 @@ if(generation) FILE(GLOB UMDS_PRE "manual/user-0?-*.md") FILE(GLOB UMDS_POST "manual/user-1?-*.md") FILE(GLOB DMDS "manual/dev-??-*.md") + FILE(GLOB AG "manual/advanced/??-*.md") # Manuals definitions set(MANUAL_OUTPUT_DIR "${CMAKE_BINARY_DIR}/doc") @@ -128,15 +129,30 @@ if(generation) COMMENT "Generating Developer Guide HTML documentation" ) + add_custom_command( + OUTPUT ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.pdf + COMMAND ${PANDOC_EXECUTABLE} -o ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.pdf --from markdown --template eisvogel --listings -N --toc ${AG} + DEPENDS ${UMDS} + COMMENT "Generating Advanced PDF documentation" + ) + add_custom_command( + OUTPUT ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.html + COMMAND ${PANDOC_EXECUTABLE} -o ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.html -s -f markdown-smart -N --toc -t html5 ${AG} + DEPENDS ${DMDS} + COMMENT "Generating Advanced HTML documentation" + ) + add_custom_target( all_docs ALL - DEPENDS copy_images ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.pdf ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.html ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.pdf ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.html + DEPENDS copy_images ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.pdf ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.html ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.pdf ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.html ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.pdf ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.html ) install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.pdf DESTINATION share/doc/pgagroal/manual) install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-user-guide.html DESTINATION share/doc/pgagroal/manual) install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.pdf DESTINATION share/doc/pgagroal/manual) install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-dev-guide.html DESTINATION share/doc/pgagroal/manual) + install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-advanced.pdf DESTINATION share/doc/pgagroal/manual) + install(FILES ${MANUAL_OUTPUT_DIR}/pgagroal-advanced-guide.html DESTINATION share/doc/pgagroal/manual) endif() diff --git a/doc/manual/97-acknowledgement.md b/doc/manual/97-acknowledgement.md index 3b291e2d..c364b48f 100644 --- a/doc/manual/97-acknowledgement.md +++ b/doc/manual/97-acknowledgement.md @@ -45,5 +45,5 @@ Please, consult our [Code of Conduct][conduct] policies for interacting in our community. Consider giving the project a [star][star] on -[GitHub][pagmoneta] if you find it useful. And, feel free to follow -the project on [Twitter][twitter] as well. \ No newline at end of file +[GitHub][pgagroal] if you find it useful. And, feel free to follow +the project on [Twitter][twitter] as well. diff --git a/doc/manual/advanced/00-frontpage.md b/doc/manual/advanced/00-frontpage.md new file mode 100644 index 00000000..4d7d86bc --- /dev/null +++ b/doc/manual/advanced/00-frontpage.md @@ -0,0 +1,13 @@ +--- +title: "Advanced connection management with pgagroal" +keywords: [pgagroal, PostgreSQL] +lang: "en" +titlepage: true, +titlepage-color: "0064A5" +titlepage-text-color: "FFFFFF" +titlepage-rule-color: "360049" +titlepage-rule-height: 0 +toc-own-page: true +listings-disable-line-numbers: true +table-use-row-colors: true +... diff --git a/doc/manual/advanced/01-preface.md b/doc/manual/advanced/01-preface.md new file mode 100644 index 00000000..d63c7a7a --- /dev/null +++ b/doc/manual/advanced/01-preface.md @@ -0,0 +1,12 @@ +# Preface + +Acme Boot is a startup company that have decided to use [**PostgreSQL**][postgresql] as +its database technology. + +The following technologies will be used for the database cluster + +* [**Rocky Linux**][rocky] **9.x** +* [**PostgreSQL**][postgresql] **17.x** +* [**pgagroal**][pgagroal] + +Note, that this guide will focus on the [**pgagroal**][pgagroal] aspect of the platform. diff --git a/doc/manual/advanced/02-introduction.md b/doc/manual/advanced/02-introduction.md new file mode 100644 index 00000000..a1223a9d --- /dev/null +++ b/doc/manual/advanced/02-introduction.md @@ -0,0 +1,34 @@ +\newpage + +# Introduction + +[**pgagroal**][pgagroal] is a high-performance protocol-native connection pool for [PostgreSQL][postgresql]. + +## Features + +* High performance +* Connection pool +* Limit connections for users and databases +* Prefill support +* Remove idle connections +* Perform connection validation +* Enable / disable database access +* Graceful / fast shutdown +* Prometheus support +* Grafana 8 dashboard +* Remote management +* Authentication query support +* Failover support +* Transport Layer Security (TLS) v1.2+ support +* Daemon mode +* User vault + +## Platforms + +The supported platforms are + +* [Fedora][fedora] 32+ +* [RHEL][rhel] 8 / RockyLinux 8 +* [RHEL][rhel] 9 / RockyLinux 9 +* [FreeBSD][freebsd] +* [OpenBSD][openbsd] diff --git a/doc/manual/advanced/03-installation.md b/doc/manual/advanced/03-installation.md new file mode 100644 index 00000000..b32a6c23 --- /dev/null +++ b/doc/manual/advanced/03-installation.md @@ -0,0 +1,172 @@ +\newpage + +# Installation + +## Rocky Linux 9.x + +We can download the [Rocky Linux](https://www.rockylinux.org/) distruction from their web site + +``` +https://rockylinux.org/download +``` + +The installation and setup is beyond the scope of this guide. + +Ideally, you would use dedicated user accounts to run [**PostgreSQL**][postgresql] and [**pgagroal**][pgagroal] + +``` +useradd postgres +usermod -a -G wheel postgres +useradd pgagroal +usermod -a -G wheel pgagroal +``` + +Add a configuration directory for [**pgagroal**][pgagroal] + +``` +mkdir /etc/pgagroal +chown -R pgagroal:pgagroal /etc/pgagroal +``` + +and lets open the ports in the firewall that we will need + +``` +firewall-cmd --permanent --zone=public --add-port=2345/tcp +firewall-cmd --permanent --zone=public --add-port=2346/tcp +``` + +## PostgreSQL 17 + +We will install PostgreSQL 17 from the official [YUM repository][yum] with the community binaries, + +**x86_64** + +``` +dnf -qy module disable postgresql +dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm +``` + +**aarch64** + +``` +dnf -qy module disable postgresql +dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-aarch64/pgdg-redhat-repo-latest.noarch.rpm +``` + +and do the install via + +``` +dnf install -y postgresql17 postgresql17-server postgresql17-contrib +``` + +First, we will update `~/.bashrc` with + +``` +cat >> ~/.bashrc +export PGHOST=/tmp +export PATH=/usr/pgsql-17/bin/:$PATH +``` + +then Ctrl-d to save, and + +``` +source ~/.bashrc +``` + +to reload the Bash environment. + +Then we can do the PostgreSQL initialization + +``` +mkdir DB +initdb -k DB +``` + +and update configuration - for a 8 GB memory machine. + +**postgresql.conf** +``` +listen_addresses = '*' +port = 5432 +max_connections = 100 +unix_socket_directories = '/tmp' +password_encryption = scram-sha-256 +shared_buffers = 2GB +huge_pages = try +max_prepared_transactions = 100 +work_mem = 16MB +dynamic_shared_memory_type = posix +wal_level = replica +wal_log_hints = on +max_wal_size = 16GB +min_wal_size = 2GB +log_destination = 'stderr' +logging_collector = on +log_directory = 'log' +log_filename = 'postgresql.log' +log_rotation_age = 0 +log_rotation_size = 0 +log_truncate_on_rotation = on +log_line_prefix = '%p [%m] [%x] ' +log_timezone = UTC +datestyle = 'iso, mdy' +timezone = UTC +lc_messages = 'en_US.UTF-8' +lc_monetary = 'en_US.UTF-8' +lc_numeric = 'en_US.UTF-8' +lc_time = 'en_US.UTF-8' +``` + +Please, check with other sources in order to create a setup for your local setup. + +Now, we are ready to start PostgreSQL + +``` +pg_ctl -D DB -l /tmp/ start +``` + +## pgagroal + +We will install [**pgagroal**][pgagroal] from the official [YUM repository][yum] as well, + +``` +dnf install -y pgagroal +``` + +First, we will need to create a master security key for the [**pgagroal**][pgagroal] installation, by + +``` +pgagroal-admin -g master-key +``` + +Then we will create the configuration for [**pgagroal**][pgagroal], + +``` +cat > /etc/pgagroal/pgagroal.conf +[pgagroal] +host = * +port = 2345 + +metrics = 2346 + +log_type = file +log_level = info +log_path = /tmp/pgagroal.log + +max_connections = 100 +idle_timeout = 600 +validation = off +unix_socket_dir = /tmp/ + +[primary] +host = localhost +port = 5432 +``` + +and end with a Ctrl-d to save the file. + +Start [**pgagroal**][pgagroal] now, by + +``` +pgagroal -d +``` diff --git a/doc/manual/advanced/04-configuration.md b/doc/manual/advanced/04-configuration.md new file mode 100644 index 00000000..ae2675dd --- /dev/null +++ b/doc/manual/advanced/04-configuration.md @@ -0,0 +1,193 @@ +\newpage + +# Configuration + +The configuration is loaded from either the path specified by the `-c` flag or `/etc/pgagroal/pgagroal.conf`. + +The configuration of [**pgagroal**][pgagroal] is split into sections using the `[` and `]` characters. + +The main section, called `[pgagroal]`, is where you configure the overall properties of [**pgagroal**][pgagroal]. + +Other sections doesn't have any requirements to their naming so you can give them meaningful names like `[primary]` for the primary [PostgreSQL][postgresql] instance. + +All properties are in the format `key = value`. + +The characters `#` and `;` can be used for comments; must be the first character on the line. + +The `Bool` data type supports the following values: `on`, `yes`, `1`, `true`, `off`, `no`, `0` and `false`. + +See a [sample][sample] configuration for running [**pgagroal**][pgagroal] on `localhost`. + +## [pgagroal] + +This section is mandatory and the pooler will refuse to start if the configuration file does not specify one and only one. Usually this section is place on top of the configuration file, but its position within the file does not really matter. +The available keys and their accepted values are reported in the table below. + +| Property | Default | Unit | Required | Description | +|----------|---------|------|----------|-------------| +| host | | String | Yes | The bind address for pgagroal | +| port | | Int | Yes | The bind port for pgagroal | +| unix_socket_dir | | String | Yes | The Unix Domain Socket location | +| metrics | 0 | Int | No | The metrics port (disable = 0) | +| metrics_cache_max_age | 0 | String | No | The number of seconds to keep in cache a Prometheus (metrics) response. If set to zero, the caching will be disabled. Can be a string with a suffix, like `2m` to indicate 2 minutes | +| metrics_cache_max_size | 256k | String | No | The maximum amount of data to keep in cache when serving Prometheus responses. Changes require restart. This parameter determines the size of memory allocated for the cache even if `metrics_cache_max_age` or `metrics` are disabled. Its value, however, is taken into account only if `metrics_cache_max_age` is set to a non-zero value. Supports suffixes: 'B' (bytes), the default if omitted, 'K' or 'KB' (kilobytes), 'M' or 'MB' (megabytes), 'G' or 'GB' (gigabytes).| +| management | 0 | Int | No | The remote management port (disable = 0) | +| log_type | console | String | No | The logging type (console, file, syslog) | +| log_level | info | String | No | The logging level, any of the (case insensitive) strings `FATAL`, `ERROR`, `WARN`, `INFO` and `DEBUG` (that can be more specific as `DEBUG1` thru `DEBUG5`). Debug level greater than 5 will be set to `DEBUG5`. Not recognized values will make the log_level be `INFO` | +| log_path | pgagroal.log | String | No | The log file location. Can be a strftime(3) compatible string. | +| log_rotation_age | 0 | String | No | The age that will trigger a log file rotation. If expressed as a positive number, is managed as seconds. Supports suffixes: 'S' (seconds, the default), 'M' (minutes), 'H' (hours), 'D' (days), 'W' (weeks). A value of `0` disables. | +| log_rotation_size | 0 | String | No | The size of the log file that will trigger a log rotation. Supports suffixes: 'B' (bytes), the default if omitted, 'K' or 'KB' (kilobytes), 'M' or 'MB' (megabytes), 'G' or 'GB' (gigabytes). A value of `0` (with or without suffix) disables. | +| log_line_prefix | %Y-%m-%d %H:%M:%S | String | No | A strftime(3) compatible string to use as prefix for every log line. Must be quoted if contains spaces. | +| log_mode | append | String | No | Append to or create the log file (append, create) | +| log_connections | `off` | Bool | No | Log connects | +| log_disconnections | `off` | Bool | No | Log disconnects | +| blocking_timeout | 30 | Int | No | The number of seconds the process will be blocking for a connection (disable = 0) | +| idle_timeout | 0 | Int | No | The number of seconds a connection is been kept alive (disable = 0) | +| rotate_frontend_password_timeout | 0 | Int | No | The number of seconds after which the passwords of frontend users are updated periodically (disable = 0) | +| rotate_frontend_password_length | 8 | Int | No | The length of the randomized frontend password | +| max_connection_age | 0 | Int | No | The maximum number of seconds that a connection will live (disable = 0) | +| validation | `off` | String | No | Should connection validation be performed. Valid options: `off`, `foreground` and `background` | +| background_interval | 300 | Int | No | The interval between background validation scans in seconds | +| max_retries | 5 | Int | No | The maximum number of iterations to obtain a connection | +| max_connections | 100 | Int | No | The maximum number of connections to PostgreSQL (max 10000) | +| allow_unknown_users | `true` | Bool | No | Allow unknown users to connect | +| authentication_timeout | 5 | Int | No | The number of seconds the process will wait for valid credentials | +| pipeline | `auto` | String | No | The pipeline type (`auto`, `performance`, `session`, `transaction`) | +| auth_query | `off` | Bool | No | Enable authentication query | +| failover | `off` | Bool | No | Enable failover support | +| failover_script | | String | No | The failover script to execute | +| tls | `off` | Bool | No | Enable Transport Layer Security (TLS) | +| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal or root. | +| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise. | +| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal or root. | +| libev | `auto` | String | No | Select the [libev](http://software.schmorp.de/pkg/libev.html) backend to use. Valid options: `auto`, `select`, `poll`, `epoll`, `iouring`, `devpoll` and `port` | +| keep_alive | on | Bool | No | Have `SO_KEEPALIVE` on sockets | +| nodelay | on | Bool | No | Have `TCP_NODELAY` on sockets | +| non_blocking | off | Bool | No | Have `O_NONBLOCK` on sockets | +| backlog | `max_connections` / 4 | Int | No | The backlog for `listen()`. Minimum `16` | +| hugepage | `try` | String | No | Huge page support (`off`, `try`, `on`) | +| tracker | off | Bool | No | Track connection lifecycle | +| track_prepared_statements | off | Bool | No | Track prepared statements (transaction pooling) | +| pidfile | | String | No | Path to the PID file. If omitted, automatically set to `unix_socket_dir`/pgagroal.`port`.pid | +| update_process_title | `verbose` | String | No | The behavior for updating the operating system process title, mainly related to connection processes. Allowed settings are: `never` (or `off`), does not update the process title; `strict` to set the process title without overriding the existing initial process title length; `minimal` to set the process title to `username/database`; `verbose` (or `full`) to set the process title to `user@host:port/database`. Please note that `strict` and `minimal` are honored only on those systems that do not provide a native way to set the process title (e.g., Linux). On other systems, there is no difference between `strict` and `minimal` and the assumed behaviour is `minimal` even if `strict` is used. `never` and `verbose` are always honored, on every system. On Linux systems the process title is always trimmed to 255 characters, while on system that provide a natve way to set the process title it can be longer. | + +__Danger zone__ + +| Property | Default | Unit | Required | Description | +|----------|---------|------|----------|-------------| +| disconnect_client | 0 | Int | No | Disconnect clients that have been idle for more than the specified seconds. This setting __DOES NOT__ take long running transactions into account | +| disconnect_client_force | off | Bool | No | Disconnect clients that have been active for more than the specified seconds. This setting __DOES NOT__ take long running transactions into account | + + +### Server section + +Each section with a name different from [**pgagroal**](https://github.com/agroal/pgagroal) will be treated as an host section. +There can be up to `64` host sections, each with an unique name and different combination of `host` and `port` settings, otherwise the pooler will complain about duplicated server configuration. + +| Property | Default | Unit | Required | Description | +|----------|---------|------|----------|-------------| +| host | | String | Yes | The address of the PostgreSQL instance | +| port | | Int | Yes | The port of the PostgreSQL instance | +| primary | | Bool | No | Identify the instance as primary (hint) | +| tls | `off` | Bool | No | Enable Transport Layer Security (TLS) support (Experimental - no pooling). Changes require restart. | +| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal or root. Changes require restart. | +| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise.Changes require restart. | +| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal or root. Changes require restart. | + +Note, that if `host` starts with a `/` it represents a path and [**pgagroal**](https://github.com/agroal/pgagroal) will connect using a Unix Domain Socket. + +## pgagroal_hba configuration + +The `pgagroal_hba` configuration controls access to [**pgagroal**](https://github.com/agroal/pgagroal) through host-based authentication. + +The configuration is loaded from either the path specified by the `-a` flag or `/etc/pgagroal/pgagroal_hba.conf`. + +The format of the file follows the similar [PostgreSQL HBA configuration format](https://www.postgresql.org/docs/current/auth-pg-hba-conf.html), and as such looks like + +``` +# +# TYPE DATABASE USER ADDRESS METHOD +# +host all all all all +``` + +| Column | Required | Description | +|--------|----------|-------------| +| TYPE | Yes | Specifies the access method for clients. `host` and `hostssl` are supported | +| DATABASE | Yes | Specifies the database for the rule. Either specific name or `all` for all databases | +| USER | Yes | Specifies the user for the rule. Either specific name or `all` for all users | +| ADDRESS | Yes | Specifies the network for the rule. `all` for all networks, or IPv4 address with a mask (`0.0.0.0/0`) or IPv6 address with a mask (`::0/0`) | +| METHOD | Yes | Specifies the authentication mode for the user. `all` for all methods, otherwise `trust`, `reject`, `password`, `md5` or `scram-sha-256` | + +Remote management users needs to have their database set to `admin` in order for the entry to be considered. + +There can be up to `64` HBA entries in the configuration file. + +## pgagroal_databases configuration + +The `pgagroal_databases` configuration defines limits for a database or a user or both. The limits are the number +of connections from [**pgagroal**](https://github.com/agroal/pgagroal) to PostgreSQL for each entry. + +The file also defines the initial and minimum pool size for a database and user pair. Note, that this feature requires +a user definition file, see below. + +The configuration is loaded from either the path specified by the `-l` flag or `/etc/pgagroal/pgagroal_databases.conf`. + +``` +# +# DATABASE USER MAX_SIZE INITIAL_SIZE MIN_SIZE +# +mydb myuser all +anotherdb userB 10 5 3 +``` + +| Column | Required | Description | +|--------|----------|-------------| +| DATABASE | Yes | Specifies the database for the rule. `all` for all databases | +| USER | Yes | Specifies the user for the rule. `all` for all users | +| MAX_SIZE | Yes | Specifies the maximum pool size for the entry. `all` for all remaining counts from `max_connections` | +| INITIAL_SIZE | No | Specifies the initial pool size for the entry. `all` for `MAX_SIZE` connections. Default is 0 | +| MIN_SIZE | No | Specifies the minimum pool size for the entry. `all` for `MAX_SIZE` connections. Default is 0 | + + +There can be up to `64` entries in the configuration file. + +In the case a limit entry has incoherent values, for example `INITIAL_SIZE` smaller than `MIN_SIZE`, the system will try to automatically adjust the settings on the fly, reporting messages in the logs. + +The system will find the best match limit entry for a given `DATABASE`-`USER` pair according to the following rules: +1. Use the first entry with an exact `DATABASE` and `USER` match. +2. If there is no exact match, use the entry with a `USER` match and `DATABASE` set to `all`. +3. If Rule 2 does not apply, use the entry with a `DATABASE` match and `USER` set to `all`. + +## pgagroal_users configuration + +The `pgagroal_users` configuration defines the users known to the system. This file is created and managed through the `pgagroal-admin` tool. + +The configuration is loaded from either the path specified by the `-u` flag or `/etc/pgagroal/pgagroal_users.conf`. + +## pgagroal_frontend_users configuration + +The `pgagroal_frontend_users` configuration defines the passwords for the users connecting to pgagroal. +This allows the setup to use different passwords for the [**pgagroal**](https://github.com/agroal/pgagroal) to PostgreSQL authentication. +This file is created and managed through the `pgagroal-admin` tool. + +All users defined in the frontend authentication must be defined in the user vault (`-u`). + +Frontend users (`-F`) requires a user vault (`-u`) to be defined. + +The configuration is loaded from either the path specified by the `-F` flag or `/etc/pgagroal/pgagroal_frontend_users.conf`. + +## pgagroal_admins configuration + +The `pgagroal_admins` configuration defines the administrators known to the system. This file is created and managed through the `pgagroal-admin` tool. + +The configuration is loaded from either the path specified by the `-A` flag or `/etc/pgagroal/pgagroal_admins.conf`. + +If pgagroal has both Transport Layer Security (TLS) and `management` enabled then `pgagroal-cli` can connect with TLS using the files `~/.pgagroal/pgagroal.key` (must be 0600 permission), `~/.pgagroal/pgagroal.crt` and `~/.pgagroal/root.crt`. + +## pgagroal_superuser configuration + +The `pgagroal_superuser` configuration defines the superuser known to the system. This file is created and managed through +the `pgagroal-admin` tool. It may only have one user defined. + +The configuration is loaded from either the path specified by the `-S` flag or `/etc/pgagroal/pgagroal_superuser.conf`. diff --git a/doc/manual/advanced/05-prefill.md b/doc/manual/advanced/05-prefill.md new file mode 100644 index 00000000..bd74b85c --- /dev/null +++ b/doc/manual/advanced/05-prefill.md @@ -0,0 +1,59 @@ +\newpage + +# Prefill + +## Create prefill configuration + +Prefill is instrumented by the `pgagroal_databases.conf` configuration file, where you need +to list databases, usernames, and limits. Every username/database pair has to be specified on a separated line. + +The limits are assumed as: + +* *max number of allowed connections* for that username/database +* *initial number of connections*, that is the effective prefill; +* *minimum number of connections* to always keep open for the pair username/database. + +Assuming you want to configure the prefill for the `mydb` database with the `myuser` username, +you have to edit the file `/etc/pgagroal/pgagroal_databases.conf` with your editor of choice +or using `cat` from the command line, as follows: + +``` +cd /etc/pgagroal +cat > pgagroal_databases.conf +mydb myuser 2 1 0 +``` + +and press `Ctrl-d` to save the file. + +This will create a configuration where `mydb` will have a maximum connection size of 2, +an initial connection size of 1 and a minimum connection size of 0 for the `myuser` user. + +The file must be owned by the operating system user [**pgagroal**](https://github.com/agroal/pgagroal). + +The `max_size` value is mandatory, while the `initial_size` and `min_size` are optional and if not explicitly set are assumed to be `0`. +See [the `pgagroal_databases.conf` file documentation](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_databases-configuration) for more details. + +## Restart pgagroal + +In order to apply changes to the prefill configuration, you need to restart [**pgagroal**](https://github.com/agroal/pgagroal). +You can do so by stopping it and then re-launch the daemon, as [**pgagroal**](https://github.com/agroal/pgagroal) operating system user: + +``` +pgagroal-cli shutdown +pgagroal -d +``` + +## Check the prefill + +You can check the prefill by running, as the [**pgagroal**](https://github.com/agroal/pgagroal) operating system user, the `status` command: + +``` +pgagroal-cli status +Status: Running +Active connections: 0 +Total connections: 1 +Max connections: 100 + +``` + +where the `Total connections` is set by the *initial* connection specified in the limit file. diff --git a/doc/manual/advanced/06-remote_management.md b/doc/manual/advanced/06-remote_management.md new file mode 100644 index 00000000..cd246535 --- /dev/null +++ b/doc/manual/advanced/06-remote_management.md @@ -0,0 +1,66 @@ +\newpage + +# Remote administration + +## Enable remote management + +On the pooler machine, you need to enable the remote management. In order to do so, +add the `management` setting to the main `pgagroal.conf` configuration file. +The value of setting is the number of a free TCP/IP port to which the remote +management will connect to. + +With your editor of choice, edit the `/etc/pgagroal/pgagroal.conf` file and add the +`management` option likely the following: + +``` +management = 2347 +``` + +under the `[pgagroal]` section, so that the configuration file looks like: + +``` +[pgagroal] +... +management = 2347 +``` + +See [the pgagroal configuration settings](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal) for more details. + +## Add remote admin user + +Remote management is done via a specific admin user, that has to be created within the pooler vault. +As the [**pgagroal**][pgagroal] operating system user, run the following command: + +``` +cd /etc/pgagroal +pgagroal-admin -f /etc/pgagroal/pgagroal_admins.conf -U admin -P admin1234 add-user +``` + +The above will create the `admin` username with the `admin1234` password. + +**We strongly encourage you to choose non trivial usernames and passwords!** + + +## Restart pgagroal + +In order to make the changes available, and therefore activate the remote management, you have to restart [**pgagroal**][pgagroal], for example by issuing the following commands from the [**pgagroal**][pgagroal] operatng system user: + +``` +pgagroal-cli shutdown +pgagroal -d +``` + +## Connect via remote administration interface + +In order to connect remotely, you need to specify at least the `-h` and `-p` flags on the `pgagroal-cli` command line. Such flags will tell `pgagroal-cli` to connect to a remote host. You can also specify the username you want to connect with by specifying the `-U` flag. +So, to get the status of the pool remotely, you can issue: + +``` +pgagroal-cli -h localhost -p 2347 -U admin status +``` + +and type the password `admin1234` when asked for it. + +If you don't specify the `-U` flag on the command line, you will be asked for a username too. + +Please note that the above example uses `localhost` as the remote host, but clearly you can specify any *real* remote host you want to manage. diff --git a/doc/manual/advanced/07-split_security.md b/doc/manual/advanced/07-split_security.md new file mode 100644 index 00000000..3722957f --- /dev/null +++ b/doc/manual/advanced/07-split_security.md @@ -0,0 +1,45 @@ +\newpage + +# Split security model + +## Create frontend users + +Frontend users are stored into the `pgagroal_frontend_users.conf` file, that can be managed via the `pgagroal-admin` command line tool. +See [the documentation on frontend users](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_frontend_users-configuration) for more details. + +As an example, consider the user `myuser` that has the `mypassword` password defined on the PostgreSQL side. It is possible to *remap* the user password on the [**pgagroal**][pgagroal] side, +so that an application can connect to the [**pgagroal**][pgagroal] using a different password, like `application_password`. In turn, [**pgagroal**][pgagroal] will connect to PostgreSQL +using the `mypassword` password. Therefore, the application doesn't not know the *real* password used to connect to PostgreSQL. + +To achieve this, as [**pgagroal**][pgagroal] operating system run the following command: + +``` +pgagroal-admin -f /etc/pgagroal/pgagroal_frontend_users.conf -U myuser -P application_password user add +``` + +You will need a password mapping for each user defined in the `pgagroal_users.conf` configuration file. + +## Restart pgagroal + +In order to apply changes, you need to restart [**pgagroal**][pgagroal] so do: + +``` +pgagroal-cli shutdown +pgagroal -d +``` + +## Connect to PostgreSQL + +You can now use the "application password" to access the PostgreSQL instance. As an example, +run the following as any operatng system user: + +``` +psql -h localhost -p 2345 -U myuser mydb +``` + +using `application_password` as the password. +As already explained, [**pgagroal**][pgagroal] will then use the `mypassword` password against PostgreSQL. + +This **split security model** allows you to avoid sharing password between applications and PostgreSQL, +letting the [**pgagroal**][pgagroal] to be the secret-keeper. This not only improves security, but also allows you +to change the PostgreSQL password without having the application change its configuration. diff --git a/doc/manual/advanced/08-tls.md b/doc/manual/advanced/08-tls.md new file mode 100644 index 00000000..5d81158d --- /dev/null +++ b/doc/manual/advanced/08-tls.md @@ -0,0 +1,66 @@ +\newpage + +# Transport Level Security (TLS) + +## Creating Certificates + +This tutorial will show you how to create self-signed certificate for the server, valid for 365 days, use the following OpenSSL command, replacing `dbhost.yourdomain.com` with the server's host name, here `localhost`: + +``` +openssl req -new -x509 -days 365 -nodes -text -out server.crt \ + -keyout server.key -subj "/CN=dbhost.yourdomain.com" +``` + +then do - + +``` +chmod og-rwx server.key +``` + +because the server will reject the file if its permissions are more liberal than this. For more details on how to create your server private key and certificate, refer to the OpenSSL documentation. + +For the purpose of this tutorial we will assume the client certificate and key same as the server certificate and server key and therefore, these equations always holds - + +* `` = `` +* `` = `` +* `` = `` +* `` = `` + +## TLS in `pgagroal` + +### Modify the `pgagroal` configuration + +It is now time to modify the [pgagroal] section of configuration file `/etc/pgagroal/pgagroal_vault.conf`, with your editor of choice by adding the following lines in the [pgagroal] section. + +``` +tls = on +tls_cert_file = +tls_key_file = +``` + +### Only Server Authentication + +If you wish to do only server authentication the aforementioned configuration suffice. + +**Client Request** + +``` +PGSSLMODE=verify-full PGSSLROOTCERT= psql -h localhost -p 2345 -U +``` + +### Full Client and Server Authentication + +To enable the server to request the client certificates add the following configuration lines + +``` +tls = on +tls_cert_file = +tls_key_file = +tls_ca_file = +``` + +**Client Request** + +``` +PGSSLMODE=verify-full PGSSLCERT= PGSSLKEY= PGSSLROOTCERT= psql -h localhost -p 2345 -U +``` diff --git a/doc/manual/advanced/09-vault.md b/doc/manual/advanced/09-vault.md new file mode 100644 index 00000000..cf20b850 --- /dev/null +++ b/doc/manual/advanced/09-vault.md @@ -0,0 +1,167 @@ +\newpage + +# pgagroal-vault + +## Enable rotation of frontend passwords + +In the main configuration file of [**pgagroal**][pgagroal] add the following configuration for rotating frontend passwords and make sure management port is enabled in the [**pgagroal**][pgagroal] section of the configuration file. + +``` +management = 2347 +rotate_frontend_password_timeout = 60 +rotate_frontend_password_length = 12 +``` + +## Configuration + +In order to run `pgagroal-vault`, you need to configure the vault `pgagroal_vault.conf` configuration file, that will tell the vault how to work, which address to listen, address of management service in [**pgagroal**][pgagroal] so on, +and then `pgagroal_vault_users.conf` that will instrument the vault about the admin username and password of the remote management. + +### pgagroal-vault.conf + +It is now time to create the main `/etc/pgagroal/pgagroal_vault.conf` configration file, with your editor of choice or using `cat` from the command line, create the following content: + +``` +cd /etc/pgagroal +cat > pgagroal_vault.conf +[pgagroal-vault] +host = localhost +port = 2500 + +metrics = 2501 + +log_type = console +log_level = info +log_path = /tmp/pgagroal-vault.log + +[main] +host = localhost +port = 2347 +user = admin +``` + +and press `Ctrl-d` (if running `cat`) to save the file. + +### Add users file + +As the [**pgagroal**][pgagroal] operating system user, run the following command: + +``` +pgagroal-admin -f /etc/pgagroal/pgagroal_vault_users.conf -U admin -P admin1234 user add +``` + +The above will create the `admin` username with the `admin1234` password. Alternately, `/etc/pgagroal/pgagroal_admins.conf` can be provided for vault users information. + +See [the documentation about `pgagroal_vault.conf` for more details](https://github.com/agroal/pgagroal/blob/master/doc/VAULT.md). + +## Start the vault + +It is now time to start `pgagroal-vault`, so as the [**pgagroal**][pgagroal] operating system user run: + +``` +pgagroal-vault -d +``` + +If both `pgagroal` and `pgagroal-vault` are on the same operating system they can use the same `pgagroal_admins.conf` file. + +This command initializes an HTTP server on localhost port 2500, which is primed to exclusively handle GET requests from clients. + +## Connect to the vault + +Since we have deployed an HTTP server we can simply use `curl` to send GET requests + +### Correct requests + +If the requested URL is of form `http://:/users/` such that `` exists, the server will return a header response with a 200 status code and the frontend password corresponding to the `` in the response body. + +**Example** + +` +curl -i http://localhost:2500/users/myuser +` + +Output + +``` +HTTP/1.1 200 OK +Content-Type: text/plain + + +password +``` + +### Incorrect requests + +All the POST requests will be ignored and the server will send a `HTTP 404 ERROR` as a response. + +Any URL other than the format: `http://:/users/*` will result in `HTTP 404 ERROR`. + +**Example** + +` +curl -i http://localhost:2500/user +` + +Output + +``` +HTTP/1.1 404 Not Found + +``` + +A URL of form `http://:/users/` such that `` does not exist will also give `HTTP 404 ERROR`. + +**Example** + +` +curl -i http://localhost:2500/users/randomuser +` + +Output + +``` +HTTP/1.1 404 Not Found + +``` + + +## Transport Level Security (TLS) + +### Enable TLS + +It is now time to modify the `[pgagroal-vault]` section of configuration file `/etc/pgagroal/pgagroal_vault.conf` with your editor of choice by adding the following lines in the [pgagroal-vault] section. + +``` +tls = on +tls_cert_file = +tls_key_file = +``` + +This will add TLS support to the server alongside the standard `http` endpoint, allowing clients to make requests to either the `https` or `http` endpoint. + +### Only Server Authentication + +If you wish to do only server authentication the aforementioned configuration suffice. + +**Client Request** + +``` +curl --cacert -i https://localhost:2500/users/ +``` + +### Full Client and Server Authentication + +To enable the server to request the client certificates add the following configuration lines + +``` +tls = on +tls_cert_file = +tls_key_file = +tls_ca_file = +``` + +**Client Request** + +``` +curl --cert --key --cacert -i https://localhost:2500/users/ +``` diff --git a/doc/manual/advanced/10-prometheus.md b/doc/manual/advanced/10-prometheus.md new file mode 100644 index 00000000..e0facd50 --- /dev/null +++ b/doc/manual/advanced/10-prometheus.md @@ -0,0 +1,31 @@ +\newpage + +# Prometheus metrics + +## pgagroal + +Once [**pgagroal**][pgagroal] is running you can access the metrics with a browser at the pooler address, specifying the `metrics` port number and routing to the `/metrics` page. For example, point your web browser at: + +``` +http://localhost:2346/metrics +``` + +It is also possible to get an explaination of what is the meaning of each metric by pointing your web browser at: + +``` +http://localhost:2346/ +``` + +## pgagroal-vault + +Once [**pgagroal-vault**][pgagroal] is running you can access the metrics with a browser at the pooler address, specifying the `metrics` port number and routing to the `/metrics` page. For example, point your web browser at: + +``` +http://localhost:2501/metrics +``` + +It is also possible to get an explaination of what is the meaning of each metric by pointing your web browser at: + +``` +http://localhost:2501/ +``` diff --git a/doc/manual/advanced/97-acknowledgement.md b/doc/manual/advanced/97-acknowledgement.md new file mode 100644 index 00000000..c364b48f --- /dev/null +++ b/doc/manual/advanced/97-acknowledgement.md @@ -0,0 +1,49 @@ +\newpage + +# Acknowledgement + +## Authors + +[**pgagroal**][pgagroal] was created by the following authors: + +``` +Jesper Pedersen +David Fetter +Will Leinweber +Junduo Dong +Luca Ferrari +Nikita Bugrovsky +Lawrence Wu +Yongting You <2010youy01@gmail.com> +Ashutosh Sharma +Henrique de Carvalho +Yihe Lu +Eugenio Gigante +Mohanad Khaled +Haoran Zhang +``` + +## Committers + +``` +Jesper Pedersen +Luca Ferrari +``` + +## Contributing + +Contributions to [**pgagroal**][pgagroal] are managed on [GitHub][pgagroal] + +* [Ask a question][ask] +* [Raise an issue][issue] +* [Feature request][request] +* [Code submission][submission] + +Contributions are most welcome! + +Please, consult our [Code of Conduct][conduct] policies for interacting in our +community. + +Consider giving the project a [star][star] on +[GitHub][pgagroal] if you find it useful. And, feel free to follow +the project on [Twitter][twitter] as well. diff --git a/doc/manual/advanced/98-licenses.md b/doc/manual/advanced/98-licenses.md new file mode 100644 index 00000000..ba7d265f --- /dev/null +++ b/doc/manual/advanced/98-licenses.md @@ -0,0 +1,78 @@ +\newpage + +# License + +``` +Copyright (C) 2025 The pgagroal community + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided +with the distribution. + +3. Neither the name of the copyright holder nor the names of +its contributors may be used to endorse or promote products +derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +``` + +[BSD-3-Clause][license] + + +## libart +Our adaptive radix tree (ART) implementation is based on + [The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases][ART_paper] + and [libart][libart] which has a [3-BSD license][license] as + +``` +Copyright (c) 2012, Armon Dadgar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of the organization nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARMON DADGAR +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/doc/manual/advanced/99-references.md b/doc/manual/advanced/99-references.md new file mode 100644 index 00000000..0d6bebf1 --- /dev/null +++ b/doc/manual/advanced/99-references.md @@ -0,0 +1,73 @@ + + + [pgagroal]: https://github.com/agroal/pgagroal + [postgresql]: https://www.postgresql.org + [rocky]: https://www.rockylinux.org + [fedora]: https://getfedora.org/ + [rhel]: https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux + [appstram]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/installing_managing_and_removing_user-space_components/using-appstream_using-appstream + [freebsd]: https://www.freebsd.org/ + [openbsd]: http://www.openbsd.org/ + [gcc]: https://gcc.gnu.org + [cmake]: https://cmake.org + [make]: https://www.gnu.org/software/make/ + [libev]: http://software.schmorp.de/pkg/libev.html + [openssl]: http://www.openssl.org/ + [systemd]: https://www.freedesktop.org/wiki/Software/systemd/ + [rst2man]: https://docutils.sourceforge.io/ + [pandoc]: https://pandoc.org/ + [pandoc_latex_template]: https://github.com/Wandmalfarbe/pandoc-latex-template + [texlive]: https://www.tug.org/texlive/ + [clang]: https://clang.llvm.org/ + [git_squash]: https://www.git-tower.com/learn/git/faq/git-squash + [progit]: https://github.com/progit/progit2/releases + [prometheus]: https://prometheus.io/ + [wireshark]: https://www.wireshark.org/ + [pgprtdbg]: https://github.com/jesperpedersen/pgprtdbg + [ART_paper]: http://www-db.in.tum.de/~leis/papers/ART.pdf + [libart]: https://github.com/armon/libart + + + [rpm]: https://github.com/agroal/pgagroal/blob/main/doc/RPM.md + [configuration]: https://github.com/agroal/pgagroal/blob/main/doc/CONFIGURATION.md + + [t_install]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md + [t_prefill]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/02_prefill.md + [t_remote_management]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/03_remote_management.md + [t_prometheus]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/04_prometheus.md + [t_split_security]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/05_split_security.md + + [sample]: https://github.com/agroal/pgagroal/blob/main/doc/etc/pgagroal.conf + + + [main_c]: https://github.com/agroal/pgagroal/blob/main/src/main.c + [cli_c]: https://github.com/agroal/pgagroal/blob/main/src/cli.c + [admin_c]: https://github.com/agroal/pgagroal/blob/main/src/admin.c + [vault_c]: https://github.com/agroal/pgagroal/blob/main/src/vault.c + + [shmem_h]: https://github.com/agroal/pgagroal/blob/main/src/include/shmem.h + [pgagroal_h]: https://github.com/agroal/pgagroal/blob/main/src/include/pgagroal.h + [messge_h]: https://github.com/agroal/pgagroal/blob/main/src/include/message.h + [network_h]: https://github.com/agroal/pgagroal/blob/main/src/include/network.h + [memory_h]: https://github.com/agroal/pgagroal/blob/main/src/include/memory.h + [management_h]: https://github.com/agroal/pgagroal/blob/main/src/include/management.h + [remote_h]: https://github.com/agroal/pgagroal/blob/main/src/include/remote.h + [prometheus_h]: https://github.com/agroal/pgagroal/blob/main/src/include/prometheus.h + [logging_h]: https://github.com/agroal/pgagroal/blob/main/src/include/logging.h + + [message_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/message.c + [network_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/network.c + [memory_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/memory.c + [remote_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/remote.c + [prometheus_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/prometheus.c + [logging_c]: https://github.com/agroal/pgagroal/blob/main/src/libpgagroal/logging.c + + + [ask]: https://github.com/agroal/pgagroal/discussions + [issue]: https://github.com/agroal/pgagroal/issues + [request]: https://github.com/agroal/pgagroal/issues + [submission]: https://github.com/agroal/pgagroal/pulls + [conduct]: https://github.com/agroal/pgagroal/blob/main/CODE_OF_CONDUCT.md + [star]: https://github.com/agroal/pgagroal/stargazers + [twitter]: https://twitter.com/pgagroal/ + [license]: https://opensource.org/licenses/BSD-3-Clause diff --git a/doc/manual/user-02-configuration.md b/doc/manual/user-02-configuration.md index 726fba0d..ae2675dd 100644 --- a/doc/manual/user-02-configuration.md +++ b/doc/manual/user-02-configuration.md @@ -121,7 +121,7 @@ host all all all all Remote management users needs to have their database set to `admin` in order for the entry to be considered. -There could be up to `64` HBA entries in the configuration file. +There can be up to `64` HBA entries in the configuration file. ## pgagroal_databases configuration diff --git a/doc/tutorial/02_prefill.md b/doc/tutorial/02_prefill.md index f67ac4e5..70a02d9b 100644 --- a/doc/tutorial/02_prefill.md +++ b/doc/tutorial/02_prefill.md @@ -25,7 +25,7 @@ The limits are assumed as: - *initial number of connections*, that is the effective prefill; - *minimum number of connections* to always keep open for the pair username/database. -Assuming you want to configure the prefill for the `mydb` database with the `mysuer` username, +Assuming you want to configure the prefill for the `mydb` database with the `myuser` username, you have to edit the file `/etc/pgagroal/pgagroal_databases.conf` with your editor of choice or using `cat` from the command line, as follows: