postgres

package
v0.0.0-...-5c79d48 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2024 License: AGPL-3.0 Imports: 37 Imported by: 0

Documentation

Overview

Package postgres implements components of the database access subsystem that proxy connections between Postgres clients (like, psql or pgAdmin) and Postgres database servers with full protocol awareness.

It understands Postgres wire protocol version 3 which is supported by Postgres 7.4 and later:

https://www.postgresql.org/docs/13/protocol-flow.html https://www.postgresql.org/docs/13/protocol-message-formats.html

The package provides the following main types:

  • Proxy. Runs inside Teleport proxy and proxies connections from Postgres clients to appropriate database servers over reverse tunnel.

  • Engine. Runs inside Teleport database service, accepts connections coming from proxy over reversetunnel and proxies them to databases.

  • TestServer. Fake Postgres server that implements a small part of its wire protocol, used in functional tests.

Protocol --------

When connecting to a database server (or a Teleport proxy in our case), Postgres clients start on a plain connection to check whether the server supports TLS and then upgrade the connection.

Because of that, the proxy implements a part of the startup protocol that indicates TLS support to the client to get it to send a client certificate and extracts the identity/routing information from it.

After that proxy hands off the connection to an appropriate database server based on the extracted routing info over reverse tunnel.

The database server in turn connects to the database and starts relaying messages between the database and the client.

The sequence diagram roughly looks like this:

psql proxy

|                       |
| ---- SSLRequest ----> |
|                       |
| <------  'S' -------- |
|                       |
| -- StartupMessage --> |                     engine
|                       |                       |
|                       | -- StartupMessage --> |                  Postgres
|                       |                       |                     |
|                       |                       | ----- connect ----> |
|                       |                       |                     |
| <-------------- ReadyForQuery --------------- |                     |
|                       |                       |                     |
| ------------------------------ Query -----------------------------> |
| <---------------------------- DataRow ----------------------------- |
| <------------------------- ReadyForQuery -------------------------- |
|                       |                       |                     |
| ----------------------------- Terminate --------------------------> |
|                       |                       |                     |

Index

Constants

View Source
const TestLongRunningQuery = "pg_sleep(forever)"

TestLongRunningQuery is a stub SQL query clients can use to simulate a long running query that can be only be stopped by a cancel request.

Variables

View Source
var TestQueryResponse = &pgconn.Result{
	FieldDescriptions: []pgproto3.FieldDescription{{Name: []byte("test-field")}},
	Rows:              [][][]byte{{[]byte("test-value")}},
	CommandTag:        pgconn.CommandTag("select 1"),
}

TestQueryResponse is the response test Postgres server sends to every query.

Functions

func MakeTestClient

func MakeTestClient(ctx context.Context, config common.TestClientConfig) (*pgconn.PgConn, error)

MakeTestClient returns Postgres client connection according to the provided parameters.

func NewEngine

func NewEngine(ec common.EngineConfig) common.Engine

NewEngine create new Postgres engine.

Types

type Engine

type Engine struct {
	// EngineConfig is the common database engine configuration.
	common.EngineConfig
	// contains filtered or unexported fields
}

Engine implements the Postgres database service that accepts client connections coming over reverse tunnel from the proxy and proxies them between the proxy and the Postgres database instance.

Implements common.Engine.

func (*Engine) ActivateUser

func (e *Engine) ActivateUser(ctx context.Context, sessionCtx *common.Session) error

ActivateUser creates or enables the database user.

func (*Engine) DeactivateUser

func (e *Engine) DeactivateUser(ctx context.Context, sessionCtx *common.Session) error

DeactivateUser disables the database user.

func (*Engine) DeleteUser

func (e *Engine) DeleteUser(ctx context.Context, sessionCtx *common.Session) error

DeleteUser deletes the database user.

func (*Engine) HandleConnection

func (e *Engine) HandleConnection(ctx context.Context, sessionCtx *common.Session) error

HandleConnection processes the connection from Postgres proxy coming over reverse tunnel.

It handles all necessary startup actions, authorization and acts as a middleman between the proxy and the database intercepting and interpreting all messages i.e. doing protocol parsing.

func (*Engine) InitializeConnection

func (e *Engine) InitializeConnection(clientConn net.Conn, sessionCtx *common.Session) error

InitializeConnection initializes the client connection.

func (*Engine) SendError

func (e *Engine) SendError(err error)

SendError sends an error to connected client in a Postgres understandable format.

type Proxy

type Proxy struct {
	// TLSConfig is the proxy TLS configuration.
	TLSConfig *tls.Config
	// Middleware is the auth middleware.
	Middleware *auth.Middleware
	// Service is used to connect to a remote database service.
	Service common.Service
	// Log is used for logging.
	Log logrus.FieldLogger
	// Limiter limits the number of active connections per client IP.
	Limiter *limiter.Limiter
	// IngressReporter reports new and active connections.
	IngressReporter *ingress.Reporter
}

Proxy proxies connections from Postgres clients to database services over reverse tunnel. It runs inside Teleport proxy service.

Implements common.Proxy.

func (*Proxy) HandleConnection

func (p *Proxy) HandleConnection(ctx context.Context, clientConn net.Conn) (err error)

HandleConnection accepts connection from a Postgres client, authenticates it and proxies it to an appropriate database service.

type TestServer

type TestServer struct {
	// contains filtered or unexported fields
}

TestServer is a test Postgres server used in functional database access tests.

It supports a very small subset of Postgres wire protocol that can:

  • Accept a TLS connection from Postgres client.
  • Reply with the same TestQueryResponse to every query the client sends.
  • Recognize terminate messages from clients closing connections.

func NewTestServer

func NewTestServer(config common.TestServerConfig) (svr *TestServer, err error)

NewTestServer returns a new instance of a test Postgres server.

func (*TestServer) Close

func (s *TestServer) Close() error

Close closes the server listener.

func (*TestServer) ParametersCh

func (s *TestServer) ParametersCh() chan map[string]string

ParametersCh returns channel that receives startup message parameters.

func (*TestServer) Port

func (s *TestServer) Port() string

Port returns the port server is listening on.

func (*TestServer) QueryCount

func (s *TestServer) QueryCount() uint32

QueryCount returns the number of queries the server has received.

func (*TestServer) Serve

func (s *TestServer) Serve() error

Serve starts serving client connections.

func (*TestServer) UserEventsCh

func (s *TestServer) UserEventsCh() <-chan UserEvent

UserEventsCh returns channel that receives user activate/deactivate events.

type UserEvent

type UserEvent struct {
	// Name is the user Name.
	Name string
	// Roles are the user Roles.
	Roles []string
	// Active is whether user activated or deactivated.
	Active bool
}

UserEvent represents a user activation/deactivation event.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL