atunnel

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Overview

Package atunnel carries actor ingress and egress through an ateom worker pod.

Index

Constants

View Source
const (
	// DefaultConnectPort is the worker port on which atunnel accepts inbound
	// mTLS CONNECT tunnels from the ingress router.
	DefaultConnectPort = 8443

	// StaleAssignmentHeader distinguishes an atunnel routing rejection from a
	// 421 returned by the actor application itself.
	StaleAssignmentHeader = "X-Ate-Assignment-Stale"
	// TargetPortHeader carries the port to reach on the actor: the CONNECT
	// :authority's port for arbitrary-port ingress, or the default 80
	// otherwise (see atenet-router's HandleRequestHeaders). cfg.Upstream is
	// fixed for the Server's lifetime, so this lets the port vary per
	// request; stripped before the request reaches the actor.
	TargetPortHeader = "X-Ate-Target-Port"
)

Variables

View Source
var ErrGatewayHandshake = errors.New("atunnel: egress gateway TLS handshake")

ErrGatewayHandshake reports that the gateway's front door refused the connection at TLS: it rejected the client certificate, or its own certificate did not verify.

Functions

func EgressPort added in v0.2.0

func EgressPort(listenAddress string) (uint16, error)

EgressPort is the port from a listen address, which each sandbox's redirect aims at. The address itself is never bound: egress is served from inside the sandbox namespaces.

func ParsePort

func ParsePort(s string) (port int, ok bool)

ParsePort parses s as a TCP port number, returning ok=false for anything outside the valid 1-65535 range (including non-numeric input).

func TCPOriginalDestination

func TCPOriginalDestination(conn net.Conn) (string, error)

TCPOriginalDestination reads the IPv4 or IPv6 destination preserved by a Linux REDIRECT rule.

Types

type BrokerCertificateSource

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

BrokerCertificateSource owns atunnel's actor private key and obtains the matching short-lived certificate from the node-local atelet.

func NewBrokerCertificateSource

func NewBrokerCertificateSource(cfg BrokerConfig) (*BrokerCertificateSource, error)

NewBrokerCertificateSource creates one actor key for this activation. The key is reused across renewals and never leaves atunnel; only its CSR crosses the credential broker socket.

func (*BrokerCertificateSource) GetClientCertificate

GetClientCertificate supplies the current actor certificate to the egress gateway TLS handshake and refuses to use it after expiry.

func (*BrokerCertificateSource) MintAteomCertificate added in v0.2.0

func (s *BrokerCertificateSource) MintAteomCertificate(ctx context.Context) (time.Time, error)

MintAteomCertificate requests and installs a fresh certificate for the source's existing actor key. It returns the new expiry for renewal scheduling.

type BrokerConfig

type BrokerConfig struct {
	// SocketPath is the atelet-owned Unix socket shared with this worker.
	SocketPath string
	// CredentialBundlePath is the worker Pod certificate and private key used
	// only to authenticate atunnel to atelet.
	CredentialBundlePath string
	// TrustBundlePath verifies atelet's Pod certificate.
	TrustBundlePath string

	// Which actor are we currently running?
	ActorAtespace string
	ActorName     string
	ActorUID      string

	// AteletSPIFFEID is the identity the node-local atelet must present on the
	// credential broker connection. It names atelet's namespace, not this
	// worker's, so it is configured rather than derived from the downward API.
	AteletSPIFFEID string
}

BrokerConfig configures the node-local atelet credential broker client.

type Client

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

Client opens actor egress streams through an mTLS-authenticated gateway.

func NewClient

func NewClient(cfg ClientConfig, opts ...ClientOption) (*Client, error)

NewClient creates an egress CONNECT client and validates its TLS material.

func (*Client) Close added in v0.5.0

func (c *Client) Close() error

Close any pooled HTTP/2 connections to the egress gateway and cancels any in-flight connection dial.

func (*Client) DialContext

func (c *Client) DialContext(ctx context.Context, destination string) (net.Conn, error)

Open a CONNECT tunnel to destination. destination becomes the request authority, so it must include an explicit port. TODO(yanavlasov): update .md file with the description of this machinery. TODO(yanavlasov): consider simplifying this code by dropping support for H/1.

type ClientConfig

type ClientConfig struct {
	GatewayAddress       string
	ServerName           string
	GetClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
	TrustBundlePath      string
}

TODO(liorlieberman): support/use CONNECT on Ingress as well. ClientConfig configures an egress CONNECT client.

type ClientOption

type ClientOption func(*Client)

ClientOption customizes a Client beyond its configuration. Production callers need none of these.

func WithDialer

func WithDialer(dial DialFunc) ClientOption

WithDialer overrides how the client reaches the egress gateway. It exists so tests can substitute a transport; by default a net.Dialer is used.

type Config

type Config struct {
	CredentialBundlePath string
	TrustBundlePath      string
	AllowedClientID      string
	Upstream             *url.URL
}

Config configures an ingress Server.

type ConnectRejectedError

type ConnectRejectedError struct {
	StatusCode int
	// Status is the full status line, e.g. "403 Forbidden".
	Status string
	// Message is the response body, or the status text when the body is empty.
	Message string
}

ConnectRejectedError reports a CONNECT the gateway answered with a non-2xx status. The caller authenticated successfully and the request was declined anyway, which is what an authorization denial looks like from here. The status code is carried separately from the message because it is the part a caller can act on.

func (*ConnectRejectedError) Error

func (e *ConnectRejectedError) Error() string

type DialFunc

type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)

DialFunc dials a network address. It matches net.Dialer.DialContext.

type Egress

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

Egress proxies actor TCP connections through an egress CONNECT dialer. It is long-lived across actor activations, but only carries traffic while an actor is assigned to its worker.

func NewEgress

func NewEgress(originalDestination OriginalDestination) (*Egress, error)

NewEgress creates an activation-aware egress proxy.

func (*Egress) Activate

func (e *Egress) Activate(actorUID string, dialer egressDialer, certificateSource actorCertificateSource, expiresAt time.Time) error

Activate enables the actor's egress and certificate renewal until deactivation.

func (*Egress) Bind added in v0.2.0

func (e *Egress) Bind(actorUID string) (func(context.Context, net.Listener) error, error)

Bind captures the actor's activation before its listeners start serving.

func (*Egress) Deactivate

func (e *Egress) Deactivate(ctx context.Context, actorUID string) error

Deactivate disables the actor's egress and closes and drains its streams.

type OriginalDestination

type OriginalDestination func(net.Conn) (string, error)

OriginalDestination returns the address that a transparently intercepted connection originally targeted.

type Server

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

Server is an HTTPS reverse proxy for the worker's active actors.

func NewServer

func NewServer(cfg Config) (*Server, error)

NewServer creates a Server and validates its TLS material.

func (*Server) Activate

func (s *Server) Activate(atespace, actorName, actorUID string, dial DialFunc) error

Activate routes requests for the actor through its namespace-specific dialer. Requests are routed by name, so an older incarnation still active under the same name is replaced.

func (*Server) Deactivate

func (s *Server) Deactivate(ctx context.Context, atespace, actorName, actorUID string) error

Deactivate rejects new requests for the actor and cancels and drains its handlers. It leaves a newer incarnation under the same name alone.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, lis net.Listener) error

Serve serves HTTPS on lis until ctx is canceled or the server fails.

func (*Server) ServeConnect

func (s *Server) ServeConnect(ctx context.Context, lis net.Listener) error

ServeConnect serves the mTLS CONNECT endpoint. CONNECT is deliberately on a separate listener so ordinary actor ingress remains a request proxy, while the router can use this listener for a bidirectional tunnel. The router's actor cluster mirrors the downstream protocol, so either can arrive here. The tunnel itself relays opaque bytes, so protocolMirrorTransport's gRPC-only gate does not apply to CONNECT traffic — and that is the point: this listener is the basis of the planned tunnel-based ingress, where ordinary actor traffic arrives here as a spliced tunnel and all protocol decisions move to the router's route config, leaving atunnel with no request parsing at all.

func (*Server) ServeConnectHTTP

func (s *Server) ServeConnectHTTP(w http.ResponseWriter, r *http.Request)

ServeConnectHTTP accepts a router-authenticated CONNECT request and relays its tunnel to the named port on the currently active actor.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP validates the actor routing header on every request before proxying it.

Jump to

Keyboard shortcuts

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