diff --git a/Dockerfile b/Dockerfile index 720df8b..6ed78b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bullseye as builder +FROM debian:bookworm as builder WORKDIR /tmp/ @@ -34,8 +34,8 @@ RUN set -ex \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -FROM debian:bullseye - +FROM debian:bookworm-slim +ENV CERTFILE='/tmp/tls-cert/tls.crt' RUN set -ex \ && apt-get update \ && apt-get upgrade -y \ @@ -44,13 +44,16 @@ RUN set -ex \ curl \ libmicrohttpd-dev \ && curl -L https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb -o /tmp/libprom-dev-0.1.3-Linux.deb \ - && curl -L https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb -o /tmp/libpromhttp-dev-0.1.3-Linux.dev \ + && curl -L https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb -o /tmp/libpromhttp-dev-0.1.3-Linux.deb \ && dpkg --install /tmp/libprom-dev-0.1.3-Linux.deb \ - && dpkg --install /tmp/libpromhttp-dev-0.1.3-Linux.dev \ + && dpkg --install /tmp/libpromhttp-dev-0.1.3-Linux.deb \ + && rm /tmp/libpromhttp-dev-0.1.3-Linux.deb \ + && rm /tmp/libprom-dev-0.1.3-Linux.deb \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /tmp/odyssey/build/sources/odyssey /usr/local/bin/ +COPY ./entrypoint.sh . RUN adduser --disabled-password --gecos '' odyssey USER odyssey -ENTRYPOINT ["/usr/local/bin/odyssey"] +ENTRYPOINT ["./entrypoint.sh"] EXPOSE 5432 diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..ad76ceb --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Test if CERT file exist, if yes store the expiration date +if [ -f "$CERTFILE" ]; then + openssl x509 -enddate -noout < $CERTFILE > /tmp/TLSENDATE +else + echo "No cert file" + echo "no CRT" > /tmp/TLSENDATE +fi +# Start Odyssey +/usr/local/bin/odyssey $1 diff --git a/odyssey_sample.conf b/odyssey_sample.conf new file mode 100644 index 0000000..e50a31f --- /dev/null +++ b/odyssey_sample.conf @@ -0,0 +1,711 @@ +### +### Odyssey configuration file. +### + +# +# Include files. +# +# Include one or more configuration files. Include files can +# include other files. +# +# include "path" +# + +### +### SERVICE +### + +# +# Start as a daemon. +# +# By default Odyssey does not run as a daemon. Set to 'yes' to enable. +# +daemonize no + +# +# Process priority. +# +# Set Odyssey parent process and threads priority. +# +# priority -10 + +# +# Pid file. +# +# If pid_file is specified, Odyssey will write its process id to +# the specified file at startup. +# +# pid_file "/var/run/odyssey.pid" +# + +# +# UNIX socket directory. +# +# If unix_socket_dir is specified, Odyssey will enable UNIX socket +# communications. Specified directory path will be used for +# searching socket files. +# +unix_socket_dir "/tmp" + +# +# UNIX socket file mode. +# +# Set `unix_socket_mode` file mode to any created unix files. +# +unix_socket_mode "0644" + +# +# Directory to place odyssey internal-used locks +# Odyssey will use /tmp by default +# + +locks_dir "/tmp/odyssey" + +# +# In this mode odyssey will perform gracefully shutdown +# when signalled with SIGUSR2: +# it will not terminate established connections, but do not accept new ones +# +graceful_die_on_errors no + +# +# Online restart feauture. +# When setting to yes, restart odyssey simply with +# running new version (old one will automaticly perform graceful shutdown) +# +enable_online_restart no + +# +# UNIX socker SO_REUSEPORT optional enable +# + +bindwith_reuseport no + +### +### LOGGING +### + +# +# Log file. +# +# If log_file is specified, Odyssey will additionally use it to write +# log events. +# +# log_file "/var/log/odyssey.log" +# + +# +# Log text format. +# +# Odyssey allows to configure log text format. This could be useful to +# support external log parser format. Format string can contain plain +# text, escape symbols and format flags. +# +# Supported flags: +# +# %n = unixtime +# %t = timestamp with date +# %p = process ID +# %i = client ID +# %s = server ID +# %u = user name +# %d = database name +# %c = context +# %l = level (error, warning, debug) +# %m = message +# %M = message tskv +# %r = client port +# %h = client host +# +log_format "%p %t %l [%i %s] (%c) %m\n" + +# +# Log to stdout. +# +# Set to 'yes' if you need to additionally display log output in stdout. +# Enabled by default. +# +log_to_stdout yes + +# +# Log to system logger. +# +# To enable syslog(3) usage, set log_syslog to 'yes'. Additionally set +# log_syslog_ident and log_syslog_facility. +# +log_syslog no +log_syslog_ident "odyssey" +log_syslog_facility "daemon" + +# +# Verbose logging. +# +# Enable verbose logging of all events, which will generate a log of +# detailed information useful for development or testing. +# +# It is also possible to enable verbose logging for specific users +# (see routes section). +# +log_debug no + +# +# Log configuration. +# +# Write configuration to the log during start and config reload. +# +log_config yes + +# +# Log session events. +# +# Write client connect and disconnect events to the log. +# +log_session yes + +# +# Log client queries. +# +# Write client queries text to the log. Disabled by default. +# +log_query no + +# +# Log client statistics. +# +# Periodically display information about active routes. +# +log_stats yes + +# +# Statistics update inverval. +# +# Set interval in seconds for internal statistics update and log report. +# +stats_interval 60 + +# +# Log stats in Prometheus format. +# +# Write stats in Prometheus format in addition to ordinary logs. +# +# Enable log general odyssey's log, not related to concrete routes +# +log_general_stats_prom no + +# +# Enable log route related logs +# Note, this option also turn on general prometheus logging +log_route_stats_prom no + +# +# Port for Prometheus metrics http-server to listen +# Require Prometheus C library and Promhttp library +# Once port is set and server is started change require restart +# +# promhttp_server_port 7777 + + +### +### PERFORMANCE +### + +# +# Worker threads. +# +# Set size of thread pool used for client processing. +# +# 1: By default, Odyssey runs with a single worker. This is a special +# mode optimized for general use. This mode also made to reduce multi-thread +# communication overhead. +# +# N: Add additional worker threads, if your server experience heavy load, +# especially using TLS setup. +# +workers 1 + +# +# Resolver threads. +# +# Number of threads used for DNS resolving. This value can be increased, if +# your server experience a big number of connecting clients. +# +resolvers 1 + +# +# IO Readahead. +# +# Set size of per-connection buffer used for io readahead operations. +# +readahead 8192 + +# +# Coroutine cache size. +# +# Set pool size of free coroutines cache. It is a good idea to set +# this value to a sum of max clients plus server connections. Please note, that +# each coroutine consumes around `coroutine_stack_size` of memory. +# +# Set to zero, to disable coroutine cache. +# +cache_coroutine 0 + +# +# Coroutine stack size. +# +# Set coroutine stack size in pages. In some rare cases +# it might be necessary to make stack size bigger. Actual stack will be +# allocated as (`coroutine_stack_size` + 1_guard_page) * page_size. +# Guard page is used to track stack overflows. +# +# 16KB by default. +# +coroutine_stack_size 8 + +# +# TCP nodelay. +# +# Set to 'yes', to enable nodelay. +# +nodelay yes + +# +# TCP keepalive time. +# +# Set to zero, to disable keepalive. +# +keepalive 15 + +# +# TCP keepalive interval +# + +keepalive_keep_interval 75 + +# +# TCP keepalive probes +# + +keepalive_probes 9 + +# +# TCP user timeout +# +keepalive_usr_timeout 0 + +### +### GLOBAL LIMITS +### + +# +# Global limit of client connections. +# +# Comment 'client_max' to disable the limit. On client limit reach, Odyssey will +# reply with 'too many connections'. +# +# client_max 100 + +# +# Global limit of client connections concurrently being routed. +# Client connection is being routed after it is accepted and until it's startup +# message is read and connection is assigned route to the database. Most of the +# routing time is occupied with TLS handshake. +# +# Unset or zero 'client_max_routing' will set it's value equal to 16 * workers +# +# client_max_routing 32 + +# +# If server responds with "Too many clients" client will wait for server_login_retry milliseconds. +# +# server_login_retry +# +# 1 by default. + +### +### LISTEN +### + +# +# Listen section defines listening servers used for accepting +# incoming client connections. +# +# It is possible to define several Listen sections. Odyssey will listen on +# every specified address port and can use separate TLS settings. +# +# Odyssey will fail in case it could not bind on any resolved address. +# + +listen { +# +# Bind address. +# +# If host is not set, Odyssey will try to listen using UNIX socket if +# unix_socket_dir is set. +# + host "*" +# +# Listen port. + port 6432 +# +# TCP listen backlog. + backlog 128 +# +# TLS support. +# +# Supported TLS modes: +# +# "disable" - disable TLS protocol +# "allow" - switch to TLS protocol on request +# "require" - TLS clients only +# "verify_ca" - require valid client certificate +# "verify_full" - require valid client certificate +# +# tls "disable" +# tls_ca_file "" +# tls_key_file "" +# tls_cert_file "" +# tls_protocols "" + +# +# Support of PostgreSQL protocol compression (experimental). Set to 'yes' to enable, disabled by default. +# + compression no + +# client_login_timeout +# Prevent client stall during routing for more that client_login_timeout milliseconds. +# Defaults to 15000. +} + +### +### ROUTING +### + +# +# Odyssey allows to define client routing rules by specifying +# 'database', 'user' and 'storage' sections. +# +# On client accept appropriate route is assigned by matching 'database' and +# 'user' sections, all requests then forwarded to a 'storage' +# (which is referenced from the 'user' section). +# +# Database | default. +# +# Defines database name requested by client. Each 'database' section structure +# consist of a 'user' subsections. +# +# A special 'database default' is used, in case when no database is matched. +# +# User | default. +# +# Defines authentication, pooling and storage settings for +# requested route. +# +# A special 'user default' is used, in case when no user is matched. +# +# Storage . +# +# Defines server used as a data storage or admin console operations. +# + +storage "postgres_server" { +# +# Storage type. +# +# "remote" - PostgreSQL server +# "local" - Odyssey (admin console) +# + type "remote" +# +# Remote server address. +# +# If host is not set, Odyssey will try to connect using UNIX socket if +# unix_socket_dir is set. +# Multiple hosts may be specified, separate with comma. Port should be specified +# using [] braces + + host "[localhost]:5432,host1,[192.168.1.1]:5433" +# +# Default remote server port. Odyssey will use this port for remote host connection +# if port was not specified using [] braces. +# + port 5432 + +# +# Target session attrs feature. Odyssey will lookup for primary/standby, depending on +# value set. +# Possible values are: +# * read-write - always select host, avalible for write +# * read-only - never select host, avalible for write +# * any (the default one) - select host randomly +# +# Odyssey will traverse host and execute pg_is_in_recovery against them, to check if +# host is primary or not. +# +# target_session_attrs "read-write" +# + +# +# Remote server TLS settings. +# +# tls "disable" +# tls_ca_file "" +# tls_key_file "" +# tls_cert_file "" +# tls_protocols "" + +# +# Global limit of server connections concurrently being routed. +# We are opening no more than server_max_routing server connections concurrently. +# +# Unset or zero 'server_max_routing' will set it's value equal to number of workers +# +# server_max_routing 4 + + +# Storage lag-polling watchdog +# +# Defines storage lag-polling watchdog options and actually enables cron-like +# watchdog for this storage. This routine will execute `watchdog_lag_query` againts +# storage server and send return value to all routes, to decide, if connecting is desirable +# with particular lag value. + + watchdog { + authentication "none" + + storage "postgres_server" + storage_db "postgres" + storage_user "postgres" + + pool_routing "internal" + pool "transaction" + pool_size 10 + + pool_timeout 0 + pool_ttl 1201 + + log_debug no + +# Watchdog will execute this query to get underlaying server lag. +# Consider something like now() - pg_last_xact_replay_timestamp() or +# git@github.com:man-brain/repl_mon.git for production usages + watchdog_lag_query "SELECT TRUNC(EXTRACT(EPOCH FROM NOW())) - 100" + watchdog_lag_interval 10 + } +} + +database default { + user default { +# +# Authentication method. +# +# "none" - authentication turned off +# "block" - block this user +# "clear_text" - PostgreSQL clear text authentication +# "md5" - PostgreSQL md5 authentication +# "scram-sha-256" - PostgreSQL scram-sha-256 authentication +# "cert" - Compare client certificate Common Name against auth_common_name's +# + authentication "none" + +# +# Authentication certificate CN. +# +# Specify common names to check for "cert" authentification method. +# If there are more then one common name is defined, all of them +# will be checked until match. +# +# Set 'default' to check for current user. +# +# auth_common_name default +# auth_common_name "test" + +# +# Authentication method password. +# +# Depending on selected method, password can be in plain text or md5 hash. +# +# password "" + +# +# Authentication query. +# +# Use selected 'auth_query_db' and 'auth_query_user' to match a route. +# Use matched route server to send 'auth_query' to get username and password needed +# to authenticate a client. +# +# auth_query "SELECT usename, passwd FROM pg_shadow WHERE usename=$1" +# auth_query_db "" +# auth_query_user "" + +# Authentication PAM. +# +# auth_pam_service "passwd" + +# +# Client connections limit. +# +# Comment 'client_max' to disable the limit. On client limit reach, Odyssey will +# reply with 'too many connections'. +# +# client_max 100 + +# +# Remote server to use. +# +# By default route database and user names are used as connection +# parameters to remote server. It is possible to override this values +# by specifying 'storage_db' and 'storage_user'. Remote server password +# can be set using 'storage_password' field. +# + storage "postgres_server" +# storage_db "database" +# storage_user "test" +# storage_password "test" +# + +# Remote server auth +# password_passthrough "yes" +# By default odyssey authenticate users itself, but if side auth application is used, +# like LDAP server, PAM module, or custom auth module, sometimes, +# instead of configuring storage_password, it is more convenient to reuse +# client-provided password to perform backend auth. If you set this option to "yes" +# Odyssey will store client token and use when new server connection is Opened. Anyway, if +# you configure storage_password for route, password_passthrough is essentially ignored +# + +# +# Server pool mode. +# +# "session" - assign server connection to a client until it disconnects +# "transaction" - assign server connection to a client during a transaction lifetime +# + pool "transaction" + +# +# Server pool size. +# +# Keep the number of servers in the pool as much as 'pool_size'. +# Clients are put in a wait queue, when all servers are busy. +# +# Set to zero to disable the limit. +# + pool_size 0 + +# +# Server pool wait timeout. +# +# Time to wait in milliseconds for an available server. +# Disconnect client on timeout reach. +# +# Set to zero to disable. +# + pool_timeout 0 + +# +# Server pool idle timeout. +# +# Close an server connection when it becomes idle for 'pool_ttl' seconds. +# +# Set to zero to disable. +# + pool_ttl 60 + +# +# Server pool parameters discard. +# +# Execute 'DISCARD ALL' and reset client parameters before using server +# from the pool. +# + pool_discard no + +# +# Server pool auto-cancel. +# +# Start additional Cancel connection in case if server left with +# executing query. Close connection otherwise. +# + pool_cancel yes + +# +# Server pool auto-rollback. +# +# Execute 'ROLLBACK' if server left in active transaction. +# Close connection otherwise. +# + pool_rollback yes + +# +# drop stale client connection after this much seconds of idleness, which is not in transaction. 0 means inf (never drop) +# + pool_client_idle_timeout 0 + +# +# drop client connection in transaction after this much seconds of idleness. 0 means inf (never drop) +# + pool_idle_in_transaction_timeout 0 + +# +# Forward PostgreSQL errors during remote server connection. +# + client_fwd_error yes + +# +# Add client host name to application_name parameter +# + + application_name_add_host yes + +# +# Connect new client to server immediately or wait for first query +# + reserve_session_server_connection yes + +# +# Server lifetime - maximum number of seconds for a server connetion to live. Prevents cache bloat. +# Defaults to 3600 (1 hour) +# + + server_lifetime 3600 + +# +# Enable verbose mode for a specific route only. +# + log_debug no + +# Compute quantiles of query and transaction times + quantiles "0.99,0.95,0.5" + } +} + + + + +### +### ODYSSEY MODULES +### + +# +# You can create your DIY SO file and put here to load on start +# Check list of available callback in module.h +# +# load_module "/tmp/od_modules/audit_module.so" + +### +### ADMIN CONSOLE (example) +### + + +#storage "local" { +# type "local" +#} + +#database "console" { +# user default { +# authentication "none" +# role "admin" +# pool "session" +# storage "local" +# } +#} + +