Documentation
¶
Overview ¶
Package admin は管理用 API(仕様 5, 11 節)。既定は Unix ソケット(root 所有 0600)で待ち受け、 Web UI と CLI が使う。独自のパスワードは持たず、守りは Unix ソケットのパーミッション、 Tailscale、SSH 転送という既存の境界と、ブラウザ経路の Host 検査・他オリジン発の変更の拒否で行う。
Index ¶
- Constants
- Variables
- func ApplyBatchToRules(rules []proto.Rule, req BatchRequest) ([]proto.Rule, error)
- func Listen(addr string, warnNonLoopback bool) (net.Listener, error)
- func ReservedFromServerInfo(info ServerInfo) proto.Reserved
- func Serve(addr string, h http.Handler, warnNonLoopback bool) error
- func ServeListener(ln net.Listener, h http.Handler) error
- func T(locale, key string) string
- type AgentChangeError
- type AgentDisabledResponse
- type AgentInfo
- type AgentRuleStatus
- type AgentRuleStatusBackend
- type ApplyStatus
- type ApplyStatusBackend
- type Backend
- type BatchRequest
- type BatchResponse
- type Client
- func (c *Client) AgentState(name string) (*proto.State, error)
- func (c *Client) Agents() ([]AgentInfo, error)
- func (c *Client) Batch(req BatchRequest) (*BatchResponse, error)
- func (c *Client) CheckConnectivity(ruleID string) (*ConnCheck, error)
- func (c *Client) DisableAgent(name string) (*AgentDisabledResponse, error)
- func (c *Client) DismissWarning(name, kind, detail string) error
- func (c *Client) EnableAgent(name string) (*AgentDisabledResponse, error)
- func (c *Client) JoinString(name string) (*JoinStringResponse, error)
- func (c *Client) NFT() (string, error)
- func (c *Client) Revoke(name string) error
- func (c *Client) Rules() (*BatchResponse, error)
- func (c *Client) ServerInfo() (*ServerInfo, error)
- func (c *Client) Warnings() ([]Warning, error)
- type ConnCheck
- type Drift
- type DriftResource
- type ErrorBody
- type FlowBudget
- type IPForwardBackend
- type IPForwardStatus
- type JoinStringRequest
- type JoinStringResponse
- type ResourceStatus
- type ResourceStatusBackend
- type RuleApply
- type Server
- type ServerInfo
- type TunnelStatus
- type UDPReply
- type UDPReplyBackend
- type Warning
Constants ¶
const ( ApplyActive = adminapi.ApplyActive ApplyPending = adminapi.ApplyPending ApplyNotActive = adminapi.ApplyNotActive )
この API の読み取り側の型は internal/vpsd/adminapi が持ち、ここで同じ名前に別名を付ける (design.md 10.2d 節。admin.go の別名と同じ理由である)。
Variables ¶
var ErrBatchConflict = errors.New("rules changed since the expected digest was read")
ErrBatchConflict は Backend.Batch が ExpectedDigest の不一致で拒んだときの誤り。 管理用 API は HTTP 409 に写し、Web UI の読み込み確認はこれを、確認ページを描いた後に 変わった場合と同じ「re-upload を求める」画面に写す(webui_import.go の uiImportApply)。
Functions ¶
func ApplyBatchToRules ¶ added in v0.4.0
ApplyBatchToRules は ExpectedDigest を照合したうえで、req の upsert/delete を rules に ID で当てはめた結果を返す(ID があれば置き換え、なければ追加。delete は最後に外す)。 本物の Backend(internal/vpsd の Daemon.Batch)はエージェントの登録確認や nftables への 反映、同じ ExpectedDigest の照合も行うが、ここにはその一部が無い。fake や demo の Backend 実装(admin_test.go の fakeBackend、tools/uidemo のもの)が、CLI/Web UI から見た 見た目だけを本物に合わせるために共有する組み立てである。store.ApplyBatch の mutate に そのまま渡せる ([]proto.Rule, error) を返す形にしているのは、rules がその関数の中で 読み取る「今の」集合そのもの(トランザクションの内側)であることを利用して、 ExpectedDigest の照合を読み取りと変更の間に割り込みの余地なく行うためである。
func Listen ¶ added in v0.4.0
Listen は addr で待ち受けを開く。addr が unix:// で始まれば Unix ソケット(0600、root 所有)、 それ以外は TCP。warnNonLoopback が真で TCP がループバックでなければ起動ログに警告する。 待ち受けを開くところまでを応答と分けるのは、vpsd が全部の待ち受けを開けてから起動完了の ログを出すため(仕様 10.4 節)。
func ReservedFromServerInfo ¶ added in v1.0.0
func ReservedFromServerInfo(info ServerInfo) proto.Reserved
ReservedFromServerInfo builds the proto.Reserved set a real Batch refuses a listen_port for, from a ServerInfo report of the server's own ports. It mirrors, field for field, how internal/vpsd/vpsd.go builds Daemon.reserved at startup (around opts.WGPort/AdminAddr/ AgentAPIAddr): the WireGuard port is always reserved; the admin API's port is reserved only when AdminAddr parses as host:port (a Unix socket, e.g. the default "unix:///run/wgft/admin.sock", does not reserve a port); the agent API's port comes from AgentAPIPort, which this struct's producers (Daemon.ServerInfo, the admin client's ServerInfo) already return net.SplitHostPort'd (an empty or unparseable value reserves nothing for it, the same as a net.SplitHostPort failure in vpsd.go).
Both `rule add`/`rule set --dry-run` (cmd/wgft/rule.go) and the Web UI's read-import confirmation (webui_import.go's importIssues) call this function so the reserved-port rule cannot drift between the two callers the way it once did (design.md's revision record, --dry-run entry): the CLI reconstructed the rule from ServerInfo on its own, the Web UI passed nil, and only the CLI's copy was ever fixed to match Daemon.reserved.
func ServeListener ¶ added in v0.4.0
ServeListener は Listen で開いた待ち受けで応答を続ける。ln が Unix ソケットなら期限を付けない (相手は root か、その root に入れる人に限られる)。TCP なら defaultAdminTCPTimeouts を付ける。
Types ¶
type AgentChangeError ¶ added in v1.2.0
AgentChangeError は、エージェントの無効化と有効化が 422 で終わる 2 つの場合を表す (設計文書 5.1、7a.11 節)。Saved が false なら有効化の書き込みの時の検査が拒み、何も保存していない。 true なら保存は済んだが、dataplane への公開に失敗した。server の 30 秒ごとの再試行が公開する。 管理用 API は Saved を応答の本文の saved として返し、Client はそれをこの型に戻す。
func (*AgentChangeError) Error ¶ added in v1.2.0
func (e *AgentChangeError) Error() string
func (*AgentChangeError) Unwrap ¶ added in v1.2.0
func (e *AgentChangeError) Unwrap() error
type AgentDisabledResponse ¶ added in v1.2.0
type AgentDisabledResponse struct {
Name string `json:"name"`
// Disabled は操作の後の状態。
Disabled bool `json:"disabled"`
// Changed は状態が変わったか。変わったときだけ世代が進む。
Changed bool `json:"changed"`
// Generation は操作の後の世代。
Generation uint64 `json:"generation"`
}
AgentDisabledResponse は、エージェントの無効化と有効化(POST /api/v1/agents/{name}/disable と /enable)の成功の応答である(設計文書 5.1、7a.11 節)。状態が変わらない操作も成功で、Changed が false になる。
type AgentRuleStatus ¶ added in v0.6.0
type AgentRuleStatus = adminapi.AgentRuleStatus
AgentRuleStatus is one rule's agent-side status (design.md 5.2, 7a.11 節). 宣言は internal/vpsd/adminapi にあり、その型の説明もそこにある。ここは別名である (design.md 10.2d 節。admin.go の別名と同じ理由である)。
type AgentRuleStatusBackend ¶ added in v0.6.0
type AgentRuleStatusBackend interface {
// AgentRuleStatuses returns an entry for every one of rules, by rule ID - never fewer, since an
// absent id would be indistinguishable from omitting the whole field (see AgentRuleStatus). rules
// is the rule set already read for this response (getRules/postBatch pass resp.Rules), so this
// needs no store read of its own.
//
// A rule's status comes only from its OWN agent (r.Agent), never from a different agent that
// happens to also list the same rule ID in a stale cached heartbeat. This matters because a
// disconnected agent keeps its last heartbeat's content (design.md 5.2 節): if a rule moves from
// agent A to agent B while A is offline, or is deleted while its agent is offline, A's old
// heartbeat can still list that rule ID. Looking it up by the rule's current agent, rather than
// scanning every agent that ever mentioned the ID, is what keeps a moved rule showing B's live
// status (not A's stale one) and keeps a deleted rule's ID from appearing at all (it is no longer
// in rules, so it is never looked up).
AgentRuleStatuses(rules []proto.Rule) map[string]AgentRuleStatus
}
AgentRuleStatusBackend is implemented by a Backend that can report every rule's agent-side status. It is a separate interface, like ApplyStatusBackend and ResourceStatusBackend, so the report stays optional: a Backend without it (a fake or demo Backend, e.g.) serves the rules without the added field at all - the only way a consumer can tell "this Backend does not report agent status" apart from "every rule was reported and fine", now that every current rule gets an entry.
type ApplyStatus ¶ added in v0.5.0
type ApplyStatus struct {
DesiredGeneration uint64
ActiveGeneration uint64
Rules map[string]RuleApply
Drift Drift
// LastError is the failure of the last transaction that failed as a whole, or, when it
// published but a repair after the publication failed, that failure (design.md 7a.3 節: 戻れない
// 地点の後の修復). Empty once everything succeeded.
LastError string
}
ApplyStatus is the server's Desired against Active report.
type ApplyStatusBackend ¶ added in v0.5.0
type ApplyStatusBackend interface {
// ApplyStatus returns the report, and false until the first transaction was attempted.
ApplyStatus() (ApplyStatus, bool)
}
ApplyStatusBackend is implemented by a Backend that can report the apply state. It is a separate interface so the report stays optional: a Backend without it serves the rules without the added fields.
type Backend ¶
type Backend interface {
Rules() ([]proto.Rule, error)
Generation() (uint64, error)
// Batch は変更を 1 トランザクションで適用し、成功したら nftables などへ反映する。
Batch(req BatchRequest) (*store.BatchResult, error)
// AgentState はそのエージェントに配る全体状態(stream ができるまでの橋渡しにも使う)。
AgentState(agent string) (*proto.State, error)
// Agents は登録済みのエージェント。
Agents() ([]AgentInfo, error)
// RuleDrops は rule_id → 累積 drop パケット数。
RuleDrops() (map[string]uint64, error)
// JoinString は名前に紐付いた接続文字列を発行する(仕様 5.1 節)。
JoinString(name string) (JoinStringResponse, error)
// Revoke はエージェントを削除する。恒久トークンを使えなくし、ピアとアドレスを回収する(仕様 5.1、11 節)。
Revoke(name string) error
// DisableAgent はエージェントを無効にし、EnableAgent は有効に戻す(仕様 5.1 節)。不明な名前は
// store.ErrAgentNotFound(404)、書き込みの時の検査の拒否と、保存は済んだが公開に失敗した場合は
// *AgentChangeError(422)、それ以外の誤りは 500 になる。
DisableAgent(name string) (AgentDisabledResponse, error)
EnableAgent(name string) (AgentDisabledResponse, error)
// Warnings は窃取検知の警告一覧。
Warnings() ([]Warning, error)
// DismissWarning は警告を消す(管理者が正当と確認したとき。仕様 5.2 節)。ip-mismatch では
// 消した警告の 2 つの IP の組を確認済みとして記録する。
DismissWarning(agent, kind, detail string) error
// IPMismatchAcks は ip-mismatch の確認済みの組を全エージェント分返す(仕様 5.2 節)。ダッシュボードが
// 1 回の読み取りで使う。管理用 API には出さない。
IPMismatchAcks() ([]store.Ack, error)
// CheckConnectivity は TCP ルールの疎通確認(仕様 10.1 節)。
CheckConnectivity(ruleID string) (ConnCheck, error)
// ServerInfo は vpsd/VPS の構成と環境(ダッシュボード上部に出す)。
ServerInfo() (ServerInfo, error)
}
Backend は API が呼ぶ vpsd 側の操作。
type BatchRequest ¶
type BatchRequest struct {
Upsert []proto.Rule `json:"upsert"` // ID があれば置き換え、なければ追加
Delete []string `json:"delete"` // ID
Force bool `json:"force"` // bind 中のポートとの衝突を無視する
// ExpectedDigest は任意(空なら検査しない、既存の呼び出し元と互換)。指定すると、
// Batch はこのバッチが変更しようとしている今のルール集合の proto.RulesDigest と
// 一致するかを、読み取りと変更を 1 トランザクション/1 ロックの内側で照合する。
// 一致しなければ何も変えず ErrBatchConflict を返す。読み取ってから Batch を呼ぶまでの
// 間に他経路(別の CLI 呼び出しや別タブの Web UI)が割り込む競合を塞ぐためのもの
// (仕様 5.4、10.1 節)。Web UI の読み込み確認・適用はこれを使う(webui_import.go)。
ExpectedDigest string `json:"expected_digest,omitempty"`
// Op はこの変更の出どころ(ログの識別用。例 "ui import"、"cli rule add")。
// 空なら Batch の実装が既定("api")を補う。
Op string `json:"op,omitempty"`
}
BatchRequest はルールの追加・変更・削除をまとめて行う(仕様 5.4 節)。
type Client ¶
Client は CLI が使う管理用 API のクライアント。Base は http://host:port か unix:///path/to.sock(Unix ソケット。既定)。パスワードは持たない(仕様 11 節)。
func (*Client) AgentState ¶
AgentState はそのエージェントに配られる全体状態を取る(確認用)。
func (*Client) Batch ¶
func (c *Client) Batch(req BatchRequest) (*BatchResponse, error)
Batch は追加・変更・削除を 1 トランザクションで適用する(仕様 5.4 節)。
func (*Client) CheckConnectivity ¶
CheckConnectivity は TCP ルールの疎通確認を server に依頼する(仕様 10.1 節)。
func (*Client) DisableAgent ¶ added in v1.2.0
func (c *Client) DisableAgent(name string) (*AgentDisabledResponse, error)
DisableAgent はエージェントを無効にする(仕様 5.1 節)。422 の誤りは *AgentChangeError で、 Saved が保存は済んだが公開していないことを表す。
func (*Client) DismissWarning ¶
DismissWarning は警告を消す。ip-flapping は再検出されれば再び出る。ip-mismatch は消した警告の 2 つの IP の組を server が確認済みとして記録し、同じ組の食い違いが続く間は出さない(仕様 5.2 節)。
func (*Client) EnableAgent ¶ added in v1.2.0
func (c *Client) EnableAgent(name string) (*AgentDisabledResponse, error)
EnableAgent はエージェントを有効に戻す(仕様 5.1 節)。422 の誤りは *AgentChangeError で、 Saved が false なら書き込みの時の検査が拒み、何も保存していない。
func (*Client) JoinString ¶
func (c *Client) JoinString(name string) (*JoinStringResponse, error)
JoinString は名前に紐付いた接続文字列を発行する(仕様 5.1 節)。
func (*Client) ServerInfo ¶ added in v0.7.0
func (c *Client) ServerInfo() (*ServerInfo, error)
ServerInfo は vpsd/VPS の構成と環境を取る(仕様 10.1 節)。`rule add`/`rule set` の `--dry-run` はこれを使って proto.Reserved を組み立て、実際の Batch が拒む予約ポートと 同じ判定にする(design.md 11a 節)。
type Drift ¶ added in v0.5.0
Drift lists what is forwarded although the declaration no longer asks for it.
type DriftResource ¶ added in v0.5.0
type DriftResource = adminapi.DriftResource
DriftResource is one forwarding resource that differs from the declaration.
type ErrorBody ¶
type ErrorBody struct {
Error string `json:"error"`
// Saved は、エージェントの無効化と有効化(POST /api/v1/agents/{name}/disable と /enable)の
// 失敗の応答(404、422、500)だけが持つ(設計文書 7a.11 節)。true は、変更をサーバのデータベースに
// 保存したが、まだ公開していないことを表す(422)。false は何も保存していないことを表す。
// 他のルートの失敗では省く。
Saved *bool `json:"saved,omitempty"`
}
ErrorBody は失敗時の本文。
type FlowBudget ¶ added in v0.5.0
type FlowBudget = adminapi.FlowBudget
FlowBudget is Resource Guard's process-wide flow budget for one protocol (design.md 7a.10 節 「共有プールと隔離予約」). 宣言は internal/vpsd/adminapi にあり、ここは別名である (design.md 10.2d 節。admin.go の別名と同じ理由である)。
type IPForwardBackend ¶ added in v1.2.0
type IPForwardBackend interface {
// IPForward reads the sysctl now. ok is false when this server does not forward through the
// kernel, so the value would say nothing about its rules.
IPForward() (status IPForwardStatus, ok bool)
}
IPForwardBackend is implemented by a Backend that forwards through the kernel and so depends on net.ipv4.ip_forward (design.md 6.1、10.2a 節). It is optional like UDPReplyBackend: a Backend without it, and a userspace-mode server, serve the rules without ip_forward.
type IPForwardStatus ¶ added in v1.2.0
type IPForwardStatus = adminapi.IPForwardStatus
IPForwardStatus is net.ipv4.ip_forward as the server read it (design.md 6.1、10.2a 節). 宣言は internal/vpsd/adminapi にある。
type JoinStringRequest ¶
type JoinStringRequest struct {
Name string `json:"name"`
}
JoinStringRequest / JoinStringResponse は接続文字列の発行。
type JoinStringResponse ¶
type JoinStringResponse struct {
JoinString string `json:"join_string"`
ExpiresAt string `json:"expires_at"`
}
JoinStringResponse は接続文字列の発行結果。ExpiresAt は RFC 3339。
type ResourceStatus ¶ added in v0.5.0
type ResourceStatus struct {
// FlowBudget is keyed by protocol ("udp", "tcp"). Kernel mode server has no entry for "udp":
// kernel mode counts UDP through nftables/conntrack, not through a resource.Pool.
FlowBudget map[proto.Proto]FlowBudget
// Refusals is keyed by rule ID, then by reason. A rule of a protocol/forwarding combination that
// Go never judges (a Transparent rule in kernel mode) never appears here, since no resource.Pool
// ever sees it (design.md 7a.10 節「kernel 側の保護」).
Refusals map[string]map[string]uint64
}
ResourceStatus is Resource Guard's report (design.md 7a.10 節「拒否の報告」): the process-wide flow budget by protocol, and the admission refusals accumulated since the process started, by rule ID and reason. Reasons are "budget", "rule_cap" and "reserve" (internal/resource.Reason); a rule or reason that never triggered a refusal is simply absent from the map, not present with a zero count, matching internal/resource.Pool.Refusals. Not persisted across restarts.
type ResourceStatusBackend ¶ added in v0.5.0
type ResourceStatusBackend interface {
ResourceStatus() ResourceStatus
}
ResourceStatusBackend is implemented by a Backend that can report Resource Guard's status. It is a separate interface, like ApplyStatusBackend, so the report stays optional: a Backend without it (a fake or demo Backend, e.g.) serves the rules without the added fields.
type RuleApply ¶ added in v0.5.0
RuleApply is one rule's apply state on the server's data plane (design.md 7a.3 節).
type Server ¶
type Server struct {
// AllowedHosts は localhost / 127.0.0.1 / [::1] に加えて許可する Host(--admin-host)。
// 応答を始める前に決め、以後は変えない。
AllowedHosts []string
// contains filtered or unexported fields
}
Server は管理用 API の HTTP ハンドラ。
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP は防御的なヘッダを付けたうえで、Host と Origin の検査(仕様 11 節)を通してから mux に渡す。
func (*Server) SetTailnetHosts ¶ added in v1.2.0
SetTailnetHosts は Host の検査で許可する tailnet の IP と名前を差し替える(設計文書 11 節)。 応答の最中に呼んでよい。
type ServerInfo ¶
type ServerInfo struct {
Version string `json:"version"`
Mode string `json:"mode"` // 転送方式 kernel / userspace(仕様 9・11a 節)
StartedAt string `json:"started_at"`
WGInterface string `json:"wg_interface"`
WGAddress string `json:"wg_address"`
WGPort int `json:"wg_port"`
WGEndpoint string `json:"wg_endpoint"`
AgentAPIPort string `json:"agent_api_port"`
AdminAddr string `json:"admin_addr"`
MTU int `json:"mtu"`
ServerPubKey string `json:"server_public_key"`
Kernel string `json:"kernel"`
NFT string `json:"nft"`
IPForwardSetAt string `json:"ip_forward_set_at"`
UDPTimeout int `json:"udp_timeout"`
UDPTimeoutStream int `json:"udp_timeout_stream"`
// IPForward は net.ipv4.ip_forward の今の値("1" か "0")で、読めなければ省く(仕様 6.1、10.1 節)。
// v1 への加算である。IPForwardSetAt は wgft が起動時に 0 から 1 にした記録であり、今の値ではない。
IPForward string `json:"ip_forward,omitempty"`
}
ServerInfo は vpsd 自身と VPS 環境の情報(仕様 10.1)。
type TunnelStatus ¶ added in v0.6.0
type TunnelStatus = adminapi.TunnelStatus
TunnelStatus is the tunnel status as `agent ls`/the admin API show it (design.md 5.2、7a.11 節). 宣言は internal/vpsd/adminapi にあり、ここは別名である(design.md 10.2d 節。admin.go の別名と 同じ理由である)。
func TunnelStatusView ¶ added in v0.6.0
func TunnelStatusView(t proto.TunnelStatus) TunnelStatus
TunnelStatusView converts the wire type to the admin API's view (design.md 7a.11 節). The wire type itself is left untouched; only this rendering changes. Exported for internal/vpsd, which builds AgentInfo from the heartbeat's proto.TunnelStatus.
type UDPReply ¶ added in v1.2.0
UDPReply is what the server has seen of one UDP rule's replies (design.md 10.2a 節「UDP の応答の 観測」、7a.11 節). 宣言は internal/vpsd/adminapi にある。
type UDPReplyBackend ¶ added in v1.2.0
type UDPReplyBackend interface {
// UDPReplies returns an entry for each of rules that is an enabled UDP rule the server
// publishes now, by rule ID. ok is false when the server does not observe replies at all.
UDPReplies(rules []proto.Rule) (replies map[string]UDPReply, ok bool)
}
UDPReplyBackend is implemented by a Backend that observes its UDP rules' replies. It is optional like AgentRuleStatusBackend: a Backend without it (fakeBackend, tools/uidemo) serves the rules without udp_replies.