proxy

package
v0.0.21 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2023 License: MIT Imports: 34 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 indicates whether TLS client authentication is required
	// for this service.
	ClientAuth bool `yaml:"clientAuth,omitempty"`
	// ClientACL 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.
	ClientACL *[]string `yaml:"clientACL,omitempty"`
	// ClientCAs is either a file name or a set of PEM-encoded CA
	// certificates that are used to authenticate clients.
	ClientCAs string `yaml:"clientCAs,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"`
	// 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 ClientACL. 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 that the HTTP Client-Cert header should
	// be added to the request when Mode is HTTP or HTTPS.
	AddClientCertHeader bool `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 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"`
	// 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"`
}

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 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.

Jump to

Keyboard shortcuts

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