pgwire

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2022 License: Apache-2.0 Imports: 76 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ErrSSLRequired is returned when a client attempts to connect to a
	// secure server in cleartext.
	ErrSSLRequired = "node is running secure mode, SSL connection required"

	// ErrDrainingNewConn is returned when a client attempts to connect to a server
	// which is not accepting client connections.
	ErrDrainingNewConn = "server is not accepting clients, try another node"
	// ErrDrainingExistingConn is returned when a connection is shut down because
	// the server is draining.
	ErrDrainingExistingConn = "server is shutting down"
)

Variables

View Source
var (
	MetaConns = metric.Metadata{
		Name:        "sql.conns",
		Help:        "Number of active sql connections",
		Measurement: "Connections",
		Unit:        metric.Unit_COUNT,
	}
	MetaNewConns = metric.Metadata{
		Name:        "sql.new_conns",
		Help:        "Counter of the number of sql connections created",
		Measurement: "Connections",
		Unit:        metric.Unit_COUNT,
	}
	MetaBytesIn = metric.Metadata{
		Name:        "sql.bytesin",
		Help:        "Number of sql bytes received",
		Measurement: "SQL Bytes",
		Unit:        metric.Unit_BYTES,
	}
	MetaBytesOut = metric.Metadata{
		Name:        "sql.bytesout",
		Help:        "Number of sql bytes sent",
		Measurement: "SQL Bytes",
		Unit:        metric.Unit_BYTES,
	}
	MetaConnLatency = metric.Metadata{
		Name:        "sql.conn.latency",
		Help:        "Latency to establish and authenticate a SQL connection",
		Measurement: "Nanoseconds",
		Unit:        metric.Unit_NANOSECONDS,
	}
	MetaPGWireCancelTotal = metric.Metadata{
		Name:        "sql.pgwire_cancel.total",
		Help:        "Counter of the number of pgwire query cancel requests",
		Measurement: "Requests",
		Unit:        metric.Unit_COUNT,
	}
	MetaPGWireCancelIgnored = metric.Metadata{
		Name:        "sql.pgwire_cancel.ignored",
		Help:        "Counter of the number of pgwire query cancel requests that were ignored due to rate limiting",
		Measurement: "Requests",
		Unit:        metric.Unit_COUNT,
	}
	MetaPGWireCancelSuccessful = metric.Metadata{
		Name:        "sql.pgwire_cancel.successful",
		Help:        "Counter of the number of pgwire query cancel requests that were successful",
		Measurement: "Requests",
		Unit:        metric.Unit_COUNT,
	}
)

Fully-qualified names for metrics.

View Source
var AutoSelectPasswordAuth = settings.RegisterBoolSetting(
	settings.TenantWritable,
	"server.user_login.cert_password_method.auto_scram_promotion.enabled",
	"whether to automatically promote cert-password authentication to use SCRAM",
	true,
).WithPublic()

AutoSelectPasswordAuth determines whether CockroachDB automatically promotes the password protocol when a SCRAM hash is detected in the stored credentials.

It is exported for use in tests.

View Source
var DefaultHBAConfig = func() *hba.Conf {
	loadDefaultMethods()
	conf, err := ParseAndNormalize(`
host  all all  all cert-password # built-in CockroachDB default
local all all      password      # built-in CockroachDB default
`)
	if err != nil {
		panic(err)
	}
	return conf
}()

DefaultHBAConfig is used when the stored HBA configuration string is empty or invalid.

Functions

func Match

func Match(rd io.Reader) bool

Match returns true if rd appears to be a Postgres connection.

func NewReadTimeoutConn

func NewReadTimeoutConn(c net.Conn, checkExitConds func() error) net.Conn

NewReadTimeoutConn wraps the given connection with a readTimeoutConn.

func ParseAndNormalize

func ParseAndNormalize(val string) (*hba.Conf, error)

ParseAndNormalize calls hba.ParseAndNormalize and also ensures the configuration starts with a rule that authenticates the root user with client certificates.

This prevents users from shooting themselves in the foot and making root not able to login, thus disallowing anyone from fixing the HBA configuration.

func RegisterAuthMethod

func RegisterAuthMethod(
	method string, fn AuthMethod, validConnTypes hba.ConnType, checkEntry CheckHBAEntry,
)

RegisterAuthMethod registers an AuthMethod for pgwire authentication and for use in HBA configuration.

The minReqVersion is checked upon configuration to verify whether the current active cluster version is at least the version specified.

The validConnTypes is checked during rule matching when accepting connections: if the connection type is not accepted by the auth method, authentication is refused upfront. For example, the "cert" method requires SSL; if a rule specifies "host .... cert" and the client connects without SSL, the authentication is refused. (To express "cert on SSL, password on non-SSL", the HBA conf can list 'hostssl ... cert; hostnossl .... password' instead.)

The checkEntry method, if provided, is called upon configuration the cluster setting in the SQL client which attempts to change the configuration. It can block the configuration if e.g. the syntax is invalid.

func UseProvidedIdentity

func UseProvidedIdentity(
	_ context.Context, id security.SQLUsername,
) ([]security.SQLUsername, error)

UseProvidedIdentity is a trivial implementation of RoleMapper which always returns its input.

Types

type AuthBehaviors

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

AuthBehaviors encapsulates the per-connection behaviors that may be configured. This type is returned by AuthMethod implementations.

Callers should call the AuthBehaviors.ConnClose method once the associated network connection has been terminated to allow external resources to be released.

func (*AuthBehaviors) Authenticate

func (b *AuthBehaviors) Authenticate(
	ctx context.Context,
	systemIdentity security.SQLUsername,
	clientConnection bool,
	pwRetrieveFn PasswordRetrievalFn,
) error

Authenticate delegates to the Authenticator passed to SetAuthenticator or returns an error if SetAuthenticator has not been called.

func (*AuthBehaviors) ConnClose

func (b *AuthBehaviors) ConnClose()

ConnClose delegates to the function passed to SetConnClose to release any resources associated with the connection. This method is a no-op if SetConnClose has not been called or was called with nil.

func (*AuthBehaviors) MapRole

func (b *AuthBehaviors) MapRole(
	ctx context.Context, systemIdentity security.SQLUsername,
) ([]security.SQLUsername, error)

MapRole delegates to the RoleMapper passed to SetRoleMapper or returns an error if SetRoleMapper has not been called.

func (*AuthBehaviors) ReplacementIdentity

func (b *AuthBehaviors) ReplacementIdentity() (_ security.SQLUsername, ok bool)

ReplacementIdentity returns an optional replacement for the client-provided identity when validating the incoming connection. This allows "ambient" authentication mechanisms, such as GSSAPI, to provide replacement values. This method will return ok==false if SetReplacementIdentity has not been called.

func (*AuthBehaviors) SetAuthenticator

func (b *AuthBehaviors) SetAuthenticator(a Authenticator)

SetAuthenticator updates the Authenticator to be used.

func (*AuthBehaviors) SetConnClose

func (b *AuthBehaviors) SetConnClose(fn func())

SetConnClose updates the connection-close callback.

func (*AuthBehaviors) SetReplacementIdentity

func (b *AuthBehaviors) SetReplacementIdentity(id security.SQLUsername)

SetReplacementIdentity allows the AuthMethod to override the client-reported system identity.

func (*AuthBehaviors) SetRoleMapper

func (b *AuthBehaviors) SetRoleMapper(m RoleMapper)

SetRoleMapper updates the RoleMapper to be used.

type AuthConn

type AuthConn interface {
	// SendAuthRequest send a request for authentication information. After
	// calling this, the authenticator needs to call GetPwdData() quickly, as the
	// connection's goroutine will be blocked on providing us the requested data.
	SendAuthRequest(authType int32, data []byte) error
	// GetPwdData returns authentication info that was previously requested with
	// SendAuthRequest. The call blocks until such data is available.
	// An error is returned if the client connection dropped or if the client
	// didn't respect the protocol. After an error has been returned, GetPwdData()
	// cannot be called any more.
	GetPwdData() ([]byte, error)
	// AuthOK declares that authentication succeeded and provides a
	// unqualifiedIntSizer, to be returned by authenticator.authResult(). Future
	// authenticator.sendPwdData() calls fail.
	AuthOK(context.Context)
	// AuthFail declares that authentication has failed and provides an error to
	// be returned by authenticator.authResult(). Future
	// authenticator.sendPwdData() calls fail. The error has already been written
	// to the client connection.
	AuthFail(err error)

	// SetAuthMethod sets the authentication method for subsequent
	// logging messages.
	SetAuthMethod(method string)
	// SetDbUser updates the AuthConn with the actual database username
	// the connection has authenticated to.
	SetDbUser(dbUser security.SQLUsername)
	// SetSystemIdentity updates the AuthConn with an externally-defined
	// identity for the connection. This is useful for "ambient"
	// authentication mechanisms, such as GSSAPI.
	SetSystemIdentity(systemIdentity security.SQLUsername)
	// LogAuthInfof logs details about the progress of the
	// authentication.
	LogAuthInfof(ctx context.Context, format string, args ...interface{})
	// LogAuthFailed logs details about an authentication failure.
	LogAuthFailed(ctx context.Context, reason eventpb.AuthFailReason, err error)
	// LogAuthOK logs when the authentication handshake has completed.
	LogAuthOK(ctx context.Context)
}

AuthConn is the interface used by the authenticator for interacting with the pgwire connection.

type AuthMethod

type AuthMethod = func(
	ctx context.Context,
	c AuthConn,
	tlsState tls.ConnectionState,
	execCfg *sql.ExecutorConfig,
	entry *hba.Entry,
	identMap *identmap.Conf,
) (*AuthBehaviors, error)

AuthMethod is a top-level factory for composing the various functionality needed to authenticate an incoming connection.

type Authenticator

type Authenticator = func(
	ctx context.Context,
	systemIdentity security.SQLUsername,
	clientConnection bool,
	pwRetrieveFn PasswordRetrievalFn,
) error

Authenticator is a component of an AuthMethod that determines if the given system identity (e.g.: Kerberos or X.509 principal, plain-old username, etc) is who it claims to be.

type CheckHBAEntry

type CheckHBAEntry func(*settings.Values, hba.Entry) error

CheckHBAEntry defines a method for validating an hba Entry upon configuration of the cluster setting by a SQL client.

var NoOptionsAllowed CheckHBAEntry = func(sv *settings.Values, e hba.Entry) error {
	if len(e.Options) != 0 {
		return errors.Newf("the HBA method %q does not accept options", e.Method)
	}
	return nil
}

NoOptionsAllowed is a CheckHBAEntry that returns an error if any options are present in the entry.

type PasswordRetrievalFn

type PasswordRetrievalFn = func(context.Context) (
	expired bool,
	pwHash security.PasswordHash,
	_ error,
)

PasswordRetrievalFn defines a method to retrieve a hashed password and expiration time for a user logging in with password-based authentication.

type RoleMapper

type RoleMapper = func(
	ctx context.Context,
	systemIdentity security.SQLUsername,
) ([]security.SQLUsername, error)

RoleMapper defines a mechanism by which an AuthMethod associated with an incoming connection may replace the caller-provided system identity (e.g.: GSSAPI or X.509 principal, LDAP DN, etc.) with zero or more SQLUsernames that will be subsequently validated against the SQL roles defined within the database. The mapping from system identity to database roles may be derived from the host-based authentication mechanism built into CockroachDB, or it could conceivably be implemented by an external directory service which maps groups of users onto database roles.

func HbaMapper

func HbaMapper(hbaEntry *hba.Entry, identMap *identmap.Conf) RoleMapper

HbaMapper implements the "map" option that may be defined in a host-based authentication rule. If the HBA entry does not define a "map" option, this function will return UseProvidedIdentity.

This mapper will return an error if an applied mapping rule results in the root user or a reserved user, which includes the node, "public", and various other magic prefixes.

type Server

type Server struct {
	AmbientCtx log.AmbientContext

	SQLServer *sql.Server
	// contains filtered or unexported fields
}

Server implements the server side of the PostgreSQL wire protocol.

func MakeServer

func MakeServer(
	ambientCtx log.AmbientContext,
	cfg *base.Config,
	st *cluster.Settings,
	sqlMemMetrics sql.MemoryMetrics,
	parentMemoryMonitor *mon.BytesMonitor,
	histogramWindow time.Duration,
	executorConfig *sql.ExecutorConfig,
) *Server

MakeServer creates a Server.

Start() needs to be called on the Server so it begins processing.

func (*Server) AnnotateCtxForIncomingConn

func (s *Server) AnnotateCtxForIncomingConn(ctx context.Context, conn net.Conn) context.Context

AnnotateCtxForIncomingConn annotates the provided context with a tag that reports the peer's address. In the common case, the context is annotated with a "client" tag. When the server is configured to recognize client-specified remote addresses, it is annotated with a "peer" tag and the "client" tag is added later when the session is set up.

func (*Server) BytesOut

func (s *Server) BytesOut() uint64

BytesOut returns the total number of bytes transmitted from this server.

func (*Server) Drain

func (s *Server) Drain(
	ctx context.Context,
	queryWait time.Duration,
	reporter func(int, redact.SafeString),
	stopper *stop.Stopper,
) error

Drain prevents new connections from being served and waits the duration of queryWait for open connections to terminate before canceling them. An error will be returned when connections that have been canceled have not responded to this cancellation and closed themselves in time. The server will remain in draining state, though open connections may continue to exist. The RFC on drain modes has more information regarding the specifics of what will happen to connections in different states: https://sqlfmt/cockroach/blob/master/docs/RFCS/20160425_drain_modes.md

The reporter callback, if non-nil, is called on a best effort basis to report work that needed to be done and which may or may not have been done by the time this call returns. See the explanation in pkg/server/drain.go for details.

func (*Server) GetAuthenticationConfiguration

func (s *Server) GetAuthenticationConfiguration() (*hba.Conf, *identmap.Conf)

GetAuthenticationConfiguration retrieves the current applicable authentication configuration.

This is guaranteed to return a valid configuration. Additionally, the various setters for the configuration also pass through ParseAndNormalize(), whereby an entry is always present at the start, to enable root to log in with a valid client cert.

The data returned by this method is also observable via the debug endpoint /debug/hba_conf.

func (*Server) GetConnCancelMapLen

func (s *Server) GetConnCancelMapLen() int

GetConnCancelMapLen returns the length of connCancelMap of the server. This is a helper function when the server waits the SQL connections to be closed. During this period, the server listens to the status of all connections, and early exits this draining phase if there remains no active SQL connections.

func (*Server) HBADebugFn

func (s *Server) HBADebugFn() http.HandlerFunc

HBADebugFn exposes the computed HBA configuration via the debug interface, for inspection by tests.

func (*Server) IsDraining

func (s *Server) IsDraining() bool

IsDraining returns true if the server is not currently accepting connections.

func (*Server) Metrics

func (s *Server) Metrics() (res []interface{})

Metrics returns the set of metrics structs.

func (*Server) ServeConn

func (s *Server) ServeConn(ctx context.Context, conn net.Conn, socketType SocketType) error

ServeConn serves a single connection, driving the handshake process and delegating to the appropriate connection type.

The socketType argument is an optimization to avoid a string compare on conn.LocalAddr().Network(). When the socket type is unix datagram (local filesystem), SSL negotiation is disabled even when the server is running securely with certificates. This has the effect of forcing password auth, also in a way compatible with postgres.

An error is returned if the initial handshake of the connection fails.

func (*Server) Start

func (s *Server) Start(ctx context.Context, stopper *stop.Stopper)

Start makes the Server ready for serving connections.

func (*Server) TestingEnableAuthLogging

func (s *Server) TestingEnableAuthLogging()

TestingEnableAuthLogging is exported for use in tests.

func (*Server) TestingEnableConnLogging

func (s *Server) TestingEnableConnLogging()

TestingEnableConnLogging is exported for use in tests.

func (*Server) TestingSetTrustClientProvidedRemoteAddr

func (s *Server) TestingSetTrustClientProvidedRemoteAddr(b bool) func()

TestingSetTrustClientProvidedRemoteAddr is used in tests.

func (*Server) Undrain

func (s *Server) Undrain()

Undrain switches the server back to the normal mode of operation in which connections are accepted.

func (*Server) WaitForSQLConnsToClose

func (s *Server) WaitForSQLConnsToClose(
	ctx context.Context, connectionWait time.Duration, stopper *stop.Stopper,
) error

WaitForSQLConnsToClose waits for the client to close all SQL connections for the duration of connectionWait. With this phase, the node starts rejecting SQL connections, and as soon as all existing SQL connections are closed, the server early exits this draining phase.

type ServerMetrics

type ServerMetrics struct {
	BytesInCount                *metric.Counter
	BytesOutCount               *metric.Counter
	Conns                       *metric.Gauge
	NewConns                    *metric.Counter
	ConnLatency                 *metric.Histogram
	PGWireCancelTotalCount      *metric.Counter
	PGWireCancelIgnoredCount    *metric.Counter
	PGWireCancelSuccessfulCount *metric.Counter
	ConnMemMetrics              sql.BaseMemoryMetrics
	SQLMemMetrics               sql.MemoryMetrics
}

ServerMetrics is the set of metrics for the pgwire server.

type SocketType

type SocketType bool

SocketType indicates the connection type. This is an optimization to prevent a comparison against conn.LocalAddr().Network().

const (
	// SocketTCP is used for TCP sockets. The standard.
	SocketTCP SocketType = true
	// SocketUnix is used for unix datagram sockets.
	SocketUnix SocketType = false
)

Directories

Path Synopsis
Package hba implements an hba.conf parser.
Package hba implements an hba.conf parser.
Package identmap contains the code for parsing a pg_ident.conf file, which allows a database operator to create some number of mappings between system identities (e.g.: GSSAPI or X.509 principals) and database usernames.
Package identmap contains the code for parsing a pg_ident.conf file, which allows a database operator to create some number of mappings between system identities (e.g.: GSSAPI or X.509 principals) and database usernames.
Package pgcode defines the PostgreSQL 5-character support codes used throughout the CockroachDB source tree.
Package pgcode defines the PostgreSQL 5-character support codes used throughout the CockroachDB source tree.
Package pgwirebase contains type definitions and very basic protocol structures to be used by both the pgwire package and by others (particularly by the sql package).
Package pgwirebase contains type definitions and very basic protocol structures to be used by both the pgwire package and by others (particularly by the sql package).

Jump to

Keyboard shortcuts

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