feat: 通道组——一次开放多台主机 / 多个端口,共用邀请与授权
- 批量创建:主机支持 IP、主机名、末段范围(10.0.1.11-13)和 主机:端口, 与端口列表展开为 主机 × 端口,自动分配连续的访问端口,创建前可预览 - 授权以组为单位:一条邀请链接、一次审批即可访问组内全部地址; 计时从首次连上任一地址开始,撤销一次全组断开;后加入组的通道自动获得组授权 - 网关授权状态按作用范围(通道 / 通道组)存储,通道的动态白名单统一由状态库重新计算, 通道授权与组授权互不干扰;组内最后一个通道关闭或组被解散时,组的邀请与授权失效 - 闲置联动:组内任一地址在用时整组都不算闲置;支持整组开关 - 已有通道可并入组或移出组;组可改名、追加目标、解散(保留或删除成员) - App 与网页面板:组卡片、新建 / 编辑通道组、组邀请与“连接与授权”,授权页列出全部地址 - 测试:网关 9 个、Agent 5 个通道组用例
This commit is contained in:
1 parent
86e159b3f0
commit
3797bef88a
22 files changed
+3894
-471
No files matched your search
@@ -17,6 +17,7 @@ const (
|
||||
TypeInviteResp = "invite_resp"
|
||||
TypeRevokeInvite = "revoke_invite"
|
||||
TypeDecideRequest = "decide_request"
|
||||
TypeDeleteGroup = "delete_group"
|
||||
TypeMetrics = "metrics_update"
|
||||
TypePing = "ping"
|
||||
TypePong = "pong"
|
||||
@@ -68,6 +69,10 @@ type TunnelConfig struct {
|
||||
Notes string `json:"notes,omitempty"`
|
||||
LeaseDuration string `json:"lease_duration,omitempty"` // 已废弃:放通时长改为在每个邀请上设置,保留字段仅为兼容旧配置
|
||||
RequireApproval bool `json:"require_approval,omitempty"` // 已废弃:是否审批改为在每个邀请上设置,保留字段仅为兼容旧配置
|
||||
// GroupID 所属通道组:组内通道共用邀请、授权与审批,闲置计时联动
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
// GroupName 由 Agent 同步到服务端时填写,用于授权页展示(不持久化)
|
||||
GroupName string `json:"group_name,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterTunnelMessage registers a tunnel on server
|
||||
@@ -110,13 +115,21 @@ type KillConnMessage struct {
|
||||
ConnID string `json:"conn_id"`
|
||||
}
|
||||
|
||||
// RevokeLeaseMessage removes a temporary (web-auth) whitelist lease; empty IP revokes all leases of the tunnel
|
||||
// RevokeLeaseMessage removes a temporary (web-auth) whitelist lease; empty IP revokes all leases of the scope.
|
||||
// 设置 GroupID 时作用于整个通道组的授权(TunnelID 忽略),下同。
|
||||
type RevokeLeaseMessage struct {
|
||||
Type string `json:"type"`
|
||||
TunnelID string `json:"tunnel_id"`
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteGroupMessage drops the invites, leases and requests of a dissolved tunnel group
|
||||
type DeleteGroupMessage struct {
|
||||
Type string `json:"type"`
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// Lease durations (Invite.LeaseDuration):通过邀请获得授权后可访问多久
|
||||
const (
|
||||
LeaseDuration1h = "1h"
|
||||
@@ -185,10 +198,11 @@ type Invite struct {
|
||||
Uses []InviteUse `json:"uses,omitempty"`
|
||||
}
|
||||
|
||||
// AccessRequest is an access application on a tunnel that requires approval
|
||||
// AccessRequest is an access application on a tunnel (or tunnel group) that requires approval
|
||||
type AccessRequest struct {
|
||||
ID string `json:"id"`
|
||||
TunnelID string `json:"tunnel_id"`
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
IP string `json:"ip"`
|
||||
Invite string `json:"invite,omitempty"`
|
||||
@@ -201,6 +215,7 @@ type CreateInviteMessage struct {
|
||||
Type string `json:"type"`
|
||||
RequestID string `json:"request_id"`
|
||||
TunnelID string `json:"tunnel_id"`
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
ValidMinutes int `json:"valid_minutes"`
|
||||
MaxUses int `json:"max_uses"`
|
||||
@@ -223,6 +238,7 @@ type InviteRespMessage struct {
|
||||
type RevokeInviteMessage struct {
|
||||
Type string `json:"type"`
|
||||
TunnelID string `json:"tunnel_id"`
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
@@ -230,6 +246,7 @@ type RevokeInviteMessage struct {
|
||||
type DecideRequestMessage struct {
|
||||
Type string `json:"type"`
|
||||
TunnelID string `json:"tunnel_id"`
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
RequestID string `json:"request_id"`
|
||||
Approve bool `json:"approve"`
|
||||
}
|
||||
@@ -279,6 +296,14 @@ type TunnelMetrics struct {
|
||||
Pending []AccessRequest `json:"pending,omitempty"`
|
||||
}
|
||||
|
||||
// GroupMetrics carries the access state shared by all tunnels of a group
|
||||
type GroupMetrics struct {
|
||||
GroupID string `json:"group_id"`
|
||||
DynamicLeases []DynamicLease `json:"dynamic_leases,omitempty"`
|
||||
Invites []Invite `json:"invites,omitempty"`
|
||||
Pending []AccessRequest `json:"pending,omitempty"`
|
||||
}
|
||||
|
||||
// SecurityEvent records blocked or flagged connection attempts
|
||||
type SecurityEvent struct {
|
||||
ID string `json:"id"`
|
||||
@@ -293,6 +318,7 @@ type SecurityEvent struct {
|
||||
type MetricsMessage struct {
|
||||
Type string `json:"type"`
|
||||
Tunnels []TunnelMetrics `json:"tunnels"`
|
||||
Groups []GroupMetrics `json:"groups,omitempty"`
|
||||
ActiveConns []ActiveConnInfo `json:"active_conns"`
|
||||
SecurityEvents []SecurityEvent `json:"security_events,omitempty"`
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user