mereach

package
v0.56.4 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package mereach is the homelab side of kombify Me's reach API (Gateway services/me/docs/API.md "Homelab reach: tunnel mode and DNS-01"): the homelab's own Me registration enables tunnel mode for its base, receives the connector token sealed to its local custody, and publishes DNS-01 values and the LAN name's private address for the LAN-name certificate (homelab identity target §5, §8, §14 decisions 3 and 4). It holds the Me registration key in Owner custody and never prints, logs or returns it.

Index

Constants

View Source
const (
	// Zone is the shared parent of every homelab base.
	Zone = "kombify.me"
	// DefaultAPI is Me's public API root.
	DefaultAPI = "https://kombify.me/_kombify/api/v1"
	// RemoteListenerIngress is the only ingress tunnel mode may carry: the
	// Access Gate's remote entrypoint on the connector network.
	RemoteListenerIngress = "http://stackkit-remote-listener.internal:8000"
)

Variables

View Source
var ErrLANAddressReadBack = errors.New("mereach: kombify Me's read-back of the LAN address record differs from what was sent")

ErrLANAddressReadBack reports a Me answer that does not read back the LAN address record as it was sent.

View Source
var (

	// ErrNoRegistration reports a homelab without a Me registration in custody.
	ErrNoRegistration = errors.New("mereach: no Me registration in custody; run 'sudo stackkit reach registration set'")
)

Functions

func BaseOf

func BaseOf(domain string) (string, bool)

BaseOf returns the Me base of a homelab domain <base>.kombify.me.

func RemoveRegistration

func RemoveRegistration(workspace string) error

RemoveRegistration deletes the registration from custody.

func SaveRegistration

func SaveRegistration(workspace string, registration Registration) error

SaveRegistration stores the registration 0600 in Owner custody.

Types

type APIError

type APIError struct {
	Status    int
	Code      string `json:"error_code"`
	Message   string `json:"error"`
	Retryable bool   `json:"retryable"`
}

APIError is Me's error answer.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	Registration Registration
	HTTP         *http.Client
}

Client calls Me with the homelab's own registration key.

func (Client) DeliverToken

func (c Client) DeliverToken(ctx context.Context, now func() time.Time) (TunnelView, []byte, error)

DeliverToken rotates the tunnel secret and receives the new connector token sealed to a fresh key of this node's local custody, which opens it. The caller owns and clears the token.

func (Client) DisableTunnel

func (c Client) DisableTunnel(ctx context.Context) (TunnelView, error)

DisableTunnel removes the base's tunnel and its DNS record; Me reads both back absent before it answers.

func (Client) EnableTunnel

func (c Client) EnableTunnel(ctx context.Context) (TunnelView, error)

EnableTunnel enables or repairs tunnel mode for the base. It answers no token. The node refuses a tunnel whose ingress is not the remote listener.

func (Client) LANName

func (c Client) LANName() string

LANName is the LAN name of this registration's base.

func (Client) RemoveChallenge

func (c Client) RemoveChallenge(ctx context.Context, identifier, value string) error

RemoveChallenge removes one DNS-01 value; Me proves it absent.

func (Client) RemoveLANAddress

func (c Client) RemoveLANAddress(ctx context.Context) error

RemoveLANAddress removes the base's LAN address record; Me proves it absent.

func (Client) SetChallenge

func (c Client) SetChallenge(ctx context.Context, identifier, value string) error

SetChallenge publishes one DNS-01 value for a name under the base.

func (Client) SetLANAddress

func (c Client) SetLANAddress(ctx context.Context, name string, address netip.Addr) error

SetLANAddress publishes the node's private address as the one DNS-only A or AAAA record of name, which must be this base's LAN name, and checks Me's read-back: the same name, DNS-only and the same address. A Me refusal is an *APIError naming Me's answer code; Me itself admits only private addresses and only for the caller's own base.

func (Client) Tunnel

func (c Client) Tunnel(ctx context.Context) (TunnelView, error)

Tunnel reads the base's tunnel mode back from Cloudflare through Me.

type DNSRecord

type DNSRecord struct {
	Name    string `json:"name"`
	Type    string `json:"type,omitempty"`
	Content string `json:"content,omitempty"`
	Proxied bool   `json:"proxied,omitempty"`
	State   string `json:"state,omitempty"`
}

DNSRecord is one record of the tunnel view.

type LANAddressRecord

type LANAddressRecord struct {
	Name    string `json:"name"`
	Type    string `json:"type"`
	Address string `json:"address"`
	Proxied *bool  `json:"proxied"`
	TTL     int    `json:"ttl"`
	Created bool   `json:"created"`
}

LANAddressRecord is Me's Cloudflare read-back of the base's LAN address record lan.<base>.kombify.me. Proxied is a pointer so that an answer without it never reads as DNS-only.

type Registration

type Registration struct {
	APIVersion string `json:"apiVersion"`
	Base       string `json:"base"`
	API        string `json:"api"`
	APIKey     string `json:"apiKey"`
}

Registration is the homelab's own Me registration: its base and the registration key Me answered once.

func LoadRegistration

func LoadRegistration(workspace string) (Registration, error)

LoadRegistration reads the registration from Owner custody.

type TunnelView

type TunnelView struct {
	Base           string      `json:"base"`
	Enabled        bool        `json:"enabled"`
	TunnelID       string      `json:"tunnel_id"`
	TunnelName     string      `json:"tunnel_name"`
	TunnelStatus   string      `json:"tunnel_status"`
	Hostnames      []string    `json:"hostnames"`
	IngressService string      `json:"ingress_service"`
	IngressCurrent bool        `json:"ingress_current"`
	DNSRecords     []DNSRecord `json:"dns_records"`
	Custody        string      `json:"custody,omitempty"`
	Tunnel         string      `json:"tunnel,omitempty"`
}

TunnelView is Me's Cloudflare read-back of a base's tunnel mode. It never carries a token.

Jump to

Keyboard shortcuts

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