Documentation
¶
Index ¶
- Variables
- func Listen(addr string) (net.Listener, error)
- func ListenAndServe(addr string, f func(conn net.Conn)) (net.Listener, error)
- func Load(ctx context.Context, d *Dest, obj interface{}, kind, ns string, name string) error
- type ContextDialer
- type Dest
- type Discoverer
- type HttpProvider
- type Mesh
- func (mesh *Mesh) DialContext(ctx context.Context, network, addr string) (net.Conn, error)
- func (mesh *Mesh) Discover(ctx context.Context, addr string) (*Dest, error)
- func (mesh *Mesh) GetToken(ctx context.Context, aud string) (string, error)
- func (mesh *Mesh) L4HttpTransport(ctx context.Context) *http.Transport
- func (mesh *Mesh) Provision(ctx context.Context) error
- type MeshCfg
- type Module
- type RESTRequest
- type ResourceStore
- type TokenSource
Constants ¶
This section is empty.
Variables ¶
var ( TokenPayload = tokens.TokenPayload DecodeJWT = tokens.DecodeJWT JwtRawParse = tokens.JwtRawParse )
Functions ¶
Types ¶
type ContextDialer ¶
type Dest ¶
type Dest struct {
// Addr is the main (VIP or URL) address of the destination.
//
// For HTTP, Addr is the URL, including any required path prefix, for the destination.
//
// For TCP, Addr is the TCP address - VIP:port or DNS:port format. tcp:// is assumed.
//
// For K8S service it should be in the form serviceName.namespace.svc:svcPort
// The cluster suffix is assumed to be 'cluster.local' or the custom k8s suffix,
// equivalent to cluster.server in kubeconfig.
//
// This can also be an 'original dst' address for individual endpoints.
//
// Individual IPs (real or relay like waypoints or egress GW, etc) will be in
// the info.addrs field.
Addr string `json:"addr,omitempty"`
// Proto determines how to talk with the Dest.
// Could be 'hbone' (compat with Istio), 'h2c', 'h2', 'ssh', etc.
// If not set - Dial will use regular TCP or TLS, depending on the other settings.
Proto string `json:"protocol,omitempty"`
// Name is the 'basename' or alias of the service.
//
Name string `json:"id,omitempty"`
// If empty, the cluster is using system certs or SPIFFE CAs - as configured in
// Mesh.
//
// Otherwise, it's the configured root certs list, in PEM format.
// May include multiple concatenated roots.
//
// TODO: allow root SHA only.
// TODO: move to trust config
CACertPEM string `json:"ca_cert,omitempty"`
// Sources of trust for validating the peer destination.
// Typically, a certificate - if not set, SYSTEM certificates will be used for non-mesh destinations
// and the MESH certificates for destinations using one of the mesh domains.
// If not set, the nodes' trust config is used.
// TrustConfig *tokens.TrustConfig `json:"trust,omitempty"`
// If set, Bearer tokens will be added.
TokenProvider TokenSource `json:-`
// If set, a token source with this name is used. The provider must be set in MeshEnv.AuthProviders
// If not found, no tokens will be added. If found, errors getting tokens will result
// in errors connecting.
// In K8S - it will be the well-known token file.
TokenSource string `json:"tokens,omitempty"`
// If set, the destination is using HTTP protocol - and this is the roundtripper to use.
// HttpClient() returns a http client initialized for this destination.
// For special cases ( reverse connections in h2r ) it will be a *http2.ClientConn.
//
RoundTripper http.RoundTripper `json:-`
InsecureSkipTLSVerify bool `json:"insecure,omitempty"`
Dialer ContextDialer `json:-`
// L4Secure is set if the destination can be reached over a secure L4 network (ambient, VPC, IPSec, secure CNI, etc)
L4Secure bool `json:"l4secure,omitempty"`
Backoff time.Duration `json:"-"`
// contains filtered or unexported fields
}
Dest represents the metadata associated with an address.
It is discovered from multiple sources - local config, control plane, DNS.
This is primarily concerned with the security aspects (auth, transport), and include 'trusted' attributes from K8S configs or JWT/cert.
K8S clusters can be represented as a Dest - rest.Config Host is Addr, CACertPEM, same for all REST or gRPC services. For L7 destinations a HttpClient and RoundTripper are created based on the metadata. This is required because the Transport is associated with the trust configs.
func (*Dest) AddTrustPEM ¶
func (*Dest) BackoffReset ¶
func (d *Dest) BackoffReset()
BackoffReset and Sleep implement the backoff interface
func (*Dest) BackoffSleep ¶
func (d *Dest) BackoffSleep()
func (*Dest) HttpClient ¶
HttpClient returns a http client configured to talk with this Dest using a secure connection. - if CACertPEM is set, will be used instead of system
The client is cached in Dest.
func (*Dest) RestClient ¶
func (d *Dest) RestClient(g, v string) (*RESTRequest, error)
type Discoverer ¶
type Discoverer interface {
// Discover will use configs, DNS, XDS, K8S or other means to find the properties of a destination.
// If none is found, the default is:
// - if addr is a general FQDN, use it as a standard internet destination.
// - if addr is a public IP - use the standard Dialer.
// - if addr has '.internal' or '.local' - use mesh root certificates and HBONE or SSH protocol.
// - for private IP ranges - same
//
// Custom Discover can set egress gateways or adjust.
Discover(ctx context.Context, addr string) (*Dest, error)
}
type HttpProvider ¶
type HttpProvider interface {
// The module must use domain and prefix to register with the mux.
RegisterMux(mux *http.ServeMux)
}
The normal pattern of registering in 'init' or startup is simple but lacks flexibility. It panics on duplicates, can't remove.
Instead the listener and http servers use a handler that allows swapping the Mux, and each module can be re-created with a new Mux.
type Mesh ¶
type Mesh struct {
*MeshCfg
// ResourceStore is used to load configs and data on-demand and unmarshal
// them to the appropriate type.
//
// It acts as a filesystem.
ResourceStore ResourceStore `json:"-"`
// Primary workload ID TLS certificate and private key. Loaded or generated.
// Default is to use EC256 certs. The private key can be used to sign JWTs.
// The public key and sha can be used as a node identity.
Cert *certs.Certs `json:"-"`
// AuthProviders - matching kubeconfig user.authProvider.name
// It is expected to return tokens with the given audience - in case of GCP
// returns access tokens. If not set the cluster can't be created.
//
// A number of pre-defined token sources are used:
// - gcp - returns GCP access tokens using MDS or default credentials. Used for example by GKE clusters.
// - k8s - return K8S WorkloadID tokens with the given audience for default K8S cluster.
// - istio-ca - returns K8S tokens with istio-ca audience - used by Citadel and default Istiod
// - sts - federated google access tokens associated with GCP identity pools.
AuthProviders map[string]TokenSource `json:"-"`
// Default dialer used to connect to host:port extracted from metadata.
// Defaults to net.Dialer, making real connections.
//
// Can be replaced with a mux or egress dialer or router for
// integrations.
NetDialer ContextDialer `json:"-"`
// Mux is used for HTTP and gRPC handler exposed externally.
//
// It is the default handler for "hbone" and "hbonec" protocol handlers.
//
// The HTTP server on localhost:15000 uses http.DefaultServerMux -
// which is also used by pprof and others by default and can't be changed.
// It could also be exposed with 'admin' auth wrapper.
Mux *http.ServeMux `json:"-"`
HandlerWrapper func(hf http.Handler, op string) http.Handler `json:"-"`
RTWrapper func(rt http.RoundTripper) http.RoundTripper `json:"-"`
// contains filtered or unexported fields
}
Mesh represents a workload identity and associated info required for minimal mesh-compatible security. Includes helpers for authentication and basic provisioning.
A workload may be associated with multiple service accounts and identity providers, and may have multiple certificates.
func FromEnv ¶
FromEnv will attempt to identify and Init the certificates. This should be called from main() and for normal app use.
New can be used in tests or for fine control over what cert is loaded.
- default GKE/Istio location for workload identity - /var/run/secrets/...FindC - /etc/istio/certs - $HOME/.ssh/id_ecdsa - if it is in standard pem format
ssh-keygen -t ecdsa -b 256 -m PEM -f id_ecdsa
If a cert is found, the identity is extracted from the cert. The platform is expected to refresh the cert.
If a cert is not found, Cert field will be nil, and the app should use one of the methods of getting a cert or call InitSelfSigned.
func (*Mesh) DialContext ¶
DialContext should connect to the address, using one of the modules and config - falling back to the default dialer.
Normal golang - network is "tcp" and address is host:port - or custom values are allowed.
All forwarding/tunneling methods should call this method to establish outbound connections.
func (*Mesh) GetToken ¶
GetToken is the default token source for the object. Will try: - MDS - AuthProvider["K8S"],"GCP" - locally signed token, using the mesh private key.
TODO: add some audience policy - for example googleapis.com or .mesh.internal.
func (*Mesh) L4HttpTransport ¶
type MeshCfg ¶
type MeshCfg struct {
ConfigLocation string
// AuthnConfig defines the trust config for the node - the list of signers that are trusted for specific
// issuers and domains, audiences, etc.
//
// Based on Istio jwtRules, but generalized to all signer types.
//
// Authz is separated - this only defines who do we trust (and policies on what we trust it for)
//
// Destinations and listeners may have their own AuthnConfig - this is the default.
tokens.AuthnConfig `json:",inline"`
// Trusted roots, in DER format.
// Deprecated - AuthnConfig
RootCertificates [][]byte `json:"roots,omitempty"`
// Domain is extracted from the cert or set by user, used to verify
// peer certificates. If not set, will be populated when cert is loaded.
// Should be a real domain with OIDC keys or platform specific.
// NOT cluster.local
Domain string `json:"domain,omitempty"`
DomainAliases []string `json:"domainAliases,omitempty"`
// Namespace and Name are extracted from the certificate or set by user.
// Namespace is used to verify peer certificates
Namespace string `json:"namespace,omitempty"`
// Name of the service account. Can be an email or spiffee or just the naked name.
Name string `json:"name,omitempty"`
// Deprecated - MDS
ProjectID string `json:"project_id,omitempty"`
GSA string `json:"gsa,omitempty"`
// Authz: Additional namespaces to allow access from. If no authz rule is set, 'same namespace'
// and 'istio-system' are allowed.
AllowedNamespaces []string `json:"allow_namespaces,omitempty"`
// DER public key
PublicKey []byte `json:"pub,omitempty"`
// MeshAddr is a URL or string representing the primary (bootstrap) address
// for the mesh config - can be a K8S cluster, XDS server, file.
MeshAddr string `json:"meshAddr,omitempty"`
// Dst contains pre-configured or discovered properties for destination services.
// When running in K8S, "KUBERNETES" is set with the in-cluster config.
// A .kube/config file can be converted to dst if a subset of auth is used.
//
// K8S Services, SSH hosts, etc are also represented as Dst.
Dst map[string]*Dest `json:"dst,omitempty"`
TCPUserTimeout time.Duration
// Timeout used for TLS or SSH handshakes. If not set, 3 seconds is used.
HandsahakeTimeout time.Duration
}
MeshCfg is used to configure the mesh basic settings related to security.
type Module ¶
type Module struct {
Address string `json:"address,omitempty"`
// Modules that listen to a port should use this listener or implement a
// Handle or HandleConn method.
NetListener net.Listener `json:"-"`
// TODO: rename to 'remoteAddress' or 'dest' - use to indicate an address to use as client
ForwardTo string `json:"forwardTo,omitempty"`
// Provides access to the config, DialContext, RoundTripper, tokens and certs
Mesh *Mesh `json:"-"`
// Handler for the accepted connections.
Handler string `json:"handler,omitempty"`
// The module native interface.
Module any `json:"-"`
ConnHandler func(net.Conn) `json:"-"`
// contains filtered or unexported fields
}
Module abstract a Listener and a component capable of handling accepted connections (and UDP equivalent).
The low level net.Listener needs to be abstracted - the accepted streams may be forwarded, encrypted, etc.
type RESTRequest ¶
type RESTRequest struct {
// Must be set for namespaced resources ('default' can be used)
// If not set - cluster-wide resources.
Namespace string
// Type - required for normal K8Service resources.
Kind string
// Namespaced name - required for normal K8Service resources.
Name string
// If set - will be used instead of /api/v1/namespaces/{NS}/{KIND}s/{NAME}
Path string
// This is the resource body, typically json. Will be uploaded as POST.
Spec []byte
// If set, will be added at the end (must include ?). For example ?watch=0
Query string
// Defaults to GET if no Spec, POST otherwise.
Method string
Dest *Dest
}
RESTRequest is a REST or K8Service style request. Will be used with a Dest.
It is based on/inspired from kelseyhightower/konfig - which uses the 'raw' K8Service protocol to avoid a big dependency. Google, K8Service and many other APIs have a raw representation and don't require complex client libraries and dependencies.
No code generation or protos are used - raw JSON in []byte is used, caller can handle marshalling.
Close to K8Service raw REST client - but without the builder style.
func (*RESTRequest) HttpRequest ¶
HttpRequest creates the populated http.Request for connecting to a K8S-like server.
The destination has the Addr and config (credentials, etc).
func (*RESTRequest) Post ¶
func (k *RESTRequest) Post() *RESTRequest