proxy

package
v0.0.25 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2023 License: MIT Imports: 41 Imported by: 0

Documentation

Overview

Package proxy implements a simple lightweight TLS termination proxy that uses Let's Encrypt to provide TLS encryption for any number of TCP and HTTP servers and server names concurrently on the same port.

Index

Constants

View Source
const (
	ModePlaintext      = "PLAINTEXT"
	ModeTCP            = "TCP"
	ModeTLS            = "TLS"
	ModeTLSPassthrough = "TLSPASSTHROUGH"
	ModeHTTP           = "HTTP"
	ModeHTTPS          = "HTTPS"
	ModeConsole        = "CONSOLE"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend struct {
	// ServerNames is the list of all the server names for this service,
	// e.g. example.com, www.example.com.
	ServerNames []string `yaml:"serverNames"`
	// ClientAuth specifies that the TLS client's identity must be verified.
	ClientAuth *ClientAuth `yaml:"clientAuth,omitempty"`
	// AllowIPs specifies a list of IP network addresses to allow, in CIDR
	// format, e.g. 192.168.0.0/24.
	//
	// The rules are applied in this order:
	// * If DenyIPs is specified, the remote addr must not match any of the
	//   IP addresses in the list.
	// * If AllowIPs is specified, the remote addr must match at least one
	//   of the IP addresses on the list.
	//
	// If an IP address is blocked, the client receives a TLS "unrecognized
	// name" alert, as if it connected to an unknown server name.
	AllowIPs *[]string `yaml:"allowIPs,omitempty"`
	// DenyIPs specifies a list of IP network addresses to deny, in CIDR
	// format, e.g. 192.168.0.0/24. See AllowIPs.
	DenyIPs *[]string `yaml:"denyIPs,omitempty"`
	// SSO indicates that the backend requires user authentication, and
	// specifies which identity provider to use and who's allowed to
	// connect.
	SSO *BackendSSO `yaml:"sso,omitempty"`
	// ExportJWKS is the path where to export the proxy's JSON Web Key Set.
	// This should only be set when SSO is enabled and JSON Web Tokens are
	// generated for the users to authenticate with the backends.
	ExportJWKS string `yaml:"exportJwks,omitempty"`
	// ALPNProtos specifies the list of ALPN procotols supported by this
	// backend. The ACME acme-tls/1 protocol doesn't need to be specified.
	// The default values are: h2, http/1.1
	// Set the value to an empty slice to disable ALPN.
	// The negotiated protocol is forwarded to the backends that use TLS.
	// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
	ALPNProtos *[]string `yaml:"alpnProtos,omitempty"`
	// Mode controls how the proxy communicates with the backend.
	// - PLAINTEXT: Use a plaintext, non-encrypted, TCP connection. This is
	//     the default mode.
	//        CLIENT --TLS--> PROXY ----> BACKEND SERVER
	// - TLS: Open a new TLS connection. Set ForwardServerName, ForwardRootCAs,
	//     and/or InsecureSkipVerify to verify the identity of the server.
	//        CLIENT --TLS--> PROXY --TLS--> BACKEND SERVER
	// - TLSPASSTHROUGH: Forward the whole TLS connection to the backend.
	//     In this mode, the proxy terminates the TCP connection, but not
	//     the TLS connection. The proxy uses the information from the TLS
	//     ClientHello message to route the TLS data to the right backend.
	//     It cannot see the plaintext data, and it cannot enforce client
	//     authentication & authorization.
	//                +-TCP-PROXY-TCP-+
	//        CLIENT -+------TLS------+-> BACKEND SERVER
	// - HTTP: Parses the incoming connection as HTTPS and forwards the
	//     requests to the backends as HTTP requests. Only HTTP/1 is
	//     supported.
	//        CLIENT --HTTPS--> PROXY --HTTP--> BACKEND SERVER
	// - HTTPS: Parses the incoming connection as HTTPS and forwards the
	//     requests to the backends as HTTPS requests. Only HTTP/1 is
	//     supported.
	//        CLIENT --HTTPS--> PROXY --HTTPS--> BACKEND SERVER
	// - CONSOLE: Indicates that this backend is handled by the proxy itself
	//     to report its status and metrics. It is strongly recommended
	//     to use it with ClientAuth and ACL. Otherwise, information from
	//     the proxy's configuration can be leaked to anyone who knows the
	//     backend's server name.
	//        CLIENT --TLS--> PROXY CONSOLE
	Mode string `yaml:"mode"`
	// AddClientCertHeader indicates which fields of the HTTP
	// X-Forwarded-Client-Cert header should be added to the request when
	// Mode is HTTP or HTTPS.
	AddClientCertHeader []string `yaml:"addClientCertHeader,omitempty"`
	// Addresses is a list of server addresses where requests are forwarded.
	// When more than one address are specified, requests are distributed
	// using a simple round robin.
	Addresses []string `yaml:"addresses,omitempty"`
	// InsecureSkipVerify disabled the verification of the backend server's
	// TLS certificate. See https://pkg.go.dev/crypto/tls#Config
	InsecureSkipVerify bool `yaml:"insecureSkipVerify,omitempty"`
	// ForwardRateLimit specifies how fast requests can be forwarded to the
	// backend servers. The default value is 5 requests per second.
	ForwardRateLimit int `yaml:"forwardRateLimit"`
	// ForwardServerName is the ServerName to send in the TLS handshake with
	// the backend server. It is also used to verify the server's identify.
	// This is particularly useful when the addresses use IP addresses
	// instead of hostnames.
	ForwardServerName string `yaml:"forwardServerName,omitempty"`
	// ForwardRootCAs is either a file name or a set of PEM-encoded CA
	// certificates that are used to authenticate backend servers.
	ForwardRootCAs string `yaml:"forwardRootCAs,omitempty"`
	// ForwardTimeout is the connection timeout to backend servers. If
	// Addresses contains multiple addresses, this timeout indicates how
	// long to wait before trying the next address in the list. The default
	// value is 30 seconds.
	ForwardTimeout time.Duration `yaml:"forwardTimeout"`

	// ServerCloseEndsConnection indicates that the proxy will close the
	// whole TCP connection when the server closes its end of it. The
	// default value is true.
	ServerCloseEndsConnection *bool `yaml:"serverCloseEndsConnection,omitempty"`
	// ClientCloseEndsConnection indicates that the proxy will close the
	// whole TCP connection when the client closes its end of it. The
	// default value is false.
	ClientCloseEndsConnection *bool `yaml:"clientCloseEndsConnection,omitempty"`
	// HalfCloseTimeout is the amount of time to keep the TCP connection
	// open when one stream is closed. The default value is 1 minute.
	HalfCloseTimeout *time.Duration `yaml:"halfCloseTimeout,omitempty"`
	// contains filtered or unexported fields
}

Backend encapsulates the data of one backend.

type BackendSSO added in v0.0.24

type BackendSSO struct {
	// Provider is the the name of an identity provider defined in
	// Config.OIDCProviders.
	Provider string `yaml:"provider"`
	// ACL restricts which user identity can access this backend. It is a
	// list of email addresses and/or domains, e.g. "bob@example.com", or
	// "@example.com"
	// If ACL is nil, all identities are allowed. If ACL is an empty list,
	// nobody is allowed.
	ACL *[]string `yaml:"acl,omitempty"`
	// Paths lists the path prefixes for which this policy will be enforced.
	// If Paths is empty, the policy applies to all paths.
	Paths []string `yaml:"paths,omitempty"`
	// GenerateIDTokens indicates that the proxy should generate ID tokens
	// for authenticated users.
	GenerateIDTokens bool `yaml:"generateIdTokens,omitempty"`
	// contains filtered or unexported fields
}

BackendSSO specifies the identity parameters to use for a backend.

type ClientAuth added in v0.0.24

type ClientAuth struct {
	// ACL optionally specifies which client identities are allowed to use
	// this service. A nil value disabled the authorization check and allows
	// any valid client certificate. Otherwise, the value is a slice of
	// Subject strings from the client X509 certificate.
	ACL *[]string `yaml:"acl,omitempty"`
	// RootCAs is either a file name or a set of PEM-encoded CA
	// certificates that are used to authenticate clients.
	RootCAs string `yaml:"rootCAs,omitempty"`
}

ClientAuth specifies how to authenticate and authorize the TLS client's identity.

type Config

type Config struct {
	// Definitions is a section where yaml anchors can be defined. It is
	// otherwise ignored by the proxy.
	Definitions any `yaml:"definitions,omitempty"`

	// HTTPAddr must be reachable from the internet via port 80 for the
	// letsencrypt ACME http-01 challenge to work. If the httpAddr is empty,
	// the proxy will only use tls-alpn-01 and tlsAddr must be reachable on
	// port 443.
	// See https://letsencrypt.org/docs/challenge-types/
	HTTPAddr string `yaml:"httpAddr,omitempty"`
	// TLSAddr is the address where the proxy will receive TLS connections
	// and forward them to the backends.
	TLSAddr string `yaml:"tlsAddr"`
	// CacheDir is the directory where the proxy stores TLS certificates.
	CacheDir string `yaml:"cacheDir,omitempty"`
	// DefaultServerName is the server name to use when the TLS client
	// doesn't use the Server Name Indication (SNI) extension.
	DefaultServerName string `yaml:"defaultServerName,omitempty"`
	// Backends is the list of service backends.
	Backends []*Backend `yaml:"backends"`
	// OIDCProviders is the list of OIDC providers.
	OIDCProviders []*ConfigOIDC `yaml:"oidc,omitempty"`
	// SAMLProviders is the list of SAML providers.
	SAMLProviders []*ConfigSAML `yaml:"saml,omitempty"`
	// Email is optionally included in the requests to letsencrypt.
	Email string `yaml:"email,omitempty"`
	// MaxOpen is the maximum number of open incoming connections.
	MaxOpen int `yaml:"maxOpen,omitempty"`
	// AcceptTOS indicates acceptance of the Let's Encrypt Terms of Service.
	AcceptTOS bool `yaml:"acceptTOS"`
}

Config is the TLS proxy configuration.

func ReadConfig

func ReadConfig(filename string) (*Config, error)

ReadConfig reads and validates a YAML config file.

func (*Config) Check

func (cfg *Config) Check() error

Check checks that the Config is valid, sets some default values, and initializes internal data structures.

type ConfigOIDC added in v0.0.24

type ConfigOIDC struct {
	// Name is the name of the provider. It is used internally only.
	Name string `yaml:"name"`
	// DiscoveryURL is the discovery URL of the OIDC provider. If set, it
	// is used to discover the values of AuthEndpoint and TokenEndpoint.
	DiscoveryURL string `yaml:"discoveryUrl,omitempty"`
	// AuthEndpoint is the authorization endpoint. It must be set only if
	// DiscoveryURL is not set.
	AuthEndpoint string `yaml:"authorizationEndpoint,omitempty"`
	// Scopes is the list of scopes to request. The default list ("openid",
	// "email") returns only the user's email address.
	// To get the user's name and picture, add the "profile" scope with
	// google, or the "public_profile" scope with facebook, i.e.
	// {"openid", "email", "profile"} or {"openid", "email",
	// "public_profile"}.
	Scopes []string `yaml:"scopes,omitempty"`
	// TokenEndpoint is the token endpoint. It must be set only if
	// DiscoveryURL is not set.
	TokenEndpoint string `yaml:"tokenEndpoint,omitempty"`
	// RedirectURL is the OAUTH2 redirect URL. It must be managed by the
	// proxy.
	RedirectURL string `yaml:"redirectUrl"`
	// ClientID is the Client ID.
	ClientID string `yaml:"clientId"`
	// ClientSecret is the Client Secret.
	ClientSecret string `yaml:"clientSecret"`
	// Domain, if set, determine the domain where the user identities will
	// be valid.
	Domain string `yaml:"domain,omitempty"`
}

ConfigOIDC contains the parameters of an OIDC provider.

type ConfigSAML added in v0.0.24

type ConfigSAML struct {
	Name     string `yaml:"name"`
	SSOURL   string `yaml:"ssoUrl"`
	EntityID string `yaml:"entityId"`
	Certs    string `yaml:"certs"`
	ACSURL   string `yaml:"acsUrl"`
	// Domain, if set, determine the domain where the user identities will
	// be valid.
	Domain string `yaml:"domain,omitempty"`
}

ConfigSAML contains the parameters of a SAML identity provider.

type Proxy

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

Proxy receives TLS connections and forwards them to the configured backends.

func New

func New(cfg *Config, passphrase []byte) (*Proxy, error)

New returns a new initialized Proxy.

func NewTestProxy

func NewTestProxy(cfg *Config) (*Proxy, error)

NewTestProxy returns a test Proxy that uses an internal certificate manager instead of letsencrypt.

func (*Proxy) Reconfigure

func (p *Proxy) Reconfigure(cfg *Config) error

Reconfigure updates the proxy's configuration. Some parameters cannot be changed after Start has been called, e.g. HTTPAddr, TLSAddr, CacheDir.

func (*Proxy) Shutdown added in v0.0.19

func (p *Proxy) Shutdown(ctx context.Context)

Shutdown gracefully shuts down the proxy, waiting for all existing connections to close or ctx to be canceled.

func (*Proxy) Start

func (p *Proxy) Start(ctx context.Context) error

Start starts a TLS proxy with the given configuration. The proxy runs in background until the context is canceled.

func (*Proxy) Stop

func (p *Proxy) Stop()

Stop closes all connections and stops all goroutines.

Directories

Path Synopsis
internal
netw
Package netw is a wrapper around network connections that stores annotations and records metrics.
Package netw is a wrapper around network connections that stores annotations and records metrics.
tokenmanager
Package tokenmanager implements a simple JSON Web Token (JWT) and JSON Web Key (JWK) management system.
Package tokenmanager implements a simple JSON Web Token (JWT) and JSON Web Key (JWK) management system.

Jump to

Keyboard shortcuts

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