Documentation
¶
Index ¶
- Constants
- Variables
- func AfterCountIpBlock(ip netip.Addr, size uint, count uint) netip.Addr
- func GetClientKey(ifname string) (key wgtypes.Key, err error)
- func GetClientToken() (string, error)
- func GetOIDCAllowedWorkspaceIDs() []string
- func GetOIDCAudience() string
- func GetOIDCIssuerURL() string
- func GetOIDCToken() (string, error)
- func GetServerKey() (key wgtypes.Key, err error)
- func GetVproxPassword() (string, error)
- func IsRecoverableError(err error) bool
- func MetricsGauge(name string, value float64, tags ...string)
- func MetricsIncr(name string, tags ...string)
- func MetricsTiming(name string, d time.Duration, tags ...string)
- func StartMetricsServer()
- type AuthMode
- type Authenticator
- type AwsInterface
- type AwsMetadata
- type Client
- type ConnectionError
- type IpAllocator
- type JWKSCache
- type ModalClaims
- type OIDCConfig
- type PeerInfo
- type Server
- type ServerInfo
- type ServerManager
Constants ¶
const FirstHandshakeTimeout = 10 * time.Second
A new peer must connect with a handshake within this time.
const FwmarkBase = 0x54437D00
FwmarkBase is the base value for firewall marks used by vprox.
const PeerIdleTimeout = 5 * time.Minute
If no handshakes are received in this time, the peer is considered idle and removed from the server's WireGuard interface list.
Note that this must be at least 2-3 minutes, since WireGuard sends handshakes interleaved with a data message only when 2-3 minutes have passed since the last successful handshake. This is regardless of the persistent-keepalive setting.
const RunDir string = "/run/vprox"
RunDir is the path for runtime data that should be kept across restarts.
const WireguardListenPortBase = 50227
UDP listen port base value for WireGuard connections.
Variables ¶
var ( GitCommit = "unknown" GitTag = "unknown" )
Version information - set via ldflags at build time. Example: go build -ldflags "-X github.com/modal-labs/vprox/lib.GitCommit=abc123 -X github.com/modal-labs/vprox/lib.GitTag=v1.0.0"
Functions ¶
func AfterCountIpBlock ¶
AfterCountIpBlock returns the result of incrementing an IP address by N CIDR counts.
func GetClientToken ¶ added in v1.0.10
GetClientToken returns the bearer token the client should send to the server, based on the current auth mode.
func GetOIDCAllowedWorkspaceIDs ¶ added in v1.0.10
func GetOIDCAllowedWorkspaceIDs() []string
GetOIDCAllowedWorkspaceIDs returns the list of allowed Modal workspace IDs from the VPROX_OIDC_ALLOWED_WORKSPACE_IDS environment variable (comma-separated). If empty, any workspace is allowed. If set to "*", all workspaces are explicitly allowed (returns nil) with a warning logged at startup.
func GetOIDCAudience ¶ added in v1.0.10
func GetOIDCAudience() string
GetOIDCAudience returns the expected OIDC audience from the VPROX_OIDC_AUDIENCE environment variable. If empty, audience is not checked.
func GetOIDCIssuerURL ¶ added in v1.0.10
func GetOIDCIssuerURL() string
GetOIDCIssuerURL returns the OIDC issuer URL from the VPROX_OIDC_ISSUER environment variable. Defaults to "https://oidc.modal.com" if not set. Useful for testing Modal OIDC endpoints other than default.
func GetOIDCToken ¶ added in v1.0.10
GetOIDCToken returns the OIDC identity token from the VPROX_OIDC_TOKEN environment variable.
func GetServerKey ¶
func GetVproxPassword ¶
func IsRecoverableError ¶ added in v1.0.8
IsRecoverableError returns false if the error is a ConnectionError that is not recoverable.
func MetricsGauge ¶ added in v1.0.10
func MetricsIncr ¶ added in v1.0.10
func MetricsTiming ¶ added in v1.0.10
MetricsTiming records a latency observation in milliseconds.
func StartMetricsServer ¶ added in v1.0.10
func StartMetricsServer()
StartMetricsServer starts an HTTP server on :9090 serving Prometheus metrics. CPU and network bandwidth metrics are expected from the host-level Vector/DD agent.
Types ¶
type AuthMode ¶ added in v1.0.10
type AuthMode string
AuthMode determines how the server authenticates incoming requests.
func GetAuthMode ¶ added in v1.0.10
func GetAuthMode() AuthMode
GetAuthMode returns the configured auth mode from the VPROX_AUTH_MODE environment variable. Defaults to "password" if not set.
type Authenticator ¶ added in v1.0.10
type Authenticator struct {
// contains filtered or unexported fields
}
Authenticator provides request authentication for the vprox server.
func GetAuthenticator ¶ added in v1.0.10
func GetAuthenticator() (*Authenticator, error)
GetAuthenticator creates the appropriate Authenticator based on environment configuration. This is used by the server.
func NewOIDCModalAuthenticator ¶ added in v1.0.10
func NewOIDCModalAuthenticator(config *OIDCConfig) (*Authenticator, error)
NewOIDCModalAuthenticator creates an Authenticator that validates Modal OIDC tokens.
func NewPasswordAuthenticator ¶ added in v1.0.10
func NewPasswordAuthenticator(password string) *Authenticator
NewPasswordAuthenticator creates an Authenticator that uses password-based auth.
func (*Authenticator) Authenticate ¶ added in v1.0.10
func (a *Authenticator) Authenticate(r *http.Request) error
Authenticate checks the Authorization header of an HTTP request. Returns nil on success, or an error describing the failure.
func (*Authenticator) Mode ¶ added in v1.0.10
func (a *Authenticator) Mode() AuthMode
Mode returns the authentication mode.
type AwsInterface ¶
type AwsInterface struct {
MacAddress string
InterfaceId string // eni-[XXXXXXXXXX]
PrivateIps []string
}
AwsInterface contains information about a network interface.
type AwsMetadata ¶
type AwsMetadata struct {
// contains filtered or unexported fields
}
AwsMetadata is a client for the AWS instance metadata service.
func NewAwsMetadata ¶
func NewAwsMetadata() *AwsMetadata
NewAwsMetadata creates a new AWS metadata client.
func (*AwsMetadata) GetAddresses ¶
func (am *AwsMetadata) GetAddresses() ([]AwsInterface, error)
GetAddresses returns the info about the instance's network interfaces.
type Client ¶
type Client struct {
// Key is the private key of the client.
Key wgtypes.Key
// Ifname is the name of the client WireGuard interface.
Ifname string
// ServerIp is the public IPv4 address of the server.
ServerIp netip.Addr
// Token is the bearer token used to authenticate with the server.
// In password mode, this is the VPROX_PASSWORD value.
// In oidc-modal mode, this is the VPROX_OIDC_TOKEN value.
Token string
// WgClient is a shared client for interacting with the WireGuard kernel module.
WgClient *wgctrl.Client
// Http is used to make connect requests to the server.
Http *http.Client
// contains filtered or unexported fields
}
Client manages a peering connection with with a local WireGuard interface.
func (*Client) CheckConnection ¶
CheckConnection checks the status of the connection with the wireguard peer, and returns true if it is healthy. This sends 3 pings in succession, and blocks until they receive a response or the timeout passes.
func (*Client) Connect ¶
Connect attempts to reconnect to the peer. A network interface needs to have already been created with CreateInterface() before calling Connect()
func (*Client) CreateInterface ¶
CreateInterface creates a new interface for wireguard. DeleteInterface() needs to be called to clean this up.
func (*Client) DeleteInterface ¶
func (c *Client) DeleteInterface()
func (*Client) Disconnect ¶ added in v1.0.5
Disconnect notifies the server that this client is disconnecting, allowing the server to immediately reclaim resources (wireguard peer and subnet IP) instead of waiting for the idle timeout.
type ConnectionError ¶ added in v1.0.8
Used to determine if we can recover from an error during connection setup.
func (*ConnectionError) Error ¶ added in v1.0.8
func (e *ConnectionError) Error() string
type IpAllocator ¶
type IpAllocator struct {
// contains filtered or unexported fields
}
IpAllocator is a simple IP address allocator that produces IP addresses within a prefix, in increasing order of available IPs.
All operations on an IpAllocator are thread-safe.
func NewIpAllocator ¶
func NewIpAllocator(prefix netip.Prefix) *IpAllocator
NewIpAllocator creates a new IpAllocator for the given prefix.
The prefix is masked out to normalize its address at the beginning of the IP range. It must be valid.
func (*IpAllocator) Allocate ¶
func (ipa *IpAllocator) Allocate() netip.Addr
Allocate returns the next available IP address in the prefix.
This never uses the initial address (the "zero address") of the prefix. For example, for the prefix `192.168.0.0/24`, the first IP address allocated will be `192.168.0.1`.
If there are no more available IP addresses, this returns the zero address.
func (*IpAllocator) AllocatedCount ¶ added in v1.0.10
func (ipa *IpAllocator) AllocatedCount() int
AllocatedCount returns the number of currently allocated IP addresses.
func (*IpAllocator) Free ¶
func (ipa *IpAllocator) Free(addr netip.Addr) bool
Free marks the given IP address as available for allocation.
func (*IpAllocator) MarkAllocated ¶ added in v1.0.9
func (ipa *IpAllocator) MarkAllocated(addr netip.Addr)
MarkAllocated marks the given IP as allocated without going through the normal allocation sequence. Used for takeover mode to mark IPs that are already in use by existing WireGuard peers.
type JWKSCache ¶ added in v1.0.10
type JWKSCache struct {
// contains filtered or unexported fields
}
JWKSCache fetches and caches JWKS keys from a remote endpoint.
func NewJWKSCache ¶ added in v1.0.10
NewJWKSCache creates a new JWKS cache for the given URL.
type ModalClaims ¶ added in v1.0.10
type ModalClaims struct {
// Standard OIDC claims
Sub string `json:"sub"` // Subject: unique identifier for the user/entity
Aud string `json:"aud"` // Audience: intended recipient of the token (e.g., client ID)
Exp int64 `json:"exp"` // Expiration Time: Unix timestamp after which the token is invalid
Iat int64 `json:"iat"` // Issued At: Unix timestamp when the token was issued
Iss string `json:"iss"` // Issuer: URL of the identity provider that issued the token
Jti string `json:"jti"` // JWT ID: unique identifier for the token (used to prevent replay attacks)
// Modal-specific claims
WorkspaceID string `json:"workspace_id"`
EnvironmentID string `json:"environment_id"`
EnvironmentName string `json:"environment_name"`
AppID string `json:"app_id"`
AppName string `json:"app_name"`
FunctionID string `json:"function_id"`
FunctionName string `json:"function_name"`
ContainerID string `json:"container_id"`
}
ModalClaims represents the claims in a Modal OIDC identity token.
type OIDCConfig ¶ added in v1.0.10
type OIDCConfig struct {
// IssuerURL is the Modal OIDC issuer URL (e.g. "https://oidc.modal.com").
IssuerURL string
// Audience is the expected "aud" claim in the token. If empty, audience is not checked.
Audience string
// AllowedWorkspaceIDs is a list of Modal workspace IDs that are allowed to authenticate.
// If empty, any workspace is allowed (only issuer/signature are checked).
AllowedWorkspaceIDs []string
}
OIDCConfig holds configuration for OIDC-based authentication.
type Server ¶
type Server struct {
// Key is the private key of the server.
Key wgtypes.Key
// BindAddr is the private IPv4 address that the server binds to.
BindAddr netip.Addr
// BindIface is the interface that the address is bound to, and it's also
// the interface for outbound VPN traffic after masquerade.
//
// Currently only setting this to the default interface is supported.
BindIface netlink.Link
// Auth is the authenticator used to verify incoming requests.
Auth *Authenticator
// Index is a unique server index for firewall marks and other uses. It starts at 0.
Index uint16
// Ipt is the iptables client for managing firewall rules.
Ipt *iptables.IPTables
// WgClient is a shared client for interacting with the WireGuard kernel module.
WgClient *wgctrl.Client
// WgCidr is the CIDR block of IPs that the server assigns to WireGuard peers.
WgCidr netip.Prefix
// Ctx is the shutdown context for the server.
Ctx context.Context
// contains filtered or unexported fields
}
Server handles state for one WireGuard network.
The `vprox server` command should create one Server instance for each private IP that the server should bind to.
func (*Server) CleanupIptables ¶
func (srv *Server) CleanupIptables()
func (*Server) CleanupWireguard ¶
func (srv *Server) CleanupWireguard()
func (*Server) ListenForHttps ¶
func (*Server) StartIptables ¶
func (*Server) StartWireguard ¶
type ServerInfo ¶
type ServerInfo struct {
// contains filtered or unexported fields
}
type ServerManager ¶
type ServerManager struct {
// contains filtered or unexported fields
}
ServerManager handles creating and terminating servers on ips ServerManager is not thread safe for concurrent access.
func NewServerManager ¶
func NewServerManager(wgBlock netip.Prefix, wgBlockPerIp uint, ctx context.Context, key wgtypes.Key, auth *Authenticator, takeover bool) (*ServerManager, error)
NewServerManager creates a new server manager
func (*ServerManager) Start ¶
func (sm *ServerManager) Start(ip netip.Addr) error
Start creates a new server on the specified ip.
func (*ServerManager) Stop ¶
func (sm *ServerManager) Stop(ip netip.Addr)
Stop stops the server at the specified ip address
func (*ServerManager) Wait ¶
func (sm *ServerManager) Wait()
Wait blocks until the running servers exit.