atunnel

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 32 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"
	// OriginalHostHeader carries the actor authority across router dataplanes
	// that must use :authority to select the worker as their dynamic backend.
	// atunnel only accepts mTLS-authenticated router clients, and the router's
	// ext_proc server overwrites this header before every request.
	OriginalHostHeader = "X-Ate-Original-Host"

	// 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 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 destination preserved by a Linux REDIRECT rule. Actor networking is currently IPv4-only. TODO(liorlieberman) add the IPv6 IP6T_SO_ORIGINAL_DST variant when actor veth setup gains dual-stack support.

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) Mint

Mint 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
	// ExpectedActorUID prevents a mint started for an old activation from
	// receiving the newly assigned actor's certificate.
	ExpectedActorUID 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) DialContext

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

DialContext opens a CONNECT tunnel to destination. destination becomes the request authority, so it must include an explicit port.

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(dialer egressDialer, certificateSource actorCertificateSource, expiresAt time.Time) error

Activate allows egress with a previously obtained actor certificate and renews it until deactivation.

func (*Egress) Deactivate

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

Deactivate rejects new egress, closes active streams, and waits for their forwarding goroutines to exit.

func (*Egress) Serve

func (e *Egress) Serve(ctx context.Context, listener net.Listener) error

Serve accepts intercepted actor connections until ctx is canceled or the listener fails.

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 activation-aware HTTPS reverse proxy. It is long-lived across actor activations, but only routes requests for the actor currently assigned to its worker.

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 string) error

Activate allows requests for actorName in atespace. There can be only one active actor per worker.

func (*Server) Deactivate

func (s *Server) Deactivate(ctx context.Context) error

Deactivate rejects new requests, cancels requests for the active actor, and waits for their handlers to exit before returning.

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.

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 hostname on every request before proxying it.

Jump to

Keyboard shortcuts

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