Documentation
¶
Overview ¶
Package hostagent is the forwarding agent that stands on each app host of a multi-host Docker install where Pando's own container stands on one host (O-45, design 06 §4, notes-multi-host-docker-issue-72.md).
The agent decides nothing. Pando's proxy authenticates the request, authorizes it, mints the assertion and strips every X-Pando-* header and pando_* cookie (R-023, R-053, R-173) before it opens a connection here. The agent's two checks are the ones that keep it from being a way around that: a connection must present Pando's client certificate, and it is carried only to a container on one of the Pando-managed app networks the agent was joined to on its own host.
This package is shared by the agent (cmd/pando host-agent) and the runtime adapter that dials it. It imports nothing from core.
Index ¶
- Constants
- func ClientTLS(as Authorities, client tls.Certificate, host string) *tls.Config
- func Dial(ctx context.Context, addr string, tlsConfig *tls.Config, name string, port int) (net.Conn, error)
- func NewAuthority() ([]byte, error)
- func Permitted(addr netip.Addr, pool netip.Prefix, own []netip.Prefix) error
- func ServerName(host string) string
- func ServerTLS(certPEM, keyPEM, authoritiesPEM []byte) (*tls.Config, error)
- func SystemInterfaces() ([]netip.Prefix, error)
- type Agent
- type Authorities
- type Authority
Constants ¶
const ClientCommonName = "pando-proxy"
ClientCommonName is the subject every certificate Pando's proxy presents to an agent carries. An agent refuses any other, so a certificate the same authority issued to an agent (a server certificate) cannot be used to open a connection through another agent.
const DefaultPort = 7443
DefaultPort is where an agent listens, and the one port an app host publishes (R-026 concerns app workloads; this port reaches none without Pando's certificate).
Variables ¶
This section is empty.
Functions ¶
func ClientTLS ¶
func ClientTLS(as Authorities, client tls.Certificate, host string) *tls.Config
ClientTLS is the dialer's TLS configuration: Pando's client certificate, and the agent's verified against the authorities and the host's name.
func Dial ¶
func Dial(ctx context.Context, addr string, tlsConfig *tls.Config, name string, port int) (net.Conn, error)
Dial opens a connection through the agent at addr to the container name on port, as the client tlsConfig (ClientTLS) authenticates. The connection it returns is a stream to the workload.
func NewAuthority ¶
NewAuthority generates an authority and returns it as PEM: the certificate followed by its private key. That text is what the adapter's agent_ca credential holds, sealed like every adapter credential (R-190).
func Permitted ¶
Permitted reports whether the agent may forward to addr.
Only to a container on an app network on this host: addr must be inside the app network range, and on a network the agent itself is joined to — which on a multi-host install the adapter does for app networks and nothing else. Within such a network, never to the network's first address (Docker gives it to the bridge, which is the host itself), its network or broadcast address, or the agent's own address.
func ServerName ¶
ServerName is the name an agent's certificate is issued for, and what the dialer verifies, for the host named host in the adapter's configuration.
func ServerTLS ¶
ServerTLS is the agent's TLS configuration: its own certificate, and a client certificate required, issued by one of the authorities, for client authentication, and naming Pando's proxy.
func SystemInterfaces ¶
SystemInterfaces is every IPv4 address of this process's network interfaces, with its prefix.
Types ¶
type Agent ¶
type Agent struct {
// TLS must require and verify Pando's client certificate (ServerTLS).
TLS *tls.Config
// Pool is the range the app networks on this host take their addresses
// from: the Docker adapter's network_pool. A target outside it is
// refused, which is what keeps the agent off the network it is published
// on and off anything else on the host.
Pool netip.Prefix
// Resolve looks a container name up. Nil is the system resolver, which in
// a container on user-defined networks is Docker's.
Resolve func(ctx context.Context, name string) ([]netip.Addr, error)
// Interfaces are the agent's own addresses with their prefix lengths: the
// networks it is joined to. Nil reads them from the system each time.
Interfaces func() ([]netip.Prefix, error)
// Dial connects to the permitted address. Nil is a TCP dial.
Dial func(ctx context.Context, addr string) (net.Conn, error)
Logger *zap.Logger
}
Agent accepts Pando's proxy and carries each connection to one workload.
type Authorities ¶
type Authorities []Authority
Authorities is the configured set, newest first. The first issues; every one is trusted, which is how the authority is replaced without a moment in which an agent and the proxy disagree: add the new one first, wait for the agents to be re-created, then remove the old one.
func ParseAuthorities ¶
func ParseAuthorities(data []byte) (Authorities, error)
ParseAuthorities reads one or more authorities from PEM, each a certificate followed by its key.
func (Authorities) Fingerprint ¶
func (as Authorities) Fingerprint() string
Fingerprint names the set, so an agent issued under a different one is known to need re-creating.
func (Authorities) IssueClient ¶
func (as Authorities) IssueClient() (tls.Certificate, error)
IssueClient issues the certificate Pando's proxy presents to agents. Held in memory only: every replica issues its own from the authority at start.
func (Authorities) IssueServer ¶
func (as Authorities) IssueServer(host string) (certPEM, keyPEM []byte, err error)
IssueServer issues an agent's certificate for the host named host, as PEM. Server authentication only: it cannot be presented to another agent as Pando's.
func (Authorities) Pool ¶
func (as Authorities) Pool() *x509.CertPool
Pool is every authority's certificate, for verifying either side.
func (Authorities) PoolPEM ¶
func (as Authorities) PoolPEM() []byte
PoolPEM is Pool as PEM, which is what an agent is given: certificates only, never a key.