Documentation
¶
Overview ¶
Package l4postgres allows the L4 multiplexing of Postgres connections.
The single "postgres" matcher detects a Postgres connection and can, in addition, filter on the contents of the first message the client sends:
- user filters on the user (and, optionally, database) StartupMessage parameters;
- client filters on the application_name StartupMessage parameter;
- ssl requires the presence or absence of an SSLRequest.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func TLSClient ¶ added in v0.1.2
TLSClient performs the PostgreSQL SSLRequest negotiation as a client on conn: it sends the SSLRequest, reads the server's reply, and on 'S' completes a TLS handshake using cfg, returning the encrypted connection. On 'N' (the server declines TLS) or any other reply it returns an error.
Use this to re-originate TLS to a Postgres upstream that expects sslmode != disable, i.e. the outbound counterpart of the inbound termination done by Handler + the `tls` handler.
Types ¶
type Handler ¶ added in v0.1.2
type Handler struct{}
Handler negotiates the PostgreSQL SSLRequest preamble so that a following `tls` handler can terminate TLS and downstream matchers can then match the (now cleartext) startup message — e.g. by user, database, or application_name.
PostgreSQL does not begin TLS with a ClientHello: the client first sends an 8-byte SSLRequest and waits for a single byte, 'S' (server will use TLS) or 'N' (continue in plaintext). The generic `tls` handler expects a ClientHello immediately, so it cannot terminate a Postgres connection on its own. This handler reads the SSLRequest, replies 'S', and passes the connection on; put a `tls` handler next to perform the actual TLS handshake.
It must be preceded by a matcher that confirms the connection is a Postgres SSLRequest (e.g. the postgres matcher), so the 8 bytes it consumes really are the SSLRequest.
Example (Caddyfile): note that `postgres` is a matcher (it gates the route), while `postgres_tls`, `tls` and `proxy` are the handlers run on a match.
@pg postgres
route @pg {
postgres_tls
tls
# downstream matchers now see the cleartext startup message
proxy ...
}
func (*Handler) CaddyModule ¶ added in v0.1.2
func (*Handler) CaddyModule() caddy.ModuleInfo
CaddyModule returns the Caddy module information.
type MatchPostgres ¶
type MatchPostgres struct {
// User maps a Postgres user name to the databases it is allowed to use.
// The special key "*" applies to any user not listed explicitly. An empty
// (or nil) database list matches any database for that user. Only applies to
// StartupMessages (which carry the user/database parameters).
User map[string][]string `json:"user,omitempty"`
// Client is the list of accepted application_name values. Only applies to
// StartupMessages (which carry the application_name parameter).
Client []string `json:"client,omitempty"`
// TLS constrains whether the connection must begin with an SSLRequest:
// "enabled" requires one, "disabled" requires its absence, and "" (the
// default) is indifferent.
TLS string `json:"tls,omitempty"`
}
MatchPostgres matches Postgres connections. With no options set it matches any well-formed Postgres first message (SSLRequest, CancelRequest or a protocol-3 StartupMessage). The optional User, Client and TLS fields further constrain the match; when more than one is set, all must be satisfied.
func (*MatchPostgres) CaddyModule ¶
func (*MatchPostgres) CaddyModule() caddy.ModuleInfo
CaddyModule returns the Caddy module information.
func (*MatchPostgres) Match ¶
func (m *MatchPostgres) Match(cx *layer4.Connection) (bool, error)
Match returns true if the connection looks like the Postgres protocol and satisfies every configured constraint (tls, user/database, application_name).
func (*MatchPostgres) Provision ¶
func (m *MatchPostgres) Provision(_ caddy.Context) error
Provision validates the TLS option.
func (*MatchPostgres) UnmarshalCaddyfile ¶
func (m *MatchPostgres) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
UnmarshalCaddyfile sets up the matcher from Caddyfile tokens. Syntax:
postgres
postgres {
# match user/database pairs; repeat for each entry, "*" is the wildcard
user <name> [<database>...]
# match the application_name parameter
client <name> [<name>...]
# require (enabled) or reject (disabled) an SSLRequest; "*" is indifferent
tls <enabled|disabled|*>
}