agent

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2026 License: MIT Imports: 49 Imported by: 0

Documentation

Overview

Package agent は自宅側のエージェント(仕様 7 節)。 認証情報ファイルの鍵と最後の全体状態でトンネルとリスナーを先に立て、その後 stream に繋いで全体状態を受け取る。

Index

Constants

View Source
const (
	KernelOwnershipAbsent       = "absent"
	KernelOwnershipCurrent      = "current"
	KernelOwnershipPrevious     = "previous"
	KernelOwnershipForeign      = "foreign"
	KernelOwnershipKeyless      = "keyless"
	KernelOwnershipNotWireGuard = "not_wireguard"
)

Ownership の値。internal/dataplane/linuxkernel/wg の Ownership を、Linux の外でも読める語にしたもの。

View Source
const (
	// KernelEffectHost は、wgft0 から、wgft が公開していないホストのポートに届きうることである。
	// filter_pre と input の drop の行が両方欠けたときである
	KernelEffectHost = "host"
	// KernelEffectOtherDNAT は、wgft0 から、他のテーブルの DNAT に届きうることである。filter_pre の drop の
	// 行が欠けたときである
	KernelEffectOtherDNAT = "other_dnat"
	// KernelEffectLAN は、wgft0 から、DNAT していないパケットが LAN へ転送されうることである。filter_pre と
	// forward の wgft0 から入るものの drop の行が両方欠けたときである
	KernelEffectLAN = "lan"
	// KernelEffectHairpin は、wgft0 から入ったパケットが wgft0 へ折り返されうることである。forward の
	// wgft0 から wgft0 への drop の行が欠けたときである
	KernelEffectHairpin = "hairpin"
	// KernelEffectToTunnel は、転送したフローの返りでないパケットが wgft0 へ転送されうることである。
	// forward の wgft0 へ出るものの drop の行が欠けたときである
	KernelEffectToTunnel = "to_tunnel"
	// KernelEffectMSS は、ICMP を落とす経路で大きな TCP が止まりうることである
	KernelEffectMSS = "mss"
)

守りの行が欠けたときに開きうる面である(DoctorKernelTable.GuardEffects の値。設計文書 10.2c 節)。drop の 行は層になっているので、面は、その面を閉じる行がすべて欠けたときだけ開く。

View Source
const (
	// KernelClosedHostByFilterPre は、input の drop の行が欠けても、filter_pre の drop の行がホストのポートを閉じていることである
	KernelClosedHostByFilterPre = "host_by_filter_pre"
	// KernelClosedHostByInput は、filter_pre の drop の行が欠けても、input の drop の行がホストのポートを閉じていることである
	KernelClosedHostByInput = "host_by_input"
	// KernelClosedLANByFilterPre は、forward の drop の行が欠けても、filter_pre の drop の行が LAN への面を閉じていることである
	KernelClosedLANByFilterPre = "lan_by_filter_pre"
	// KernelClosedLANByForward は、filter_pre の drop の行が欠けても、forward の drop の行が LAN への面を閉じていることである
	KernelClosedLANByForward = "lan_by_forward"
)

欠けた drop の行の面を、残っている行がまだ閉じていることである(DoctorKernelTable.GuardClosed の値)。

View Source
const (
	// KernelTableFromRecord は、直近の公開の記録と比べたことである
	KernelTableFromRecord = "record"
	// KernelTableFromDeclaration は、記録が無く、全体状態の宣言から導ける範囲だけを比べたことである
	KernelTableFromDeclaration = "declaration"
)

Source の値。比べた材料である。

View Source
const ControlPathLimit = 103

ControlPathLimit は、どの OS でも収まる制御ソケットのパスの長さ(バイト)。sockaddr_un の sun_path は Linux と Windows で 108 バイト、macOS で 104 バイトで、終端の NUL を含む(仕様 11a 節)。

公開しているのは、繋げなかった理由が長さにあるかどうかを外から判定する読み手がいるためである (設計文書 10.2c 節の agent.control)。写しを持たせると、片方だけを直したときに判定が食い違う。

View Source
const DoctorCommand = "doctor"

DoctorCommand は制御ソケットに送る 1 行の要求である。

View Source
const DoctorReplyMaxBytes = 4 << 20

DoctorReplyMaxBytes bounds how much of a reply `wgft agent doctor` reads from the control socket before giving up (cmd/wgft/agentdoctorlive.go's readAgentLive). Both sides of this socket run on the same host, but design.md 11 節 treats the agent process as outside the trust boundary: a compromised agent binary could otherwise hold the line open and never send the newline bufio.Reader.ReadString waits for, growing its internal buffer without bound. The value matches internal/agent/stream.go's SetReadLimit for the full state this agent reads from the server over the WebSocket stream, which is the same order of magnitude as the largest legitimate reply this socket carries: a doctor response listing every rule this agent holds. rotate-key's own read below uses a much smaller limit, rotateKeyReplyLimit, since its reply is always a short "ok <key>" or "error: <text>" line.

View Source
const ReasonHandshakePending = "handshake not established"

heartbeat は処理済み世代、トンネルの状態、ルールごとの状態をまとめる(仕様 5.2 節)。 ReasonHandshakePending は、トンネルはあるが WireGuard のハンドシェイクがまだ済んでいないときの理由。 適用直後の追送り(needsHandshakeFollowUp)がこの値で判定するので、文言を変えるときは両方に効く。

公開しているのは、制御ソケットの doctor の応答から同じ場合を見分ける読み手がいるためである (設計文書 10.2c 節)。応答が載せるのは理由の文字列だけで、ハンドシェイク待ちを tunnel.Status の Err による誤りと分ける材料は他に無い。写しを持たせると、この文言を変えたときに読み手だけが 取り残される。

View Source
const ReasonWGRefused = "refused the wg configuration"

ReasonWGRefused は、トンネルが立っている間に届いた wg 設定をカーネルモードのエージェントが拒んだときの、 ハートビートのトンネルの理由の書き出しである(設計文書 7b.1 節)。agent doctor の tunnel.local が同じ 場合を見分けて所見の文面を変えるので、ReasonHandshakePending と同じく公開する。

Variables

View Source
var ErrPinMismatch = errors.New("server certificate does not match the pinned hash")

ErrPinMismatch はサーバ証明書がピンと一致しない。teardown --purge のあとに立て直したサーバか、経路上の 第三者による TLS の終端で起きる。復帰は未使用の WGFT_JOIN による再登録(仕様 5.1 節)。

View Source
var ErrRegisterRejected = errors.New("registration rejected: join string already used or expired, or the name differs")

ErrRegisterRejected は登録が認証で拒否された(トークンが無効、名前違い)。

Functions

func ControlPath

func ControlPath(path string) string

ControlPath は認証情報ファイルに対応する制御ソケットの場所。

func PinnedClient

func PinnedClient(pin [32]byte) *http.Client

PinnedClient は証明書の SHA-256 がピンと一致するときだけ通す HTTP クライアント。 通常の検証(CA、ホスト名、期限)は使わない。IP 直打ちでも DNS 名でも同じ接続文字列が使える。

func PublicKey

func PublicKey(path string) (wgtypes.Key, error)

PublicKey は認証情報ファイルの鍵の公開鍵を返す。エージェントが止まっていて鍵が無ければ、生成して 保存する。別のプロセスがロックを持っていれば読むだけで書かない(仕様 9 節)。排他の取り方は停止中の rotate-key と同じで、lockWhileStopped にある。

func ReadControlReply added in v1.2.0

func ReadControlReply(c net.Conn, max int64) (string, error)

ReadControlReply reads one line from a control-socket connection under max bytes, shared by rotateKeyRunning below (with rotateKeyReplyLimit) and cmd/wgft/agentdoctorlive.go's readAgentLive (with DoctorReplyMaxBytes): both connect to this socket by their own means, but both read a line off it, under their own size limit, the same way.

A reply that hits the cap without ever sending the newline bufio.Reader.ReadString waits for comes back as a plain io.EOF from the underlying reader, indistinguishable on its face from a well-behaved agent that simply closed the connection early after a short reply. That distinction matters to an operator reading the error: an early close points at the agent process (it stopped answering), while hitting the cap points at this size limit itself. This function tells them apart by the byte count actually read: an early close reads fewer than max bytes before EOF, while hitting the cap reads exactly that many (レビューの指摘, 2026-09-26).

func Register

func Register(ctx context.Context, j *Join, name string) (permanentToken, address, confirmedName string, err error)

Register は登録 API を呼び、恒久トークン、割り当てアドレス、確定した名前を返す。 name は任意(空なら送らない側に倣ってトークンに紐付いた名前で登録される)。

func RotateKey

func RotateKey(path string) (string, error)

RotateKey は CLI から呼ぶ。稼働中なら制御ソケット経由で、停止中なら認証情報ファイルの鍵と last_state を直接消す。

func Run

func Run(opts Options) error

Run は認証情報ファイルを読み、登録を確かめ、トンネルとリスナーを立て、stream に繋ぎ、シグナルまで動く。

func Teardown added in v1.2.0

func Teardown(opts TeardownOptions, out io.Writer) error

Teardown は撤去を実行し、out に消すもの、触らないもの、結果、手で戻す一覧を書く(設計文書 10.3 節)。

Types

type DoctorAllowTargets added in v1.1.0

type DoctorAllowTargets struct {
	// Set は一覧を持っているかどうか。偽なら、server はこのエージェントが届くどの宛先も指せる
	Set bool `json:"set"`
	// List は正規化した一覧。Set が偽なら空
	List string `json:"list,omitempty"`
	// Env は一覧を渡す設定の名前
	Env string `json:"env"`
}

DoctorAllowTargets は宛先の許可一覧である。一覧の中身はエージェントのホストにしか無く、 server には届かない(設計文書 10.2c 節)。

type DoctorBudget added in v1.1.0

type DoctorBudget struct {
	Proto proto.Proto `json:"proto"`
	// Total は予算 T、InUse は今のフロー数 u である
	Total int `json:"total"`
	InUse int `json:"in_use"`
	// RuleCap はルールが 2 本以上あるときのルール 1 本の上限 C、Reserve はルール 1 本あたりの
	// 隔離予約 q、Rules は今受け付けているルールの数 N である
	RuleCap int `json:"rule_cap"`
	Reserve int `json:"reserve"`
	Rules   int `json:"rules"`
	// Refusals は拒否の累計である。起点は DoctorRuntimeState.RefusalsSince
	Refusals []DoctorRefusal `json:"refusals,omitempty"`
}

DoctorBudget は 1 つのプロトコルのフロー予算である。記号は設計文書 7a.10 節に合わせる。

type DoctorKernel added in v1.2.0

type DoctorKernel struct {
	Interface  DoctorKernelInterface  `json:"interface"`
	Table      DoctorKernelTable      `json:"table"`
	Forwarding DoctorKernelForwarding `json:"forwarding"`
}

DoctorKernel はカーネルモードの dataplane の 3 つの面である。

func ReadKernel added in v1.2.0

func ReadKernel(f *credentials.Credentials, iface string) *DoctorKernel

ReadKernel は、止まっているエージェントのカーネルの状態を、認証情報ファイル f と WireGuard インタフェースの名前 iface から直接読む(設計文書 10.2c 節)。稼働中のエージェントも同じ読み方を 使う。カーネルに何も書かない。

type DoctorKernelForwarding added in v1.2.0

type DoctorKernelForwarding struct {
	// IPForward は net.ipv4.ip_forward の値である。読めなければ空で、IPForwardError が理由である
	IPForward      string `json:"ip_forward,omitempty"`
	IPForwardError string `json:"ip_forward_error,omitempty"`
	// RPFilterStrict は、rp_filter が 1 の設定の名前(all、default)である
	RPFilterStrict []string `json:"rp_filter_strict,omitempty"`
	// PolicyDrops は、既定でパケットを落とす他のテーブルの forward のチェーンの場所である
	PolicyDrops []string `json:"policy_drops,omitempty"`
	// PolicyError は他のテーブルを読めなかった理由、PolicyNeedsNetAdmin はそれが CAP_NET_ADMIN の
	// 不足によることである
	PolicyError         string `json:"policy_error,omitempty"`
	PolicyNeedsNetAdmin bool   `json:"policy_needs_net_admin,omitempty"`
}

DoctorKernelForwarding はホストの転送の設定である。

type DoctorKernelInterface added in v1.2.0

type DoctorKernelInterface struct {
	// Name はインタフェースの名前である
	Name string `json:"name"`
	// ReadError は、リンクそのものを読めなかった理由である。値があるとき、残りの項目は意味を持たない
	ReadError string `json:"read_error,omitempty"`
	// Exists、Kind、Up は権限なしで読める(リンクの属性)。
	Exists bool   `json:"exists"`
	Kind   string `json:"kind,omitempty"`
	Up     bool   `json:"up"`
	// NeedsNetAdmin は、鍵とピアを CAP_NET_ADMIN なしには読めなかったことである。このとき Ownership
	// から下の項目は無い
	NeedsNetAdmin bool `json:"needs_net_admin,omitempty"`
	// DeviceError は、鍵とピアを権限以外の理由で読めなかった理由である
	DeviceError string `json:"device_error,omitempty"`
	// Ownership は KernelOwnership* のどれかである。鍵を読めなかった場合は空になる
	Ownership string             `json:"ownership,omitempty"`
	MTU       int                `json:"mtu,omitempty"`
	Addresses []string           `json:"addresses,omitempty"`
	Peers     []DoctorKernelPeer `json:"peers,omitempty"`

	// Declared は、比べる宣言(全体状態の wg 設定)があったかどうかである。無ければ PeerOK と
	// Differs は意味を持たない
	Declared bool `json:"declared"`
	// ServerAddress は vpsd のトンネルアドレスである。宣言から決まる
	ServerAddress string `json:"server_address,omitempty"`
	// PeerOK は、server の公開鍵を持ち、server のトンネルアドレスを AllowedIPs に含むピアがあることである
	PeerOK bool `json:"peer_ok"`
	// Differs は、宣言と違う点である。30 秒ごとの見直しが食い違いと見るのと同じ関数から来る
	Differs []string `json:"differs,omitempty"`

	// RouteInterface は、server のトンネルアドレスへの経路が向かうインタフェースの名前である。
	// RouteError は経路を読めなかった理由である。どちらも宣言が無ければ無い
	RouteInterface string `json:"route_interface,omitempty"`
	RouteError     string `json:"route_error,omitempty"`
}

DoctorKernelInterface はエージェントの WireGuard インタフェースである。

type DoctorKernelPeer added in v1.2.0

type DoctorKernelPeer struct {
	PublicKey  string        `json:"public_key"`
	AllowedIPs []string      `json:"allowed_ips,omitempty"`
	Endpoint   string        `json:"endpoint,omitempty"`
	Keepalive  time.Duration `json:"keepalive,omitempty"`
	// LastHandshake は最終ハンドシェイクである。成立していなければゼロ値の時刻になる
	LastHandshake time.Time `json:"last_handshake"`
	RxBytes       int64     `json:"rx_bytes"`
	TxBytes       int64     `json:"tx_bytes"`
}

DoctorKernelPeer はインタフェースのピア 1 つである。値を示すだけで、健全さを判定しない。

type DoctorKernelTable added in v1.2.0

type DoctorKernelTable struct {
	// ReadError はテーブルを読めなかった理由である。NeedsNetAdmin は、それが CAP_NET_ADMIN の
	// 不足によることである
	ReadError     string `json:"read_error,omitempty"`
	NeedsNetAdmin bool   `json:"needs_net_admin,omitempty"`
	Present       bool   `json:"present"`
	// Source は比べた材料で、KernelTableFrom* のどれかである。比べる材料が無ければ空になる
	Source string `json:"source,omitempty"`
	// Generation は記録の元にした全体状態の世代である
	Generation uint64 `json:"generation,omitempty"`
	// Missing は、記録から組む表にあって実際の表に無い行、チェーン、DNAT のうち、欠けると転送が止まる
	// ものである。長くなりすぎない
	// ように先頭のいくつかだけを持ち、MissingCount が全体の数である
	Missing      []string `json:"missing,omitempty"`
	MissingCount int      `json:"missing_count,omitempty"`
	// GuardMissing は、記録から組む表にあって実際の表に無いもののうち、欠けても転送が止まらない行と
	// チェーン(守りの行)である。Missing には入らない。GuardMissingCount が全体の数である
	GuardMissing      []string `json:"guard_missing,omitempty"`
	GuardMissingCount int      `json:"guard_missing_count,omitempty"`
	// GuardEffects は、欠けた守りの行の組み合わせによって開きうる面である。値は KernelEffect* である。
	// GuardClosed は、欠けた drop の行の面を残っている行がまだ閉じていることである。値は KernelClosed* である
	GuardEffects []string `json:"guard_effects,omitempty"`
	GuardClosed  []string `json:"guard_closed,omitempty"`
	// Moved は、記録から組む表の行のうち、同じチェーンの別の位置にあるものである。欠けた行には数えない
	// (設計文書 10.2c 節)。MovedCount が全体の数である
	Moved      []string `json:"moved,omitempty"`
	MovedCount int      `json:"moved_count,omitempty"`
	// Unexpected は、記録に無いのに実際の表にある行、チェーン、DNAT である
	Unexpected      []string `json:"unexpected,omitempty"`
	UnexpectedCount int      `json:"unexpected_count,omitempty"`
	// Rules は記録か宣言から読んだルールごとの状態である。稼働中の応答では、ハートビートの状態は
	// DoctorRuntimeState.Rules にあり、こちらは記録が持つ理由である
	Rules []DoctorRule `json:"rules,omitempty"`
}

DoctorKernelTable は table inet wgft_agent と、直近の公開の記録との比較である。

type DoctorProcess added in v1.2.0

type DoctorProcess struct {
	// UID は実 uid である。Windows では -1 になる
	UID int `json:"uid"`
	// User は UID の利用者名である。引けなければ空になる。systemd の DynamicUser の利用者は
	// /etc/passwd に無いので、静的なビルドでは引けないことがある
	User string `json:"user,omitempty"`
	// NetAdmin は、プロセスが実効として CAP_NET_ADMIN を持つかどうかである。Linux の外と、読めな
	// かった場合は nil になる
	NetAdmin *bool `json:"cap_net_admin,omitempty"`
}

DoctorProcess は稼働中のエージェントのプロセスの実行主体である。root で実行した agent doctor は ファイルのパーミッションを迂回するので、エージェント自身がどの利用者で動いているかを添える (設計文書 10.2c 節)。

type DoctorRefusal added in v1.1.0

type DoctorRefusal struct {
	RuleID string `json:"rule_id"`
	// Reason は budget、rule_cap、reserve のいずれか(設計文書 7a.10 節)
	Reason resource.Reason `json:"reason"`
	Count  uint64          `json:"count"`
}

DoctorRefusal はルール 1 本の 1 つの理由の拒否の累計である。

type DoctorResponse added in v1.1.0

type DoctorResponse struct {
	// Error は応答を組む処理が失敗したことと、その理由である。運用者に何が起きたかを伝えるために
	// 載せる。値があるとき、残りの項目は無い
	Error string `json:"error,omitempty"`

	// AllowTargets は宛先の許可一覧である。起動時に決まって以後変わらず、実行時の排他も要らないので、
	// 排他を取れなかった応答にも載る
	AllowTargets *DoctorAllowTargets `json:"allow_targets,omitempty"`

	// Stream は制御ストリームの観測である。streamMu だけで読めるので、実行時の排他を取れなかった
	// 応答にも載る
	Stream *DoctorStream `json:"stream,omitempty"`

	// Process は稼働中のエージェントのプロセスの実行主体である。実行時の排他を要らないので、排他を
	// 取れなかった応答にも載る(設計文書 10.2c 節の「カーネルモードの制御ソケットの応答」)
	Process *DoctorProcess `json:"process,omitempty"`

	// RuntimeState は実行時の排他の下でしか読めない状態である。排他を期限内に取れなければ無い
	RuntimeState *DoctorRuntimeState `json:"runtime_state,omitempty"`
	// RuntimeStateTimeout は、実行時の排他を取れなかったときに待った期限である。単位はナノ秒。
	// 取れた場合は 0 になる
	RuntimeStateTimeout time.Duration `json:"runtime_state_timeout,omitempty"`
}

DoctorResponse は doctor の応答である。1 行の JSON として送る。

Error があるときは、他の 3 つの項目が無い。応答を組む処理が panic したことを表すためである。 RuntimeState が無く RuntimeStateTimeout があるときは、実行時の状態を守る排他を期限内に 取れなかったことを表す。エージェントは生きているが内部の処理で詰まっている。

type DoctorRule added in v1.1.0

type DoctorRule struct {
	ID string `json:"id"`
	// State と Reason はハートビートが組み立てる proto.RuleStatus の値そのものである
	State  string `json:"state"`
	Reason string `json:"reason,omitempty"`
	// Proto は tcp か udp
	Proto proto.Proto `json:"proto,omitempty"`
	// Listeners はこのルールに属するリスナーの数、Listening はそのうち待ち受けを開けている数である
	Listeners int `json:"listeners"`
	Listening int `json:"listening"`
	// BindErrors は待ち受けを開けなかったリスナーの数、BindError はその 1 つの理由である。
	// 開けない原因はポートの衝突を指す
	BindErrors int    `json:"bind_errors"`
	BindError  string `json:"bind_error,omitempty"`
	// TargetErrors は待ち受けは開いていて宛先に届かないリスナーの数、TargetError はその 1 つの
	// 理由である。届かない原因は宛先の機器を指すので、運用者の次の行動が bind の失敗とは違う
	TargetErrors int    `json:"target_errors"`
	TargetError  string `json:"target_error,omitempty"`
	// Sessions は中継が持っている接続の数である。TCP は公開側と宛先側の両方を数えるので、
	// フロー予算の上限の対象とは一致しない。上限の対象の数は Flows である
	Sessions int `json:"sessions"`
	Flows    int `json:"flows"`
	// Ports はルールの宣言のポートの数、DNATPorts はそのうちカーネルモードで DNAT を置いたポートの
	// 数である。カーネルモードのルールだけが持つ。DNAT を置いたまま error を報告するルールと、DNAT を
	// 持たないルールを見分けるためである(設計文書 10.2c 節)
	Ports     int `json:"ports,omitempty"`
	DNATPorts int `json:"dnat_ports,omitempty"`
}

DoctorRule はルール 1 本の状態である。リスナー 1 つずつは並べない。ポート範囲の幅に上限が無く、 listen_port=1-65535 のルール 1 本で 65535 個のリスナーができるので、そのまま並べると 1 行が 数 MB になる(設計文書 10.2c 節)。

type DoctorRuntimeState added in v1.1.0

type DoctorRuntimeState struct {
	// Mode は稼働中のエージェントの転送の方式である(kernel か userspace。仕様 11a 節)。旧い版の
	// エージェントは送らないので、空ならユーザー空間モードである
	Mode string `json:"mode,omitempty"`
	// Generation は最後に受け取って処理した全体状態の世代
	Generation uint64       `json:"generation"`
	Tunnel     DoctorTunnel `json:"tunnel"`
	// Rules はルールごとの状態である。リスナー 1 つずつは並べない。ルールを受け付ける資源が無ければ
	// 項目ごと出ない。カーネルモードでは、リスナーの数と中継の数はどれも 0 で、状態と理由だけが意味を持つ
	Rules []DoctorRule `json:"rules,omitempty"`
	// Budgets はプロトコルごとのフロー予算である。中継が無ければ項目ごと出ない
	Budgets []DoctorBudget `json:"budgets,omitempty"`
	// RefusalsSince は Budgets の拒否の累計の起点、つまり今のトンネルを立てた時刻である。
	// フロー予算はトンネルを立て直すたびに中継ごと作り直され、累計はそのたびに 0 に戻る
	// (設計文書 10.2c 節)。中継が無ければゼロ値の時刻になる。項目そのものは必ず出るので、
	// 読み手は IsZero で判定する
	RefusalsSince time.Time `json:"refusals_since"`
	// AgentDisabled は、最後に適用した全体状態の proto.State.AgentDisabled をそのまま写した
	// ものである(仕様 5.1 節)。server がこのエージェントを無効にしていることをエージェント
	// 自身の診断のために示すだけで、守りには使わない。relay.listeners はこの値から SKIPPED を
	// 判定する(設計文書 10.2c 節)
	AgentDisabled bool `json:"agent_disabled"`

	// Kernel はカーネルモードの dataplane を読んだ結果である(設計文書 10.2c 節)。カーネルモードの
	// エージェントだけが持つ。停止中の agent doctor も ReadKernel で同じ形を読む
	Kernel *DoctorKernel `json:"kernel,omitempty"`
	// PublishError は、公開できずに試し直している全体状態の誤りである(7b.3 節の 3 つ目の種類)。
	// 旧いテーブルが残って転送を続けている
	PublishError string `json:"publish_error,omitempty"`
	// CheckError は、カーネルモードの直前の見直しの誤りである。30 秒ごとの見直しと変更の通知の後の
	// 見直しの両方を指す(7b.4 節)
	CheckError string `json:"check_error,omitempty"`
}

DoctorRuntimeState は実行時の排他の下で 1 度に読んだ状態である。トンネル、ルール、フロー予算の 値はどれも同じ時点のものである。

type DoctorStream added in v1.1.0

type DoctorStream struct {
	Connected bool `json:"connected"`
	// DisconnectedAt と RetryAt、LastPingAt、LastPongAt は、値が無ければゼロ値の時刻になる。
	// encoding/json の omitempty は struct に効かないので、項目そのものは必ず出る。読み手は
	// IsZero で判定する
	DisconnectedAt   time.Time `json:"disconnected_at"`
	DisconnectReason string    `json:"disconnect_reason,omitempty"`
	// PinMismatch は、直近の切断か試みの失敗が、server の証明書と登録のときに固定したハッシュとの
	// 不一致だったことである。旧い版のエージェントは送らない
	PinMismatch bool `json:"pin_mismatch,omitempty"`
	// Backoff は直近に待った再接続の間隔。単位はナノ秒
	Backoff      time.Duration `json:"backoff,omitempty"`
	RetryAt      time.Time     `json:"retry_at"`
	LastPingAt   time.Time     `json:"last_ping_at"`
	LastPongAt   time.Time     `json:"last_pong_at"`
	AwaitingPong bool          `json:"awaiting_pong"`
}

DoctorStream は制御ストリームの観測の写しである。項目の意味は streamObservation にある。

type DoctorTunnel added in v1.1.0

type DoctorTunnel struct {
	// Present はトンネルがあるかどうか。偽なら Reason がその理由を言う
	Present bool `json:"present"`
	// State は ok か error
	State  string `json:"state"`
	Reason string `json:"reason,omitempty"`
	// Endpoint は解決済みのエンドポイント。初回の名前解決に失敗したトンネルは持たない
	Endpoint string `json:"endpoint,omitempty"`
	// LastHandshake は今の device から読んだ最終ハンドシェイクである。watchdog が別に持つ値は
	// トンネルを閉じても消えず、立て直した直後は前のトンネルの値が残るので、そちらは載せない。
	// 成立していなければゼロ値の時刻になる。項目そのものは必ず出るので、読み手は IsZero で判定する
	LastHandshake time.Time `json:"last_handshake"`
	RxBytes       int64     `json:"rx_bytes"`
	TxBytes       int64     `json:"tx_bytes"`
	// StartedAt は今のトンネルを立てた時刻。トンネルが無ければゼロ値の時刻になる
	StartedAt time.Time      `json:"started_at"`
	Watchdog  DoctorWatchdog `json:"watchdog"`
}

DoctorTunnel はトンネルの状態である。State と Reason はハートビートが組み立てる値そのもので、 doctor のための 2 つ目の判定は持たない(設計文書 10.2c 節)。

type DoctorWatchdog added in v1.1.0

type DoctorWatchdog struct {
	// RebuildInterval は判定に使う作り直しの間隔の実効値である。単位はナノ秒
	RebuildInterval time.Duration `json:"rebuild_interval"`
	// RetryAt は、作成に失敗して試し直しを待っている場合の予定の時刻。待っていなければゼロ値の
	// 時刻になる。項目そのものは必ず出るので、読み手は IsZero で判定する
	RetryAt time.Time `json:"retry_at"`
}

DoctorWatchdog はトンネルを作り直す判定の状態である。次の作り直しまでの残り時間は載せない。 残りは保持されておらず、示すには起点を求める規則を診断の側に写すことになるためである (設計文書 10.2c 節)。

type Join

type Join struct {
	Endpoint string // host:port(エージェント用 API)
	Token    string // 1 回限りの登録トークン
	Pin      [32]byte
	// contains filtered or unexported fields
}

Join は接続文字列 wgft://host:port/token#sha256:<hex> の中身(仕様 5.1 節)。

func ParseJoin

func ParseJoin(s string) (*Join, error)

ParseJoin は接続文字列を解釈する。scheme、ポート、sha256 のピンをすべて要求する。

func (*Join) TokenHash

func (j *Join) TokenHash() string

TokenHash は使用済みトークンの記録用(仕様 5.1 節の復帰経路で比較する)。

type Options

type Options struct {
	// AllowTargets は接続してよい宛先の許可一覧(仕様 7 節、WGFT_AGENT_ALLOW_TARGETS)。
	// nil なら制限せず、vpsd が配るどの宛先へも接続する
	AllowTargets    *allowtargets.List
	CredentialsPath string          // 認証情報ファイル
	Join            string          // 接続文字列(WGFT_JOIN か --join)。初回登録に使う
	Limits          resource.Limits // 同時フロー数のプロセス全体の予算(仕様 7 節)。ゼロ値は既定値
	Name            string          // エージェント名(WGFT_NAME か --name)。任意。接続文字列の発行時の名前に紐付いているので、与えなければトークンに紐付いた名前で登録される
	Version         string          // 起動ログに出す wgft の版(cmd 側の effectiveVersion())。空なら "dev" として出す

	// Mode は設定の WGFT_MODE の値である(仕様 11a 節)。kernel か userspace で、空なら省略されており
	// userspace を指す。起動時に認証情報ファイルの記録と照合する(mode.go)
	Mode string
	// WGInterface はカーネルモードの WireGuard インタフェースの名前である(WGFT_WG_INTERFACE、既定 wgft0。
	// 仕様 7b.1・11a 節)。ユーザー空間モードでは使わない
	WGInterface string
}

Options は agent の起動オプション。

type TeardownOptions added in v1.2.0

type TeardownOptions struct {
	// CredentialsPath は agent.json のパスである。
	CredentialsPath string
	// Interface は WGFT_WG_INTERFACE の値である。鍵の一致しないリンクをこの名前と作業用の名前で
	// 探して示すために使う。鍵の一致するインタフェースは名前によらず消す。
	Interface string
	// DryRun なら、消すものと手で戻す一覧を示すだけで何も変えない。
	DryRun bool
}

TeardownOptions は撤去の指定である。

Directories

Path Synopsis
Package allowtargets は、エージェントが接続してよい宛先の一覧(設計文書 7 節)。
Package allowtargets は、エージェントが接続してよい宛先の一覧(設計文書 7 節)。
Package credentials はエージェントの認証情報ファイル(agent.json)を扱う(仕様 9 節)。
Package credentials はエージェントの認証情報ファイル(agent.json)を扱う(仕様 9 節)。

Jump to

Keyboard shortcuts

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