diff --git a/adapter/client.go b/adapter/client.go index 340fdae..b1d16b7 100644 --- a/adapter/client.go +++ b/adapter/client.go @@ -34,20 +34,30 @@ type Proxy struct { Path string // For HTTP/HTTPS ServiceName string // For gRPC // Shadowsocks Options - Method string - ServerKey string // For Shadowsocks 2022 + Method string + ServerKey string // For Shadowsocks 2022 + Plugin string // Plugin for Shadowsocks + PluginOptions string // Plugin options for Shadowsocks // Vmess/Vless/Trojan Options Flow string // Flow for Vmess/Vless/Trojan // Hysteria2 Options HopPorts string // Comma-separated list of hop ports HopInterval int // Interval for hop ports in seconds ObfsPassword string // Obfuscation password for Hysteria2 + UpMbps int // Upload speed in Mbps + DownMbps int // Download speed in Mbps // Tuic Options DisableSNI bool // Disable SNI ReduceRtt bool // Reduce RTT UDPRelayMode string // UDP relay mode (e.g., "full", "partial") CongestionController string // Congestion controller (e.g., "cubic", "bbr") + + // AnyTLS + PaddingScheme string + + // Mieru + Multiplex string } type User struct { diff --git a/apis/admin/server.api b/apis/admin/server.api index 7502feb..cd73404 100644 --- a/apis/admin/server.api +++ b/apis/admin/server.api @@ -45,33 +45,6 @@ type ( CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` } - Protocol { - Type string `json:"type"` - Port uint16 `json:"port"` - Security string `json:"security,omitempty"` - SNI string `json:"sni,omitempty"` - AllowInsecure bool `json:"allow_insecure,omitempty"` - Fingerprint string `json:"fingerprint,omitempty"` - RealityServerAddr string `json:"reality_server_addr,omitempty"` - RealityServerPort int `json:"reality_server_port,omitempty"` - RealityPrivateKey string `json:"reality_private_key,omitempty"` - RealityPublicKey string `json:"reality_public_key,omitempty"` - RealityShortId string `json:"reality_short_id,omitempty"` - Transport string `json:"transport,omitempty"` - Host string `json:"host,omitempty"` - Path string `json:"path,omitempty"` - ServiceName string `json:"service_name,omitempty"` - Cipher string `json:"cipher,omitempty"` - ServerKey string `json:"server_key,omitempty"` - Flow string `json:"flow,omitempty"` - HopPorts string `json:"hop_ports,omitempty"` - HopInterval int `json:"hop_interval,omitempty"` - ObfsPassword string `json:"obfs_password,omitempty"` - DisableSNI bool `json:"disable_sni,omitempty"` - ReduceRtt bool `json:"reduce_rtt,omitempty"` - UDPRelayMode string `json:"udp_relay_mode,omitempty"` - CongestionController string `json:"congestion_controller,omitempty"` - } CreateServerRequest { Name string `json:"name"` Country string `json:"country,omitempty"` diff --git a/apis/node/node.api b/apis/node/node.api index e8f95ca..2952162 100644 --- a/apis/node/node.api +++ b/apis/node/node.api @@ -93,6 +93,13 @@ type ( ServerCommon Users []OnlineUser `json:"users"` } + QueryServerConfigRequest { + ServerID int64 `path:"server_id"` + SecretKey string `header:"secret_key"` + } + QueryServerConfigResponse { + Protocols []Protocol `json:"protocols"` + } ) @server ( @@ -122,3 +129,13 @@ service ppanel { post /online (OnlineUsersRequest) } +@server ( + prefix: v2/server + group: server +) +service ppanel { + @doc "Get Server Protocol Config" + @handler QueryServerProtocolConfig + get /:server_id (QueryServerConfigRequest) returns (QueryServerConfigResponse) +} + diff --git a/apis/types.api b/apis/types.api index d80da2a..df800b2 100644 --- a/apis/types.api +++ b/apis/types.api @@ -769,5 +769,38 @@ type ( OrderNo string `json:"order_no"` Timestamp int64 `json:"timestamp"` } + Protocol { + Type string `json:"type"` + Port uint16 `json:"port"` + Security string `json:"security,omitempty"` + SNI string `json:"sni,omitempty"` + AllowInsecure bool `json:"allow_insecure,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + RealityServerAddr string `json:"reality_server_addr,omitempty"` + RealityServerPort int `json:"reality_server_port,omitempty"` + RealityPrivateKey string `json:"reality_private_key,omitempty"` + RealityPublicKey string `json:"reality_public_key,omitempty"` + RealityShortId string `json:"reality_short_id,omitempty"` + Transport string `json:"transport,omitempty"` + Host string `json:"host,omitempty"` + Path string `json:"path,omitempty"` + ServiceName string `json:"service_name,omitempty"` + Cipher string `json:"cipher,omitempty"` + ServerKey string `json:"server_key,omitempty"` + Flow string `json:"flow,omitempty"` + HopPorts string `json:"hop_ports,omitempty"` + HopInterval int `json:"hop_interval,omitempty"` + ObfsPassword string `json:"obfs_password,omitempty"` + DisableSNI bool `json:"disable_sni,omitempty"` + ReduceRtt bool `json:"reduce_rtt,omitempty"` + UDPRelayMode string `json:"udp_relay_mode,omitempty"` + CongestionController string `json:"congestion_controller,omitempty"` + Plugin string `json:"plugin,omitempty"` // obfs, v2ray-plugin, simple-obfs + PluginOptions string `json:"plugin_options,omitempty"` // plugin options, eg: obfs=http;obfs-host=www.bing.com + Multiplex string `json:"multiplex,omitempty"` // mux, eg: off/low/medium/high + PaddingScheme string `json:"padding_scheme,omitempty"` // padding scheme + UpMbps int `json:"up_mbps,omitempty"` // upload speed limit + DownMbps int `json:"down_mbps,omitempty"` // download speed limit + } ) diff --git a/internal/handler/routes.go b/internal/handler/routes.go index f236d73..860b885 100644 --- a/internal/handler/routes.go +++ b/internal/handler/routes.go @@ -842,4 +842,11 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) { // Get user list serverGroupRouter.GET("/user", server.GetServerUserListHandler(serverCtx)) } + + serverV2GroupRouter := router.Group("/v2/server") + + { + // Get Server Protocol Config + serverV2GroupRouter.GET("/:server_id", server.QueryServerProtocolConfigHandler(serverCtx)) + } } diff --git a/internal/handler/server/queryServerProtocolConfigHandler.go b/internal/handler/server/queryServerProtocolConfigHandler.go new file mode 100644 index 0000000..1514efa --- /dev/null +++ b/internal/handler/server/queryServerProtocolConfigHandler.go @@ -0,0 +1,41 @@ +package server + +import ( + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/perfect-panel/server/internal/logic/server" + "github.com/perfect-panel/server/internal/svc" + "github.com/perfect-panel/server/internal/types" + "github.com/perfect-panel/server/pkg/logger" + "github.com/perfect-panel/server/pkg/result" +) + +// QueryServerProtocolConfigHandler Get Server Protocol Config +func QueryServerProtocolConfigHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { + return func(c *gin.Context) { + var req types.QueryServerConfigRequest + + serverID, err := strconv.ParseInt(c.Param("server_id"), 10, 64) + if err != nil { + logger.Debugf("[QueryServerProtocolConfigHandler] - strconv.ParseInt(server_id) error: %v, Param: %s", err, c.Param("server_id")) + c.String(http.StatusBadRequest, "Invalid Params") + c.Abort() + return + } + req.ServerID = serverID + + key := c.GetHeader("secret_key") + if key == "" || key != svcCtx.Config.Node.NodeSecret { + logger.Debugf("[QueryServerProtocolConfigHandler] - secret_key error: %s", key) + c.String(http.StatusUnauthorized, "Unauthorized") + c.Abort() + return + } + + l := server.NewQueryServerProtocolConfigLogic(c.Request.Context(), svcCtx) + resp, err := l.QueryServerProtocolConfig(&req) + result.HttpResult(c, resp, err) + } +} diff --git a/internal/logic/admin/server/getServerProtocolsLogic.go b/internal/logic/admin/server/getServerProtocolsLogic.go index 79b4007..66519d9 100644 --- a/internal/logic/admin/server/getServerProtocolsLogic.go +++ b/internal/logic/admin/server/getServerProtocolsLogic.go @@ -6,6 +6,9 @@ import ( "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/pkg/logger" + "github.com/perfect-panel/server/pkg/tool" + "github.com/perfect-panel/server/pkg/xerr" + "github.com/pkg/errors" ) type GetServerProtocolsLogic struct { @@ -24,7 +27,23 @@ func NewGetServerProtocolsLogic(ctx context.Context, svcCtx *svc.ServiceContext) } func (l *GetServerProtocolsLogic) GetServerProtocols(req *types.GetServerProtocolsRequest) (resp *types.GetServerProtocolsResponse, err error) { - // todo: add your logic here and delete this line + // find server + data, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.Id) + if err != nil { + l.Errorf("[GetServerProtocols] FindOneServer Error: %s", err.Error()) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[GetServerProtocols] FindOneServer Error: %s", err.Error()) + } - return + // handler protocols + var protocols []types.Protocol + dst, err := data.UnmarshalProtocols() + if err != nil { + l.Errorf("[FilterServerList] UnmarshalProtocols Error: %s", err.Error()) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[FilterServerList] UnmarshalProtocols Error: %s", err.Error()) + } + tool.DeepCopy(&protocols, dst) + + return &types.GetServerProtocolsResponse{ + Protocols: protocols, + }, nil } diff --git a/internal/logic/server/queryServerProtocolConfigLogic.go b/internal/logic/server/queryServerProtocolConfigLogic.go new file mode 100644 index 0000000..6322959 --- /dev/null +++ b/internal/logic/server/queryServerProtocolConfigLogic.go @@ -0,0 +1,47 @@ +package server + +import ( + "context" + + "github.com/perfect-panel/server/internal/svc" + "github.com/perfect-panel/server/internal/types" + "github.com/perfect-panel/server/pkg/logger" + "github.com/perfect-panel/server/pkg/tool" +) + +type QueryServerProtocolConfigLogic struct { + logger.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// NewQueryServerProtocolConfigLogic Get Server Protocol Config +func NewQueryServerProtocolConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServerProtocolConfigLogic { + return &QueryServerProtocolConfigLogic{ + Logger: logger.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *QueryServerProtocolConfigLogic) QueryServerProtocolConfig(req *types.QueryServerConfigRequest) (resp *types.QueryServerConfigResponse, err error) { + // find server + data, err := l.svcCtx.NodeModel.FindOneServer(l.ctx, req.ServerID) + if err != nil { + l.Errorf("[GetServerProtocols] FindOneServer Error: %s", err.Error()) + return nil, err + } + + // handler protocols + var protocols []types.Protocol + dst, err := data.UnmarshalProtocols() + if err != nil { + l.Errorf("[FilterServerList] UnmarshalProtocols Error: %s", err.Error()) + return nil, err + } + tool.DeepCopy(&protocols, dst) + + return &types.QueryServerConfigResponse{ + Protocols: protocols, + }, nil +} diff --git a/internal/model/node/server.go b/internal/model/node/server.go index ef230a7..9f6d401 100644 --- a/internal/model/node/server.go +++ b/internal/model/node/server.go @@ -126,6 +126,12 @@ type Protocol struct { ReduceRtt bool `json:"reduce_rtt,omitempty"` UDPRelayMode string `json:"udp_relay_mode,omitempty"` CongestionController string `json:"congestion_controller,omitempty"` + Plugin string `json:"plugin,omitempty"` // obfs, v2ray-plugin, simple-obfs + PluginOptions string `json:"plugin_options,omitempty"` // plugin options, eg: obfs=http;obfs-host=www.bing.com + Multiplex string `json:"multiplex,omitempty"` // mux, eg: off/low/medium/high + PaddingScheme string `json:"padding_scheme,omitempty"` // padding scheme + UpMbps int `json:"up_mbps,omitempty"` // upload speed limit + DownMbps int `json:"down_mbps,omitempty"` // download speed limit } // Marshal protocol to json diff --git a/internal/types/types.go b/internal/types/types.go index abe6c33..8d4766e 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -1448,6 +1448,12 @@ type Protocol struct { ReduceRtt bool `json:"reduce_rtt,omitempty"` UDPRelayMode string `json:"udp_relay_mode,omitempty"` CongestionController string `json:"congestion_controller,omitempty"` + Plugin string `json:"plugin,omitempty"` // obfs, v2ray-plugin, simple-obfs + PluginOptions string `json:"plugin_options,omitempty"` // plugin options, eg: obfs=http;obfs-host=www.bing.com + Multiplex string `json:"multiplex,omitempty"` // mux, eg: off/low/medium/high + PaddingScheme string `json:"padding_scheme,omitempty"` // padding scheme + UpMbps int `json:"up_mbps,omitempty"` // upload speed limit + DownMbps int `json:"down_mbps,omitempty"` // download speed limit } type PubilcRegisterConfig struct { @@ -1566,6 +1572,15 @@ type QueryQuotaTaskStatusResponse struct { Errors string `json:"errors"` } +type QueryServerConfigRequest struct { + ServerID int64 `path:"server_id"` + SecretKey string `header:"secret_key"` +} + +type QueryServerConfigResponse struct { + Protocols []Protocol `json:"protocols"` +} + type QuerySubscribeGroupListResponse struct { List []SubscribeGroup `json:"list"` Total int64 `json:"total"`