Documentation
¶
Index ¶
- Constants
- Variables
- func CertToPEM(cert *x509.Certificate) []byte
- func ConnectTapToBridge(bridgeName, tapName string) error
- func ContainerUsingHostNetwork() bool
- func ConvertToZCert(cert *x509.Certificate, certType certs.ZCertType) *certs.ZCert
- func CopyFile(src string, dst string) (err error)
- func CopyFolder(source, destination string) error
- func CreateBridge(name string, addrs []*net.IPNet, groupFwdMask uint16) error
- func CreateCipherCtx(cfg *CryptoConfig) (*evecommon.CipherContext, error)
- func CreateDummyInterface(name string, ips []net.IPNet) error
- func CreateTUN(name string) (*os.File, error)
- func CreateTap(name string) error
- func DecryptBlock(cipher *evecommon.CipherBlock, cfg *CryptoConfig) (*evecommon.EncryptionBlock, error)
- func DeleteBridge(name string) error
- func DeleteTap(name string) error
- func ECDSAPrivateKeyToPEM(key *ecdsa.PrivateKey) ([]byte, error)
- func EVEDockerImageName(ref *api.ImageRef) (string, error)
- func EncryptBlock(block *evecommon.EncryptionBlock, cfg *CryptoConfig, ...) (*evecommon.CipherBlock, error)
- func ExtractFromDockerImage(ctx context.Context, log *logrus.Entry, ...) error
- func ExtractFromTar(u io.Reader, destination string) error
- func FindUnusedPort(hostIP net.IP) (uint16, error)
- func FuncNameFromStackTrace(depth int) string
- func GenCARoot() (*x509.Certificate, *rsa.PrivateKey, error)
- func GenServerCertElliptic(caCert *x509.Certificate, caKey *rsa.PrivateKey, serial *big.Int, ip []net.IP, ...) (*x509.Certificate, *ecdsa.PrivateKey, error)
- func GenerateMAC(devName, ifaceName string) net.HardwareAddr
- func GetDefaultGateway(family int) (net.IP, netlink.Link, error)
- func GetDockerAuthPlain(log *logrus.Entry, fqdn string) (string, string, error)
- func GetDockerImageSizeBytes(ctx context.Context, imageName string) (int64, error)
- func GetEgressInterfaceForIP(ip net.IP) (string, error)
- func GetFirstHostIP(subnet *net.IPNet) net.IP
- func GetInterfaceIPs(ifaceName string) ([]net.IP, error)
- func GetLastHostIP(subnet *net.IPNet) net.IP
- func GetNextIP(ip net.IP) net.IP
- func GetPrevIP(ip net.IP) net.IP
- func GetSubnetPrefixLen(subnet *net.IPNet) uint
- func HaveDockerImage(ctx context.Context, log *logrus.Entry, image string) (bool, error)
- func IsErrDockerImageNotFound(err error) bool
- func LoadDockerImageFromReader(ctx context.Context, log *logrus.Entry, r io.Reader) error
- func NewIPNet(ip net.IP, subnet *net.IPNet) *net.IPNet
- func OutputCertAndKey(crt *x509.Certificate, key any, certFile string, keyFile string) error
- func PrepareAuthContainer(payload []byte, signingCert *x509.Certificate, signingKey *ecdsa.PrivateKey) (*auth.AuthContainer, error)
- func PullDockerImage(ctx context.Context, log *logrus.Entry, imageName string) error
- func RandomDeviceSerial(length int) (string, error)
- func ReEncryptCipherData(holder CipherDataHolder, oldCfg, newCfg *CryptoConfig, ...) error
- func ResolveFile(path string) (string, error)
- func RunCommandForeground(name string, args []string, opts ...CommandOpt) (err error)
- func RunDockerCommand(ctx context.Context, log *logrus.Entry, image string, command string, ...) (result string, err error)
- func RunPipeProxy(ctx context.Context, log *logrus.Entry, proxyName string, pipe1, pipe2 Pipe)
- func RunningInContainer() bool
- func SplitIPv4Subnet(subnet *net.IPNet) (*net.IPNet, *net.IPNet, error)
- func StreamDockerImageGzip(ctx context.Context, imageName string) (io.ReadCloser, error)
- func ValidatePEMCerts(pemData []byte, expectSingle bool) ([]*pem.Block, error)
- func ValidatePEMPrivateKeyECDSA(pemData []byte) error
- type CipherDataHolder
- type CommandOpt
- type CryptoConfig
- type DataGetter
- type GrpcClientPipe
- type GrpcServerPipe
- type Pipe
- type ReadWriterPipe
Constants ¶
const MaxDecompressedContentSize = 1024 * 1024 * 1024 // 1 GB
MaxDecompressedContentSize is the maximum size of a file that can be written to disk after decompression. This is to prevent a DoS attack by unpacking a compressed file that is too big to be decompressed.
Variables ¶
var EveSSHCommonArgs = []string{
"-o", "IdentitiesOnly=yes",
"-o", "ConnectTimeout=5",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
}
EveSSHCommonArgs defines common SSH client options used when connecting to EVE devices during tests. These options enforce non-interactive operation, use only the specified identity key, apply a short connection timeout, and disable host key verification to simplify ephemeral test environments.
Functions ¶
func CertToPEM ¶
func CertToPEM(cert *x509.Certificate) []byte
CertToPEM returns the PEM encoding of the certificate.
func ConnectTapToBridge ¶
ConnectTapToBridge attaches a TAP interface to a Linux bridge by setting the bridge as the TAP interface's master.
func ContainerUsingHostNetwork ¶
func ContainerUsingHostNetwork() bool
ContainerUsingHostNetwork tries to determine if this process is running inside the host network namespace, rather than in the container's own network namespace.
func ConvertToZCert ¶
ConvertToZCert converts X.509 certificate to ZCert proto message.
func CopyFolder ¶
CopyFolder from source to destination
func CreateBridge ¶
CreateBridge creates a Linux bridge with the given name, brings it up, and assigns the specified IP addresses to it. IPs can be IPv4 or IPv6.
func CreateCipherCtx ¶
func CreateCipherCtx(cfg *CryptoConfig) (*evecommon.CipherContext, error)
CreateCipherCtx constructs a CipherContext using certificate hashes to derive a deterministic context identifier and encryption parameters.
func CreateDummyInterface ¶
CreateDummyInterface creates a dummy interface with the given name and assigns the provided IP addresses. Each IP should include the CIDR mask (/32 for IPv4, /128 for IPv6).
func CreateTUN ¶
CreateTUN creates a new TUN (network tunnel) interface with the specified name. The interface is configured in TUN mode (no packet information header) and opened for read/write access via /dev/net/tun.
The caller is responsible for configuring IP addresses, MTU, and routes, as well as closing the returned file descriptor when no longer needed.
See: https://www.kernel.org/doc/Documentation/networking/tuntap.txt
func DecryptBlock ¶
func DecryptBlock(cipher *evecommon.CipherBlock, cfg *CryptoConfig) (*evecommon.EncryptionBlock, error)
DecryptBlock decrypts a CipherBlock and unmarshals it into an EncryptionBlock.
func DeleteBridge ¶
DeleteBridge brings a bridge DOWN and deletes it.
func ECDSAPrivateKeyToPEM ¶
func ECDSAPrivateKeyToPEM(key *ecdsa.PrivateKey) ([]byte, error)
ECDSAPrivateKeyToPEM returns the PEM encoding of an ECDSA private key in PKCS#8 format.
func EVEDockerImageName ¶
EVEDockerImageName converts a EVE's ImageRef into a Docker image name of the form: <Repo>:<Version>-<hypervisor>-<arch> Returns an error if any required field is missing or unknown.
func EncryptBlock ¶
func EncryptBlock(block *evecommon.EncryptionBlock, cfg *CryptoConfig, ctx *evecommon.CipherContext) (*evecommon.CipherBlock, error)
EncryptBlock serializes and encrypts an EncryptionBlock using the provided CryptoConfig and CipherContext.
func ExtractFromDockerImage ¶
func ExtractFromDockerImage(ctx context.Context, log *logrus.Entry, imageName, localPath, containerPath string) error
ExtractFromDockerImage extracts a file or directory from a Docker image without running it. It creates a temporary container, copies the specified path from it, and then removes the container. Returns an error if any step fails. The temporary container is always removed, even if extraction fails.
Parameters:
- ctx: Context for cancellation and timeout control.
- log: Logrus entry used for structured logging.
- imageName: Name of the Docker image to extract from.
- localPath: Destination path on the host where the extracted content should be written.
- containerPath: Path inside the image (container filesystem) to extract.
func ExtractFromTar ¶
ExtractFromTar extracts files from a tar reader into the destination directory
func FindUnusedPort ¶
FindUnusedPort picks a random unused TCP port on the given host IP by probing it.
func FuncNameFromStackTrace ¶
FuncNameFromStackTrace returns the name of the function at the given call stack depth. Parameters:
depth - the number of stack frames to skip:
depth 0 = FuncNameFromStackTrace itself
depth 1 = its caller
depth 2 = caller's caller, etc.
func GenCARoot ¶
func GenCARoot() (*x509.Certificate, *rsa.PrivateKey, error)
GenCARoot generates a self-signed RSA root CA certificate.
func GenServerCertElliptic ¶
func GenServerCertElliptic( caCert *x509.Certificate, caKey *rsa.PrivateKey, serial *big.Int, ip []net.IP, dns []string, cn string, ) (*x509.Certificate, *ecdsa.PrivateKey, error)
GenServerCertElliptic generates an ECDSA server certificate signed by the given CA.
func GenerateMAC ¶
func GenerateMAC(devName, ifaceName string) net.HardwareAddr
GenerateMAC returns a deterministic, locally administered, unicast MAC address derived from the device name and interface name.
The MAC is generated by hashing stable identifiers to ensure that:
- the same device/interface pair always receives the same MAC,
- MAC addresses remain consistent across restarts,
- collisions are highly unlikely,
- the address does not conflict with real hardware.
The locally administered bit is set and the multicast bit is cleared to guarantee the MAC is valid for use in virtualized environments.
func GetDefaultGateway ¶
GetDefaultGateway returns the default gateway IP address and the output interface.
func GetDockerAuthPlain ¶
GetDockerAuthPlain returns the Docker registry username and password for a given registry FQDN. It reads credentials from the local Docker configuration and returns an error if none are found.
func GetDockerImageSizeBytes ¶
GetDockerImageSizeBytes returns the size of the given image in bytes.
func GetEgressInterfaceForIP ¶
GetEgressInterfaceForIP returns the output interface name for the given destination IP.
func GetFirstHostIP ¶
GetFirstHostIP returns the IP address that should be assigned to the bridge or used as the default gateway. For IPv4 subnets, returns subnet network address + 1 (skips network address). For IPv6 subnets, returns the subnet prefix address itself (valid unicast address).
func GetInterfaceIPs ¶
GetInterfaceIPs returns all IP addresses assigned to the given interface.
func GetLastHostIP ¶
GetLastHostIP returns the last usable host IP address within the given subnet. For IPv4 subnets, this is the address immediately before the broadcast address (i.e. network | ^mask - 1). For IPv6 subnets, where there is no broadcast address, this returns the highest address in the subnet (network | ^mask).
func GetSubnetPrefixLen ¶
GetSubnetPrefixLen returns the prefix length (number of leading 1 bits) of the given subnet's mask.
func HaveDockerImage ¶
HaveDockerImage checks if a Docker image exists locally. Returns true if the image exists, false if not, and an error if the check itself fails.
func IsErrDockerImageNotFound ¶
IsErrDockerImageNotFound returns true if err indicates that a Docker image does not exist in the local Docker daemon (i.e. "No such image").
func LoadDockerImageFromReader ¶
LoadDockerImageFromReader loads a Docker image into the local Docker daemon from a streaming gzip-compressed tar archive. The provided reader must yield data equivalent to the output of:
docker save <image> | gzip
Image data is consumed incrementally and decompressed on the fly, allowing large images to be loaded without buffering the entire archive in memory.
func NewIPNet ¶
NewIPNet combines a given IP and subnet into net.IPNet. Returns nil if either the IP or subnet is nil.
func OutputCertAndKey ¶
OutputCertAndKey writes an X.509 certificate and private key to disk in PEM format.
func PrepareAuthContainer ¶
func PrepareAuthContainer(payload []byte, signingCert *x509.Certificate, signingKey *ecdsa.PrivateKey) (*auth.AuthContainer, error)
PrepareAuthContainer wraps payload in an AuthContainer signed with the given ECDSA key. It computes a SHA-256 hash of the payload, signs that hash, and records the SHA-256 fingerprint of the signing certificate so the receiver can look up the certificate and verify the signature.
func PullDockerImage ¶
PullDockerImage ensures a Docker image is available locally by pulling it if necessary. If the image already exists, the function returns immediately.
func RandomDeviceSerial ¶
RandomDeviceSerial returns a random alphanumeric device serial number. The serial contains only letters and digits (no special characters) and is suitable for use as a device identifier.
func ReEncryptCipherData ¶
func ReEncryptCipherData(holder CipherDataHolder, oldCfg, newCfg *CryptoConfig, cipherCtx *evecommon.CipherContext) error
ReEncryptCipherData decrypts cipher data using the old CryptoConfig and re-encrypts it using the new CryptoConfig and CipherContext.
func ResolveFile ¶
ResolveFile returns the absolute path of the given file after verifying that it exists and is accessible. It returns an error if the path is empty, cannot be resolved, or does not exist.
func RunCommandForeground ¶
func RunCommandForeground(name string, args []string, opts ...CommandOpt) (err error)
RunCommandForeground runs a command in the foreground, attaching its stdout and stderr to the current process and optionally applying command options. The command is terminated if the current process receives a termination signal (SIGINT, SIGTERM, SIGQUIT, or SIGHUP).
func RunDockerCommand ¶
func RunDockerCommand(ctx context.Context, log *logrus.Entry, image string, command string, volumeMap map[string]string, platform string) (result string, err error)
RunDockerCommand executes a Docker container using the specified image, command, and bind-mounted volumes, then returns the combined stdout/stderr output.
Parameters:
- ctx: Context used for cancellation and timeouts.
- log: Logrus entry for structured logging.
- image: Docker image to run.
- command: Shell command string to execute inside the container.
- volumeMap: Mapping of container paths (keys) to host paths (values) that will be mounted as bind volumes.
- platform: Optional platform (e.g., "linux/arm64" or "linux/amd64") to run the container under. If empty, the host's default platform is used.
Returns the container output as a string. If any Docker API call fails, an error is returned. Even if cleanup fails, the output (if available) is still returned.
func RunPipeProxy ¶
RunPipeProxy connects two Pipe instances and forwards data between them bidirectionally. Data received on one pipe is sent to the other, and vice versa.
The function runs two concurrent goroutines—one for each direction—and returns when either direction ends (due to closure or error).
func RunningInContainer ¶
func RunningInContainer() bool
RunningInContainer returns true if the process is likely running inside a container. This is determined by checking for the presence of "/.dockerenv" (Docker-specific) and "/run/.containerenv" (Podman-specific).
func SplitIPv4Subnet ¶
SplitIPv4Subnet splits an IPv4 subnet into two equal subnets.
func StreamDockerImageGzip ¶
StreamDockerImageGzip exports a Docker image from the local Docker daemon and returns a streaming reader that produces a gzip-compressed tar archive of the image. The returned ReadCloser streams the equivalent of:
docker save <imageName> | gzip
Data is produced lazily and streamed directly from the Docker daemon, avoiding loading the full image into memory. The caller must read the stream until EOF and close it to release underlying resources.
func ValidatePEMCerts ¶
ValidatePEMCerts parses PEM-encoded certificates and validates them as X.509. If expectSingle is true, exactly one PEM block is expected; otherwise multiple PEM blocks are allowed (e.g., for proxy or V2 TLS certs).
func ValidatePEMPrivateKeyECDSA ¶
ValidatePEMPrivateKeyECDSA parses and validates a PEM-encoded ECDSA private key. Exactly one PEM block must be present. The key may be encoded either as PKCS#8 ("PRIVATE KEY") or legacy EC ("EC PRIVATE KEY").
Types ¶
type CipherDataHolder ¶
type CipherDataHolder interface {
GetCipherData() *evecommon.CipherBlock
}
CipherDataHolder represents an object that contains CipherData.
type CommandOpt ¶
CommandOpt allows to modify Cmd config.
func SetCommandEnvVars ¶
func SetCommandEnvVars(vars []string) CommandOpt
SetCommandEnvVars sets the given list of key=value strings as the environment variables for the command.
func SetCommandStdin ¶
func SetCommandStdin(stdin string) CommandOpt
SetCommandStdin sets the given string as the standard input for the command.
func SetThisProcessStdin ¶
func SetThisProcessStdin() CommandOpt
SetThisProcessStdin configures the command to inherit the current process's standard input (stdin). This is typically used for interactive commands that require user input.
type CryptoConfig ¶
CryptoConfig holds cryptographic material derived from device and controller certificates, including certificate hashes and a shared symmetric key.
func NewCryptoConfig ¶
func NewCryptoConfig(devECDHCert, controllerECDHCert *x509.Certificate, controllerECDHKey *ecdsa.PrivateKey) (*CryptoConfig, error)
NewCryptoConfig creates a CryptoConfig by hashing the device and controller certificates and deriving a symmetric key using ECDH between the device certificate's public key and the controller's private key.
type DataGetter ¶
type DataGetter interface {
GetData() []byte
}
DataGetter is a constraint for gRPC response types that can be used with GrpcPipe. Any response type must implement GetData() to allow the pipe to extract the payload as a byte slice.
type GrpcClientPipe ¶
type GrpcClientPipe[Req any, Res any] struct { MakeRequest func(data []byte) *Req Stream grpc.BidiStreamingClient[Req, Res] }
GrpcClientPipe turns client's gRPC stream into Pipe. Res must implement DataGetter. We cannot enforce this at compile time using DataGetter instead of "any" because of pointer/value mismatches between grpc.BidiStreamingClient and the protobuf-generated response type.
func (GrpcClientPipe[Req, Res]) Name ¶
func (p GrpcClientPipe[Req, Res]) Name() string
Name of the pipe.
func (GrpcClientPipe[Req, Res]) Recv ¶
func (p GrpcClientPipe[Req, Res]) Recv() ([]byte, error)
Recv receives data from the server.
type GrpcServerPipe ¶
type GrpcServerPipe[Req any, Res any] struct { MakeResponse func(data []byte) *Res Stream grpc.BidiStreamingServer[Req, Res] }
GrpcServerPipe turns server's gRPC stream into Pipe. Req must implement DataGetter. We cannot enforce this at compile time using DataGetter instead of "any" because of pointer/value mismatches between grpc.BidiStreamingClient and the protobuf-generated response type.
func (GrpcServerPipe[Req, Res]) Name ¶
func (p GrpcServerPipe[Req, Res]) Name() string
Name of the pipe.
func (GrpcServerPipe[Req, Res]) Recv ¶
func (p GrpcServerPipe[Req, Res]) Recv() ([]byte, error)
Recv receives data from the client.
type Pipe ¶
type Pipe interface {
// Name returns a human-readable identifier for the pipe, used only for logging.
Name() string
// Recv reads data from the pipe and returns the received bytes.
// It may block until data becomes available or an error occurs.
// If the connection is closed gracefully, it should return io.EOF.
Recv() (data []byte, err error)
// Send writes data to the pipe and returns the number of bytes written.
// It may block until the data is fully transmitted or an error occurs.
Send(data []byte) (n int, err error)
}
Pipe represents a bidirectional data channel that can send and receive arbitrary byte slices. It abstracts a transport layer such as a TCP connection, a Unix socket, gRPC stream, etc.
type ReadWriterPipe ¶
type ReadWriterPipe struct {
PipeName string
RW io.ReadWriter
Buf []byte
}
ReadWriterPipe turns io.ReadWriter into Pipe.
func (ReadWriterPipe) Recv ¶
func (p ReadWriterPipe) Recv() (data []byte, err error)
Recv receives data from the tun device.