Documentation ¶
Overview ¶
Package multiplexer implements SSH and TLS multiplexing on the same listener
mux, _ := multiplexer.New(Config{Listener: listener}) mux.SSH() // returns listener getting SSH connections mux.TLS() // returns listener getting TLS connections
Index ¶
- Constants
- Variables
- func MarshalTLVs(tlvs []TLV) ([]byte, error)
- type CertAuthorityGetter
- type Config
- type Conn
- func (c *Conn) Detect() (Protocol, error)
- func (c *Conn) Discard(n int) (discarded int, err error)
- func (c *Conn) LocalAddr() net.Addr
- func (c *Conn) NetConn() net.Conn
- func (c *Conn) Peek(n int) ([]byte, error)
- func (c *Conn) Protocol() Protocol
- func (c *Conn) Read(p []byte) (int, error)
- func (c *Conn) ReadByte() (byte, error)
- func (c *Conn) ReadProxyLine() (*ProxyLine, error)
- func (c *Conn) RemoteAddr() net.Addr
- type JWTPROXYSigner
- type Listener
- type Mux
- type PP2TeleportSubtype
- type PP2Type
- type PROXYEnabledListener
- type PROXYHeaderSigner
- type PROXYProtocolMode
- type PROXYSigner
- type PostDetectFunc
- type PreDetectFunc
- type Protocol
- type ProxyLine
- func (p *ProxyLine) AddSignature(signature, signingCert []byte) error
- func (p *ProxyLine) Bytes() ([]byte, error)
- func (p *ProxyLine) IsSigned() bool
- func (p *ProxyLine) String() string
- func (p *ProxyLine) VerifySignature(ctx context.Context, caGetter CertAuthorityGetter, localClusterName string, ...) error
- type TLSListener
- type TLSListenerConfig
- type TLV
- type TestProxy
- type WebListener
- type WebListenerConfig
Constants ¶
const ( // TCP4 is TCP over IPv4 TCP4 = "TCP4" // TCP6 is tCP over IPv6 TCP6 = "TCP6" // Unknown is unsupported or unknown protocol UNKNOWN = "UNKNOWN" PP2TypeNOOP PP2Type = 0x04 // No-op used for padding // Known custom types, spec allows to use 0xE0 - 0xEF for custom types PP2TypeGCP PP2Type = 0xE0 // https://cloud.google.com/vpc/docs/configure-private-service-connect-producer PP2TypeAWS PP2Type = 0xEA // https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html PP2TypeAzure PP2Type = 0xEE // https://learn.microsoft.com/en-us/azure/private-link/private-link-service-overview PP2TypeTeleport PP2Type = 0xE4 // Teleport own type for transferring our custom data such as connection metadata PP2TeleportSubtypeSigningCert PP2TeleportSubtype = 0x01 // Certificate used to sign JWT PP2TeleportSubtypeJWT PP2TeleportSubtype = 0x02 // JWT used to verify information sent in plain PROXY header )
const ( Version2 = 2 ProxyCommand = 1 LocalCommand = 0 ProtocolTCP4 = 0x11 ProtocolTCP6 = 0x21 )
Variables ¶
var ( // ErrTruncatedTLV is returned when there's no enough bytes to read full TLV ErrTruncatedTLV = errors.New("TLV value was truncated") // ErrNoSignature is returned when proxy line doesn't have full required data (JWT and cert) for verification ErrNoSignature = errors.New("could not find signature data on the proxy line") // ErrBadCACert is returned when a HostCA cert could not successfully be added to roots for signing certificate verification ErrBadCACert = errors.New("could not add host CA to roots for verification") // ErrIncorrectRole is returned when signing cert doesn't have required system role (Proxy) ErrIncorrectRole = errors.New("could not find required system role on the signing certificate") // ErrNonLocalCluster is returned when we received signed PROXY header, which signing certificate is from remote cluster. ErrNonLocalCluster = errors.New("signing certificate is not signed by local cluster CA") // ErrNoHostCA is returned when CAGetter could not get host CA, for example if auth server is not available ErrNoHostCA = errors.New("could not get specified host CA to verify signed PROXY header") )
var ( // ErrBadIP is returned when there's a problem with client source or destination IP address ErrBadIP = trace.BadParameter( "client source and destination addresses should be valid same TCP version non-nil IP addresses") )
var (
ProxyV2Prefix = []byte{0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}
)
Functions ¶
func MarshalTLVs ¶
MarshalTLVs marshals provided slice of TLVs into slice of bytes.
Types ¶
type CertAuthorityGetter ¶
type CertAuthorityGetter = func(ctx context.Context, id types.CertAuthID, loadKeys bool) (types.CertAuthority, error)
CertAuthorityGetter allows to get cluster's host CA for verification of signed PROXY headers. We define our own version to not create dependency on the 'services' package, which causes circular references
type Config ¶
type Config struct { // Listener is listener to multiplex connection on Listener net.Listener // Context is a context to signal stops, cancellations Context context.Context // DetectTimeout is a timeout applied to the whole detection phase of the // connection, set to defaults.ReadHeadersTimeout if unspecified DetectTimeout time.Duration // Clock is a clock to override in tests, set to real time clock // by default Clock clockwork.Clock // PROXYProtocolMode controls behavior related to unsigned PROXY protocol headers. PROXYProtocolMode PROXYProtocolMode // ID is an identifier used for debugging purposes ID string // CertAuthorityGetter is used to get CA to verify singed PROXY headers sent internally by teleport CertAuthorityGetter CertAuthorityGetter // LocalClusterName set the local cluster for the multiplexer, it's used in PROXY headers verification. LocalClusterName string // IgnoreSelfConnections is used for tests, it makes multiplexer ignore the fact that it's self // connection (coming from same IP as the listening address) when deciding if it should drop connection with // missing required PROXY header. This is needed since all connections in tests are self connections. IgnoreSelfConnections bool // PreDetect, if set, is called on each incoming connection before protocol // detection; the returned [PostDetectFunc] (if any) will then be called // after protocol detection, and will have the ability to modify or wrap the // [*Conn] before it's passed to the listener; if the PostDetectFunc returns // a nil [net.Conn], the connection will not be handled any further by the // multiplexer, and it's the responsibility of the PostDetectFunc to arrange // for it to be eventually closed. PreDetect PreDetectFunc }
Config is a multiplexer config
func (*Config) CheckAndSetDefaults ¶
CheckAndSetDefaults verifies configuration and sets defaults
type Conn ¶
Conn is a connection wrapper that supports communicating remote address from proxy protocol and replays first several bytes read during protocol detection
func (*Conn) Discard ¶
Discard is *bufio.Reader.Discard.
func (*Conn) ReadProxyLine ¶
ReadProxyLine reads proxy-line from the connection.
func (*Conn) RemoteAddr ¶
RemoteAddr returns remote address of the connection
type JWTPROXYSigner ¶
type JWTPROXYSigner interface {
SignPROXYJWT(p jwt.PROXYSignParams) (string, error)
}
JWTPROXYSigner provides ability to created JWT for signed PROXY headers.
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener is a listener that receives connections from multiplexer based on the connection type
type Mux ¶
Mux supports having both SSH and TLS on the same listener socket
func (*Mux) Serve ¶
Serve is a blocking function that serves on the listening socket and accepts requests. Every request is served in a separate goroutine
func (*Mux) Wait ¶
func (m *Mux) Wait()
Wait waits until listener shuts down and stops accepting new connections this is to workaround issue https://github.com/golang/go/issues/10527 in tests
type PP2TeleportSubtype ¶
type PP2TeleportSubtype PP2Type
type PROXYEnabledListener ¶
PROXYEnabledListener wraps provided listener and can receive and apply PROXY headers and then pass connection up the chain.
func NewPROXYEnabledListener ¶
func NewPROXYEnabledListener(cfg Config) (*PROXYEnabledListener, error)
NewPROXYEnabledListener creates news instance of PROXYEnabledListener
func (*PROXYEnabledListener) Accept ¶
func (p *PROXYEnabledListener) Accept() (net.Conn, error)
Accept gets connection from the wrapped listener and detects whether we receive PROXY headers on it, after first non PROXY protocol detected it returns connection with PROXY addresses applied to it.
func (*PROXYEnabledListener) Close ¶
func (p *PROXYEnabledListener) Close() error
type PROXYHeaderSigner ¶
PROXYHeaderSigner allows to sign PROXY headers for securely propagating original client IP information
type PROXYProtocolMode ¶
type PROXYProtocolMode string
PROXYProtocolMode controls behavior related to unsigned PROXY protocol headers. Possible values: - 'on': one PROXY header is accepted and required per incoming connection. - 'off': no PROXY headers are allows, otherwise connection is rejected. If unspecified - one PROXY header is allowed, but not required. Connection is marked with source port set to 0 and IP pinning will not be allowed. It is supposed to be used only as default mode for test setups. In production you should always explicitly set the mode based on your network setup - if you have L4 load balancer with enabled PROXY protocol in front of Teleport you should set it to 'on', if you don't have it, set it to 'off'
const ( PROXYProtocolOn PROXYProtocolMode = "on" PROXYProtocolOff PROXYProtocolMode = "off" PROXYProtocolUnspecified PROXYProtocolMode = "" )
type PROXYSigner ¶
type PROXYSigner struct {
// contains filtered or unexported fields
}
PROXYSigner implements PROXYHeaderSigner to sign PROXY headers
func NewPROXYSigner ¶
func NewPROXYSigner(signingCert *x509.Certificate, jwtSigner JWTPROXYSigner) (*PROXYSigner, error)
NewPROXYSigner returns a new instance of PROXYSigner
func (*PROXYSigner) SignPROXYHeader ¶
func (p *PROXYSigner) SignPROXYHeader(source, destination net.Addr) ([]byte, error)
SignPROXYHeader creates a signed PROXY header with provided source and destination addresses
type PostDetectFunc ¶
PostDetectFunc is optionally returned by a PreDetectFunc.
type PreDetectFunc ¶
type PreDetectFunc = func(net.Conn) (PostDetectFunc, error)
PreDetectFunc is used in Mux's Config as the PreDetect hook.
type Protocol ¶
type Protocol int
Protocol defines detected protocol type.
const ( // ProtoUnknown is for unknown protocol ProtoUnknown Protocol = iota // ProtoTLS is TLS protocol ProtoTLS // ProtoSSH is SSH protocol ProtoSSH // ProtoProxy is a HAProxy proxy line protocol ProtoProxy // ProtoProxyV2 is a HAProxy binary protocol ProtoProxyV2 // ProtoHTTP is HTTP protocol ProtoHTTP // ProtoPostgres is PostgreSQL wire protocol ProtoPostgres )
type ProxyLine ¶
type ProxyLine struct { Protocol string Source net.TCPAddr Destination net.TCPAddr TLVs []TLV // PROXY protocol extensions IsVerified bool }
ProxyLine implements PROXY protocol version 1 and 2 Spec: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt Original implementation here: https://github.com/racker/go-proxy-protocol TLV: https://github.com/pires/go-proxyproto
func ReadProxyLine ¶
ReadProxyLine reads proxy line protocol from the reader
func ReadProxyLineV2 ¶
ReadProxyLineV2 reads PROXY protocol v2 line from the reader
func (*ProxyLine) AddSignature ¶
AddSignature adds provided signature and cert to the proxy line, marshaling it into appropriate TLV structure.
func (*ProxyLine) Bytes ¶
Bytes returns on-the wire bytes representation of proxy line conforming to the proxy v2 protocol
func (*ProxyLine) IsSigned ¶
IsSigned returns true if proxy line's TLV contains signature. Does not take into account if signature is valid or not, just the presence of it.
func (*ProxyLine) VerifySignature ¶
func (p *ProxyLine) VerifySignature(ctx context.Context, caGetter CertAuthorityGetter, localClusterName string, clock clockwork.Clock) error
VerifySignature checks that signature contained in the proxy line is securely signed.
type TLSListener ¶
type TLSListener struct {
// contains filtered or unexported fields
}
TLSListener wraps tls.Listener and detects negotiated protocol (assuming it's either http/1.1 or http/2) and forwards the appropriate responses to either HTTP/1.1 or HTTP/2 listeners
func NewTLSListener ¶
func NewTLSListener(cfg TLSListenerConfig) (*TLSListener, error)
NewTLSListener returns a new TLS listener
func (*TLSListener) Addr ¶
func (l *TLSListener) Addr() net.Addr
Addr returns the listener's network address.
func (*TLSListener) Close ¶
func (l *TLSListener) Close() error
Close closes the listener. Any blocked Accept operations will be unblocked and return errors.
func (*TLSListener) Serve ¶
func (l *TLSListener) Serve() error
Serve accepts and forwards tls.Conn connections
type TLSListenerConfig ¶
type TLSListenerConfig struct { // Listener is the listener returning *tls.Conn // connections on Accept Listener net.Listener // ID is an identifier used for debugging purposes ID string // ReadDeadline is a connection read deadline during the TLS handshake (start // of the connection). It is set to defaults.HandshakeReadDeadline if // unspecified. ReadDeadline time.Duration // Clock is a clock to override in tests, set to real time clock // by default Clock clockwork.Clock }
TLSListenerConfig specifies listener configuration
func (*TLSListenerConfig) CheckAndSetDefaults ¶
func (c *TLSListenerConfig) CheckAndSetDefaults() error
CheckAndSetDefaults verifies configuration and sets defaults
type TLV ¶
TLV (Type-Length-Value) is an extension mechanism in PROXY protocol v2, see end of section 2.2
func UnmarshalTLVs ¶
UnmarshalTLVs parses provided bytes slice into slice of TLVs
type TestProxy ¶
type TestProxy struct {
// contains filtered or unexported fields
}
TestProxy is tcp passthrough proxy that sends a proxy-line when connecting to the target server.
func NewTestProxy ¶
NewTestProxy creates a new test proxy that sends a proxy-line when proxying connections to the provided target address.
type WebListener ¶
type WebListener struct {
// contains filtered or unexported fields
}
WebListener multiplexes tls connections between web and database listeners based on the client certificate.
func NewWebListener ¶
func NewWebListener(cfg WebListenerConfig) (*WebListener, error)
NewWebListener returns a new web listener.
func (*WebListener) Addr ¶
func (l *WebListener) Addr() net.Addr
Addr returns the listener's network address.
func (*WebListener) Close ¶
func (l *WebListener) Close() error
Close closes the listener.
Any blocked Accept operations will be unblocked and return errors.
func (*WebListener) DB ¶
func (l *WebListener) DB() net.Listener
DB returns database access listener.
func (*WebListener) Serve ¶
func (l *WebListener) Serve() error
Serve starts accepting and forwarding tls connections to appropriate listeners.
type WebListenerConfig ¶
type WebListenerConfig struct { // Listener is the listener that accepts tls connections. Listener net.Listener // ReadDeadline is a connection read deadline during the TLS handshake. ReadDeadline time.Duration // Clock is a clock to override in tests. Clock clockwork.Clock }
WebListenerConfig is the web listener configuration.
func (*WebListenerConfig) CheckAndSetDefaults ¶
func (c *WebListenerConfig) CheckAndSetDefaults() error
CheckAndSetDefaults verifies configuration and sets defaults.