From 8cd325d796290500152c9882a000414f5ee8d498 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Wed, 16 Oct 2024 08:58:38 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=92=8C=E5=90=AF=E5=8A=A8=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 42 ++++++++++++++-------- build/client/Dockerfile | 4 +++ build/server/Dockerfile | 4 +++ cmd/{frpc => router-client}/main.go | 2 +- cmd/{frpc => router-client}/sub/admin.go | 0 cmd/{frpc => router-client}/sub/nathole.go | 0 cmd/{frpc => router-client}/sub/proxy.go | 0 cmd/{frpc => router-client}/sub/root.go | 0 cmd/{frpc => router-client}/sub/verify.go | 0 cmd/{frps => router-server}/main.go | 0 cmd/{frps => router-server}/root.go | 2 +- cmd/{frps => router-server}/verify.go | 0 12 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 build/client/Dockerfile create mode 100644 build/server/Dockerfile rename cmd/{frpc => router-client}/main.go (94%) rename cmd/{frpc => router-client}/sub/admin.go (100%) rename cmd/{frpc => router-client}/sub/nathole.go (100%) rename cmd/{frpc => router-client}/sub/proxy.go (100%) rename cmd/{frpc => router-client}/sub/root.go (100%) rename cmd/{frpc => router-client}/sub/verify.go (100%) rename cmd/{frps => router-server}/main.go (100%) rename cmd/{frps => router-server}/root.go (97%) rename cmd/{frps => router-server}/verify.go (100%) diff --git a/Makefile b/Makefile index 603aeabd97e..8074dae10d4 100644 --- a/Makefile +++ b/Makefile @@ -4,17 +4,17 @@ LDFLAGS := -s -w all: env fmt build -build: frps frpc +build: router-server router-client env: @go version # compile assets into binary file file: - rm -rf ./assets/frps/static/* - rm -rf ./assets/frpc/static/* - cp -rf ./web/frps/dist/* ./assets/frps/static - cp -rf ./web/frpc/dist/* ./assets/frpc/static + rm -rf ./assets/router-server/static/* + rm -rf ./assets/router-client/static/* + cp -rf ./web/router-server/dist/* ./assets/router-server/static + cp -rf ./web/router-client/dist/* ./assets/router-client/static fmt: go fmt ./... @@ -28,11 +28,11 @@ gci: vet: go vet ./... -frps: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -tags frps -o bin/frps ./cmd/frps +router-server: + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-server ./cmd/router-server -frpc: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -tags frpc -o bin/frpc ./cmd/frpc +router-client: + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-client ./cmd/router-client test: gotest @@ -49,23 +49,35 @@ e2e: e2e-trace: DEBUG=true LOG_LEVEL=trace ./hack/run-e2e.sh -e2e-compatibility-last-frpc: +e2e-compatibility-last-router-client: if [ ! -d "./lastversion" ]; then \ TARGET_DIRNAME=lastversion ./hack/download.sh; \ fi - FRPC_PATH="`pwd`/lastversion/frpc" ./hack/run-e2e.sh + FRPC_PATH="`pwd`/lastversion/router-client" ./hack/run-e2e.sh rm -r ./lastversion -e2e-compatibility-last-frps: +e2e-compatibility-last-router-server: if [ ! -d "./lastversion" ]; then \ TARGET_DIRNAME=lastversion ./hack/download.sh; \ fi - FRPS_PATH="`pwd`/lastversion/frps" ./hack/run-e2e.sh + FRPS_PATH="`pwd`/lastversion/router-server" ./hack/run-e2e.sh rm -r ./lastversion alltest: vet gotest e2e clean: - rm -f ./bin/frpc - rm -f ./bin/frps + rm -f ./bin/router-client + rm -f ./bin/router-server rm -rf ./lastversion + +router-server-images: + docker build . --file build/server/Dockerfile --tag docker.io/zxs943023403/router-server:v0.0.1 + +router-client-images: + docker build . --file build/client/Dockerfile --tag docker.io/zxs943023403/router-client:v0.0.1 + +image-all: router-server-images router-client-images + +docker: + make build + make image-all diff --git a/build/client/Dockerfile b/build/client/Dockerfile new file mode 100644 index 00000000000..3a80bad1dc8 --- /dev/null +++ b/build/client/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine:3.16.2 + +COPY bin/router-client /usr/bin/router-client +ENTRYPOINT ["/usr/bin/router-client"] \ No newline at end of file diff --git a/build/server/Dockerfile b/build/server/Dockerfile new file mode 100644 index 00000000000..f22443d23c6 --- /dev/null +++ b/build/server/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine:3.16.2 + +COPY bin/router-server /usr/bin/router-server +ENTRYPOINT ["/usr/bin/router-server"] \ No newline at end of file diff --git a/cmd/frpc/main.go b/cmd/router-client/main.go similarity index 94% rename from cmd/frpc/main.go rename to cmd/router-client/main.go index f7651bca169..7a7f52bd714 100644 --- a/cmd/frpc/main.go +++ b/cmd/router-client/main.go @@ -16,7 +16,7 @@ package main import ( _ "github.com/fatedier/frp/assets/frpc" - "github.com/fatedier/frp/cmd/frpc/sub" + "github.com/fatedier/frp/cmd/router-client/sub" "github.com/fatedier/frp/pkg/util/system" ) diff --git a/cmd/frpc/sub/admin.go b/cmd/router-client/sub/admin.go similarity index 100% rename from cmd/frpc/sub/admin.go rename to cmd/router-client/sub/admin.go diff --git a/cmd/frpc/sub/nathole.go b/cmd/router-client/sub/nathole.go similarity index 100% rename from cmd/frpc/sub/nathole.go rename to cmd/router-client/sub/nathole.go diff --git a/cmd/frpc/sub/proxy.go b/cmd/router-client/sub/proxy.go similarity index 100% rename from cmd/frpc/sub/proxy.go rename to cmd/router-client/sub/proxy.go diff --git a/cmd/frpc/sub/root.go b/cmd/router-client/sub/root.go similarity index 100% rename from cmd/frpc/sub/root.go rename to cmd/router-client/sub/root.go diff --git a/cmd/frpc/sub/verify.go b/cmd/router-client/sub/verify.go similarity index 100% rename from cmd/frpc/sub/verify.go rename to cmd/router-client/sub/verify.go diff --git a/cmd/frps/main.go b/cmd/router-server/main.go similarity index 100% rename from cmd/frps/main.go rename to cmd/router-server/main.go diff --git a/cmd/frps/root.go b/cmd/router-server/root.go similarity index 97% rename from cmd/frps/root.go rename to cmd/router-server/root.go index fff487d1074..db990def304 100644 --- a/cmd/frps/root.go +++ b/cmd/router-server/root.go @@ -38,7 +38,7 @@ var ( ) func init() { - rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "D:\\gopath\\src\\edgewize.io\\frp\\conf\\test\\server.ini", "config file of frps") rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps") rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", true, "strict config parsing mode, unknown fields will cause errors") diff --git a/cmd/frps/verify.go b/cmd/router-server/verify.go similarity index 100% rename from cmd/frps/verify.go rename to cmd/router-server/verify.go From 8c52e065a11b48038da6d0adb70068bf7b27f754 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Wed, 16 Oct 2024 09:08:10 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=92=8C=E5=90=AF=E5=8A=A8=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/router-server/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/router-server/root.go b/cmd/router-server/root.go index db990def304..fff487d1074 100644 --- a/cmd/router-server/root.go +++ b/cmd/router-server/root.go @@ -38,7 +38,7 @@ var ( ) func init() { - rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "D:\\gopath\\src\\edgewize.io\\frp\\conf\\test\\server.ini", "config file of frps") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps") rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps") rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", true, "strict config parsing mode, unknown fields will cause errors") From 297c5171dea736c38c3c3d5a954c142438ad245a Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Thu, 7 Nov 2024 14:09:25 +0800 Subject: [PATCH 03/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 5 +- build/client/Dockerfile | 1 - build/server/Dockerfile | 1 - client/admin_api.go | 26 ++-- client/service.go | 7 +- client/visitor/stcp.go | 6 + cmd/router-client/sub/root.go | 4 +- conf/test/client | 24 +++ conf/test/edge.ini | 17 +++ conf/test/server.ini | 4 + pkg/auth/auth.go | 2 + pkg/auth/oidc.go | 26 ++++ pkg/auth/pass.go | 4 + pkg/auth/token.go | 25 ++++ pkg/config/legacy/conversion.go | 11 +- pkg/msg/msg.go | 96 ++++++------ pkg/plugin/server/manager.go | 30 ++-- pkg/transport/tls.go | 3 +- pkg/util/net/dial.go | 5 +- pkg/util/net/tls.go | 25 +++- pkg/util/util/util.go | 65 +++++++- pkg/util/vhost/resource.go | 3 +- server/control.go | 4 +- server/dashboard_api.go | 4 +- server/proxy/proxy.go | 2 + server/proxy/sudp.go | 4 +- server/proxy/tcp.go | 3 +- server/proxy/udp.go | 3 +- server/proxy/xtcp.go | 4 +- server/service.go | 253 +++++++++++++++++--------------- 30 files changed, 438 insertions(+), 229 deletions(-) create mode 100644 conf/test/client create mode 100644 conf/test/edge.ini create mode 100644 conf/test/server.ini diff --git a/Makefile b/Makefile index 8074dae10d4..ef592fe5abb 100644 --- a/Makefile +++ b/Makefile @@ -71,13 +71,14 @@ clean: rm -rf ./lastversion router-server-images: - docker build . --file build/server/Dockerfile --tag docker.io/zxs943023403/router-server:v0.0.1 + docker build . --file build/server/Dockerfile --tag $(REPO)/router-server:$(VER) --push router-client-images: - docker build . --file build/client/Dockerfile --tag docker.io/zxs943023403/router-client:v0.0.1 + docker build . --file build/client/Dockerfile --tag $(REPO)/router-client:$(VER) --push image-all: router-server-images router-client-images +# make docker REPO=harbor.dev.thingsdao.com/edgewize VER=v0.1.13 docker: make build make image-all diff --git a/build/client/Dockerfile b/build/client/Dockerfile index 3a80bad1dc8..a243f86b701 100644 --- a/build/client/Dockerfile +++ b/build/client/Dockerfile @@ -1,4 +1,3 @@ FROM alpine:3.16.2 COPY bin/router-client /usr/bin/router-client -ENTRYPOINT ["/usr/bin/router-client"] \ No newline at end of file diff --git a/build/server/Dockerfile b/build/server/Dockerfile index f22443d23c6..9dff7059483 100644 --- a/build/server/Dockerfile +++ b/build/server/Dockerfile @@ -1,4 +1,3 @@ FROM alpine:3.16.2 COPY bin/router-server /usr/bin/router-server -ENTRYPOINT ["/usr/bin/router-server"] \ No newline at end of file diff --git a/client/admin_api.go b/client/admin_api.go index 708b2cbd9e6..dfeac95ef71 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -31,7 +31,6 @@ import ( "github.com/fatedier/frp/pkg/config/v1/validation" httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" - netpkg "github.com/fatedier/frp/pkg/util/net" ) type GeneralResponse struct { @@ -40,26 +39,27 @@ type GeneralResponse struct { } func (svr *Service) registerRouteHandlers(helper *httppkg.RouterRegisterHelper) { - helper.Router.HandleFunc("/healthz", svr.healthz) + //helper.Router.HandleFunc("/healthz", svr.healthz) subRouter := helper.Router.NewRoute().Subrouter() subRouter.Use(helper.AuthMiddleware.Middleware) // api, see admin_api.go + // 取消reload以外的所有开放api subRouter.HandleFunc("/api/reload", svr.apiReload).Methods("GET") - subRouter.HandleFunc("/api/stop", svr.apiStop).Methods("POST") - subRouter.HandleFunc("/api/status", svr.apiStatus).Methods("GET") - subRouter.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET") - subRouter.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT") + //subRouter.HandleFunc("/api/stop", svr.apiStop).Methods("POST") + //subRouter.HandleFunc("/api/status", svr.apiStatus).Methods("GET") + //subRouter.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET") + //subRouter.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT") // view - subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET") - subRouter.PathPrefix("/static/").Handler( - netpkg.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(helper.AssetsFS))), - ).Methods("GET") - subRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/static/", http.StatusMovedPermanently) - }) + //subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET") + //subRouter.PathPrefix("/static/").Handler( + // netpkg.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(helper.AssetsFS))), + //).Methods("GET") + //subRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // http.Redirect(w, r, "/static/", http.StatusMovedPermanently) + //}) } // /healthz diff --git a/client/service.go b/client/service.go index 0cbd8757e84..75a9cf6e2b8 100644 --- a/client/service.go +++ b/client/service.go @@ -34,7 +34,6 @@ import ( httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" netpkg "github.com/fatedier/frp/pkg/util/net" - "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/wait" "github.com/fatedier/frp/pkg/util/xlog" ) @@ -249,7 +248,7 @@ func (svr *Service) login() (conn net.Conn, connector Connector, err error) { Os: runtime.GOOS, PoolCount: svr.common.Transport.PoolCount, User: svr.common.User, - Version: version.Full(), + Version: "edgewize-msg-transport-v1", Timestamp: time.Now().Unix(), RunID: svr.runID, Metas: svr.common.Metadatas, @@ -262,8 +261,10 @@ func (svr *Service) login() (conn net.Conn, connector Connector, err error) { if err = svr.authSetter.SetLogin(loginMsg); err != nil { return } + var cryp = new(msg.CryptoLogin) + svr.authSetter.SetCrypto(cryp, loginMsg) - if err = msg.WriteMsg(conn, loginMsg); err != nil { + if err = msg.WriteMsg(conn, cryp); err != nil { return } diff --git a/client/visitor/stcp.go b/client/visitor/stcp.go index b26faf5200c..43e33e053b9 100644 --- a/client/visitor/stcp.go +++ b/client/visitor/stcp.go @@ -79,6 +79,9 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { xl := xlog.FromContextSafe(sv.ctx) defer userConn.Close() + var head msg.ConnectHead + _ = msg.ReadMsgInto(userConn, &head) + xl.Debugf("get a new stcp user connection") visitorConn, err := sv.helper.ConnectServer() if err != nil { @@ -95,6 +98,9 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { UseEncryption: sv.cfg.Transport.UseEncryption, UseCompression: sv.cfg.Transport.UseCompression, } + if head.ServiceName != "" { + newVisitorConnMsg.ProxyName = head.ServiceName + } err = msg.WriteMsg(visitorConn, newVisitorConnMsg) if err != nil { xl.Warnf("send newVisitorConnMsg to server error: %v", err) diff --git a/cmd/router-client/sub/root.go b/cmd/router-client/sub/root.go index b844ddfd5e9..41c5d700ef7 100644 --- a/cmd/router-client/sub/root.go +++ b/cmd/router-client/sub/root.go @@ -32,7 +32,6 @@ import ( v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/config/v1/validation" "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/pkg/util/version" ) var ( @@ -54,7 +53,8 @@ var rootCmd = &cobra.Command{ Short: "frpc is the client of frp (https://github.com/fatedier/frp)", RunE: func(cmd *cobra.Command, args []string) error { if showVersion { - fmt.Println(version.Full()) + //fmt.Println(version.Full()) + fmt.Println("edgewize-msg-transport-v1") return nil } diff --git a/conf/test/client b/conf/test/client new file mode 100644 index 00000000000..753559a056b --- /dev/null +++ b/conf/test/client @@ -0,0 +1,24 @@ +[common] +server_addr = 172.31.19.39 +server_port = 31716 +log_level=info +token = qingcloud +[demo2-cloud] +type = stcp +sk = I9PR0ojaVGik1alh +local_ip=router-manager.edgewize-system +local_port=8081 +[edge-node52] +type = stcp +sk = I9PR0ojaVGik1alh +role = visitor +server_name = demo2-cloud +bind_addr = 0.0.0.0 +bind_port = 6000 +[edge-node55] +type = stcp +sk = I9PR0ojaVGik1alh +role = visitor +server_name = demo2-cloud +bind_addr = 0.0.0.0 +bind_port = 6000 \ No newline at end of file diff --git a/conf/test/edge.ini b/conf/test/edge.ini new file mode 100644 index 00000000000..9351c562256 --- /dev/null +++ b/conf/test/edge.ini @@ -0,0 +1,17 @@ +[common] +server_addr = 172.27.144.1 +server_port = 7500 +log_level=info +token = qingcloud +[demo2-cloud] +type = stcp +sk = I9PR0ojaVGik1alh +role = visitor +server_name = demo2 +bind_addr = 0.0.0.0 +bind_port = 6000 +[demo2-edge] +type = stcp +sk = NKXjPqrHQRe848 +local_ip=www.baidu.com +local_port=443 \ No newline at end of file diff --git a/conf/test/server.ini b/conf/test/server.ini new file mode 100644 index 00000000000..4740f89d40c --- /dev/null +++ b/conf/test/server.ini @@ -0,0 +1,4 @@ +[common] +bind_port = 7500 +bind_addr = 0.0.0.0 +token = qingcloud \ No newline at end of file diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 9d8db7b686b..a5a2574128c 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -25,6 +25,7 @@ type Setter interface { SetLogin(*msg.Login) error SetPing(*msg.Ping) error SetNewWorkConn(*msg.NewWorkConn) error + SetCrypto(c *msg.CryptoLogin, login *msg.Login) } func NewAuthSetter(cfg v1.AuthClientConfig) (authProvider Setter) { @@ -43,6 +44,7 @@ type Verifier interface { VerifyLogin(*msg.Login) error VerifyPing(*msg.Ping) error VerifyNewWorkConn(*msg.NewWorkConn) error + VerifyCrypto(c *msg.CryptoLogin) *msg.Login } func NewAuthVerifier(cfg v1.AuthServerConfig) (authVerifier Verifier) { diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index d87420ff764..3b7eca20977 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -16,8 +16,12 @@ package auth import ( "context" + "encoding/hex" + "encoding/json" "fmt" + "github.com/fatedier/frp/pkg/util/util" "slices" + "strconv" "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2/clientcredentials" @@ -149,3 +153,25 @@ func (auth *OidcAuthConsumer) VerifyNewWorkConn(newWorkConnMsg *msg.NewWorkConn) return auth.verifyPostLoginToken(newWorkConnMsg.PrivilegeKey) } + +func (auth *OidcAuthProvider) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { + bs, _ := json.Marshal(login) + c.Auth = util.RandomString(16) + key := util.GenerateAesKey(c.Auth)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) +} + +func (auth *OidcAuthConsumer) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + var login *msg.Login + bs, err := hex.DecodeString(c.Sign) + if err != nil { + fmt.Println("verify crypto error,", err) + return nil + } + key := util.GenerateAesKey(c.Auth)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + before := util.Decrypt(bs, key, []byte(iv)) + _ = json.Unmarshal(before, login) + return login +} diff --git a/pkg/auth/pass.go b/pkg/auth/pass.go index 2eaf3f0bd70..ca0b1489046 100644 --- a/pkg/auth/pass.go +++ b/pkg/auth/pass.go @@ -24,6 +24,10 @@ var _ Verifier = &alwaysPass{} type alwaysPass struct{} +func (p *alwaysPass) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + return nil +} + func (*alwaysPass) VerifyLogin(*msg.Login) error { return nil } func (*alwaysPass) VerifyPing(*msg.Ping) error { return nil } diff --git a/pkg/auth/token.go b/pkg/auth/token.go index 9ee993f9d50..982f1cf84b1 100644 --- a/pkg/auth/token.go +++ b/pkg/auth/token.go @@ -15,8 +15,11 @@ package auth import ( + "encoding/hex" + "encoding/json" "fmt" "slices" + "strconv" "time" v1 "github.com/fatedier/frp/pkg/config/v1" @@ -89,3 +92,25 @@ func (auth *TokenAuthSetterVerifier) VerifyNewWorkConn(m *msg.NewWorkConn) error } return nil } + +func (auth *TokenAuthSetterVerifier) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { + bs, _ := json.Marshal(login) + key := util.GenerateAesKey(auth.token)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + c.Auth = util.RandomString(16) + c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) +} + +func (auth *TokenAuthSetterVerifier) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + var login msg.Login + bs, err := hex.DecodeString(c.Sign) + if err != nil { + fmt.Println("verify crypto error,", err) + return nil + } + key := util.GenerateAesKey(auth.token)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + before := util.Decrypt(bs, key, []byte(iv)) + _ = json.Unmarshal(before, &login) + return &login +} diff --git a/pkg/config/legacy/conversion.go b/pkg/config/legacy/conversion.go index dd8c4a11d91..e535793d270 100644 --- a/pkg/config/legacy/conversion.go +++ b/pkg/config/legacy/conversion.go @@ -57,8 +57,10 @@ func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConf out.Transport.QUIC.KeepalivePeriod = conf.QUICKeepalivePeriod out.Transport.QUIC.MaxIdleTimeout = conf.QUICMaxIdleTimeout out.Transport.QUIC.MaxIncomingStreams = conf.QUICMaxIncomingStreams - out.Transport.TLS.Enable = lo.ToPtr(conf.TLSEnable) - out.Transport.TLS.DisableCustomTLSFirstByte = lo.ToPtr(conf.DisableCustomTLSFirstByte) + // 强制开启tls + out.Transport.TLS.Enable = lo.ToPtr(true) + // 强制启用TLS头字符 + out.Transport.TLS.DisableCustomTLSFirstByte = lo.ToPtr(false) out.Transport.TLS.TLSConfig.CertFile = conf.TLSCertFile out.Transport.TLS.TLSConfig.KeyFile = conf.TLSKeyFile out.Transport.TLS.TLSConfig.TrustedCaFile = conf.TLSTrustedCaFile @@ -69,8 +71,9 @@ func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConf out.Log.MaxDays = conf.LogMaxDays out.Log.DisablePrintColor = conf.DisableLogColor - out.WebServer.Addr = conf.AdminAddr - out.WebServer.Port = conf.AdminPort + // 强制开启只监听本地端口的web server + out.WebServer.Addr = "127.0.0.1" + out.WebServer.Port = 2333 out.WebServer.User = conf.AdminUser out.WebServer.Password = conf.AdminPwd out.WebServer.AssetsDir = conf.AssetsDir diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index a6344d08fe3..eaf98dab95e 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -20,24 +20,26 @@ import ( ) const ( - TypeLogin = 'o' - TypeLoginResp = '1' - TypeNewProxy = 'p' - TypeNewProxyResp = '2' - TypeCloseProxy = 'c' - TypeNewWorkConn = 'w' - TypeReqWorkConn = 'r' - TypeStartWorkConn = 's' - TypeNewVisitorConn = 'v' - TypeNewVisitorConnResp = '3' - TypePing = 'h' - TypePong = '4' - TypeUDPPacket = 'u' - TypeNatHoleVisitor = 'i' - TypeNatHoleClient = 'n' - TypeNatHoleResp = 'm' - TypeNatHoleSid = '5' - TypeNatHoleReport = '6' + TypeLogin = 0x01 + TypeLoginResp = 0x02 + TypeNewProxy = 0x03 + TypeNewProxyResp = 0x04 + TypeCloseProxy = 0x05 + TypeNewWorkConn = 0x06 + TypeReqWorkConn = 0x07 + TypeStartWorkConn = 0x08 + TypeNewVisitorConn = 0x09 + TypeNewVisitorConnResp = 0x0a + TypePing = 0x0b + TypePong = 0x0c + TypeUDPPacket = 0x0d + TypeNatHoleVisitor = 0x0e + TypeNatHoleClient = 0x10 + TypeNatHoleResp = 0x11 + TypeNatHoleSid = 0x12 + TypeNatHoleReport = 0x0f + TypeConnHead = 0x13 + TypeCryptoLogin = 0xf8 ) var msgTypeMap = map[byte]interface{}{ @@ -59,6 +61,8 @@ var msgTypeMap = map[byte]interface{}{ TypeNatHoleResp: NatHoleResp{}, TypeNatHoleSid: NatHoleSid{}, TypeNatHoleReport: NatHoleReport{}, + TypeConnHead: ConnectHead{}, + TypeCryptoLogin: CryptoLogin{}, } var TypeNameNatHoleResp = reflect.TypeOf(&NatHoleResp{}).Elem().Name() @@ -69,32 +73,38 @@ type ClientSpec struct { // Optional values: ssh-tunnel Type string `json:"type,omitempty"` // If the value is true, the client will not require authentication. - AlwaysAuthPass bool `json:"always_auth_pass,omitempty"` + AlwaysAuthPass bool `json:"auth_type,omitempty"` +} + +type CryptoLogin struct { + TimeStamp int64 `json:"time_stamp,omitempty"` + Auth string `json:"auth"` + Sign string `json:"sign,omitempty"` } // When frpc start, client send this message to login to server. type Login struct { - Version string `json:"version,omitempty"` - Hostname string `json:"hostname,omitempty"` - Os string `json:"os,omitempty"` - Arch string `json:"arch,omitempty"` - User string `json:"user,omitempty"` - PrivilegeKey string `json:"privilege_key,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - RunID string `json:"run_id,omitempty"` - Metas map[string]string `json:"metas,omitempty"` + Version string `json:"tag,omitempty"` + Hostname string `json:"path,omitempty"` + Os string `json:"system,omitempty"` + Arch string `json:"types,omitempty"` + User string `json:"people,omitempty"` + PrivilegeKey string `json:"identify,omitempty"` + Timestamp int64 `json:"time_second,omitempty"` + RunID string `json:"self_id,omitempty"` + Metas map[string]string `json:"data_bucket,omitempty"` // Currently only effective for VirtualClient. - ClientSpec ClientSpec `json:"client_spec,omitempty"` + ClientSpec ClientSpec `json:"other_data,omitempty"` // Some global configures. - PoolCount int `json:"pool_count,omitempty"` + PoolCount int `json:"count,omitempty"` } type LoginResp struct { - Version string `json:"version,omitempty"` - RunID string `json:"run_id,omitempty"` - Error string `json:"error,omitempty"` + Version string `json:"tag,omitempty"` + RunID string `json:"self_id,omitempty"` + Error string `json:"error_msg,omitempty"` } // When frpc login success, send this message to frps for running a new proxy. @@ -160,17 +170,17 @@ type StartWorkConn struct { } type NewVisitorConn struct { - RunID string `json:"run_id,omitempty"` - ProxyName string `json:"proxy_name,omitempty"` - SignKey string `json:"sign_key,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - UseEncryption bool `json:"use_encryption,omitempty"` - UseCompression bool `json:"use_compression,omitempty"` + RunID string `json:"dog_name,omitempty"` + ProxyName string `json:"cat_name,omitempty"` + SignKey string `json:"elephant_name,omitempty"` + Timestamp int64 `json:"duck_name,omitempty"` + UseEncryption bool `json:"monkey_name,omitempty"` + UseCompression bool `json:"snake_name,omitempty"` } type NewVisitorConnResp struct { - ProxyName string `json:"proxy_name,omitempty"` - Error string `json:"error,omitempty"` + ProxyName string `json:"panda_name,omitempty"` + Error string `json:"something,omitempty"` } type Ping struct { @@ -244,3 +254,7 @@ type NatHoleReport struct { Sid string `json:"sid,omitempty"` Success bool `json:"success,omitempty"` } + +type ConnectHead struct { + ServiceName string `json:"serviceName"` +} diff --git a/pkg/plugin/server/manager.go b/pkg/plugin/server/manager.go index ed96444ac22..b3f66421460 100644 --- a/pkg/plugin/server/manager.go +++ b/pkg/plugin/server/manager.go @@ -48,21 +48,21 @@ func (m *Manager) Register(p Plugin) { if p.IsSupport(OpLogin) { m.loginPlugins = append(m.loginPlugins, p) } - if p.IsSupport(OpNewProxy) { - m.newProxyPlugins = append(m.newProxyPlugins, p) - } - if p.IsSupport(OpCloseProxy) { - m.closeProxyPlugins = append(m.closeProxyPlugins, p) - } - if p.IsSupport(OpPing) { - m.pingPlugins = append(m.pingPlugins, p) - } - if p.IsSupport(OpNewWorkConn) { - m.newWorkConnPlugins = append(m.newWorkConnPlugins, p) - } - if p.IsSupport(OpNewUserConn) { - m.newUserConnPlugins = append(m.newUserConnPlugins, p) - } + //if p.IsSupport(OpNewProxy) { + // m.newProxyPlugins = append(m.newProxyPlugins, p) + //} + //if p.IsSupport(OpCloseProxy) { + // m.closeProxyPlugins = append(m.closeProxyPlugins, p) + //} + //if p.IsSupport(OpPing) { + // m.pingPlugins = append(m.pingPlugins, p) + //} + //if p.IsSupport(OpNewWorkConn) { + // m.newWorkConnPlugins = append(m.newWorkConnPlugins, p) + //} + //if p.IsSupport(OpNewUserConn) { + // m.newUserConnPlugins = append(m.newUserConnPlugins, p) + //} } func (m *Manager) Login(content *LoginContent) (*LoginContent, error) { diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 5bc75921cbd..372748a3894 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -20,6 +20,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/pem" + "fmt" "math/big" "os" ) @@ -108,9 +109,9 @@ func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Conf if err != nil { return nil, err } - base.Certificates = []tls.Certificate{*cert} } + fmt.Println("tls config certificates", certPath, keyPath, base.Certificates) base.ServerName = serverName diff --git a/pkg/util/net/dial.go b/pkg/util/net/dial.go index 1a3859edfa7..6f29200cb9c 100644 --- a/pkg/util/net/dial.go +++ b/pkg/util/net/dial.go @@ -11,8 +11,9 @@ import ( func DialHookCustomTLSHeadByte(enableTLS bool, disableCustomTLSHeadByte bool) libnet.AfterHookFunc { return func(ctx context.Context, c net.Conn, addr string) (context.Context, net.Conn, error) { - if enableTLS && !disableCustomTLSHeadByte { - _, err := c.Write([]byte{byte(FRPTLSHeadByte)}) + if enableTLS { + //_, err := c.Write([]byte{byte(FRPTLSHeadByte)}) + _, err := c.Write(FRPTLSHeadByte) if err != nil { return nil, nil, err } diff --git a/pkg/util/net/tls.go b/pkg/util/net/tls.go index 6645dfaf546..8311b78f72b 100644 --- a/pkg/util/net/tls.go +++ b/pkg/util/net/tls.go @@ -23,13 +23,13 @@ import ( libnet "github.com/fatedier/golib/net" ) -var FRPTLSHeadByte = 0x17 +var FRPTLSHeadByte = []byte{'e', 'd', 'g', 'e', 'w', 'i', 'z', 'e', 't', 'l', 's'} func CheckAndEnableTLSServerConnWithTimeout( c net.Conn, tlsConfig *tls.Config, tlsOnly bool, timeout time.Duration, ) (out net.Conn, isTLS bool, custom bool, err error) { sc, r := libnet.NewSharedConnSize(c, 2) - buf := make([]byte, 1) + buf := make([]byte, len(FRPTLSHeadByte)) var n int _ = c.SetReadDeadline(time.Now().Add(timeout)) n, err = r.Read(buf) @@ -39,13 +39,14 @@ func CheckAndEnableTLSServerConnWithTimeout( } switch { - case n == 1 && int(buf[0]) == FRPTLSHeadByte: + case n == len(FRPTLSHeadByte) && BytesEqual(buf, FRPTLSHeadByte): out = tls.Server(c, tlsConfig) isTLS = true custom = true - case n == 1 && int(buf[0]) == 0x16: - out = tls.Server(sc, tlsConfig) - isTLS = true + // 取消对原版frpc的tls兼容 + //case n == 1 && int(buf[0]) == 0x16: + // out = tls.Server(sc, tlsConfig) + // isTLS = true default: if tlsOnly { err = fmt.Errorf("non-TLS connection received on a TlsOnly server") @@ -55,3 +56,15 @@ func CheckAndEnableTLSServerConnWithTimeout( } return } + +func BytesEqual(a, b []byte) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/pkg/util/util/util.go b/pkg/util/util/util.go index 7758054d948..da44a2372b0 100644 --- a/pkg/util/util/util.go +++ b/pkg/util/util/util.go @@ -15,6 +15,9 @@ package util import ( + "bytes" + "crypto/cipher" + "crypto/des" "crypto/md5" "crypto/rand" "crypto/subtle" @@ -52,7 +55,9 @@ func GetAuthKey(token string, timestamp int64) (key string) { md5Ctx.Write([]byte(token)) md5Ctx.Write([]byte(strconv.FormatInt(timestamp, 10))) data := md5Ctx.Sum(nil) - return hex.EncodeToString(data) + after := hex.EncodeToString(data) + fmt.Println(fmt.Sprintf("token=%s, timestamp=%d,data=%s", token, timestamp, after)) + return after } func CanonicalAddr(host string, port int) (addr string) { @@ -134,3 +139,61 @@ func RandomSleep(duration time.Duration, minRatio, maxRatio float64) time.Durati func ConstantTimeEqString(a, b string) bool { return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1 } + +func Encrypt(src, key string, iv []byte) []byte { + data := []byte(src) + keyByte := []byte(key) + block, err := des.NewCipher(keyByte) + if err != nil { + panic(err) + } + //data = padding.PKCS7Padding(data, block.BlockSize()) + data = PKCS7Padding(data, block.BlockSize()) + mode := cipher.NewCBCEncrypter(block, iv) + out := make([]byte, len(data)) + mode.CryptBlocks(out, data) + return out +} + +func Decrypt(data []byte, key string, iv []byte) []byte { + keyByte := []byte(key) + block, err := des.NewCipher(keyByte) + if err != nil { + panic(err) + } + mode := cipher.NewCBCDecrypter(block, iv) + plaintext := make([]byte, len(data)) + mode.CryptBlocks(plaintext, data) + //plaintext = padding.PKCS5UnPadding(plaintext) + plaintext = PKCS7UnPadding(plaintext, block.BlockSize()) + return plaintext +} + +func PKCS7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +func PKCS7UnPadding(plantText []byte, blockSize int) []byte { + length := len(plantText) + unpadding := int(plantText[length-1]) + return plantText[:(length - unpadding)] +} + +func GenerateAesKey(k string) string { + m := md5.New() + m.Write([]byte(k)) + return hex.EncodeToString(m.Sum(nil)) +} + +var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +func RandomString(length int) string { + result := make([]byte, length) + for i := 0; i < length; i++ { + result[i] = chars[mathrand.IntN(len(chars))] + } + + return string(result) +} diff --git a/pkg/util/vhost/resource.go b/pkg/util/vhost/resource.go index a65e29973ea..f39d00aa1f9 100644 --- a/pkg/util/vhost/resource.go +++ b/pkg/util/vhost/resource.go @@ -21,7 +21,6 @@ import ( "os" "github.com/fatedier/frp/pkg/util/log" - "github.com/fatedier/frp/pkg/util/version" ) var NotFoundPagePath = "" @@ -69,7 +68,7 @@ func getNotFoundPageContent() []byte { func NotFoundResponse() *http.Response { header := make(http.Header) - header.Set("server", "frp/"+version.Full()) + //header.Set("server", "frp/"+version.Full()) header.Set("Content-Type", "text/html") content := getNotFoundPageContent() diff --git a/server/control.go b/server/control.go index 0b6b31741b0..ea9114f35ad 100644 --- a/server/control.go +++ b/server/control.go @@ -34,7 +34,6 @@ import ( "github.com/fatedier/frp/pkg/transport" netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" - "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/wait" "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" @@ -202,7 +201,8 @@ func NewControl( // Start send a login success message to client and start working. func (ctl *Control) Start() { loginRespMsg := &msg.LoginResp{ - Version: version.Full(), + //Version: version.Full(), + Version: "edgewize-msg-transport-v1", RunID: ctl.runID, Error: "", } diff --git a/server/dashboard_api.go b/server/dashboard_api.go index f34da4ef513..b14b851466f 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -29,7 +29,6 @@ import ( httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" netpkg "github.com/fatedier/frp/pkg/util/net" - "github.com/fatedier/frp/pkg/util/version" ) type GeneralResponse struct { @@ -107,7 +106,8 @@ func (svr *Service) apiServerInfo(w http.ResponseWriter, r *http.Request) { log.Infof("Http request: [%s]", r.URL.Path) serverStats := mem.StatsCollector.GetServer() svrResp := serverInfoResp{ - Version: version.Full(), + //Version: version.Full(), + Version: "edgewize-msg-transport-v1", BindPort: svr.cfg.BindPort, VhostHTTPPort: svr.cfg.VhostHTTPPort, VhostHTTPSPort: svr.cfg.VhostHTTPSPort, diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index d5ab0f13ae5..fe8bb89bfe9 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -143,10 +143,12 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn, if src != nil { srcAddr, srcPortStr, _ = net.SplitHostPort(src.String()) + srcAddr = "1.2.3.4" srcPort, _ = strconv.Atoi(srcPortStr) } if dst != nil { dstAddr, dstPortStr, _ = net.SplitHostPort(dst.String()) + dstAddr = "4.3.2.1" dstPort, _ = strconv.Atoi(dstPortStr) } err := msg.WriteMsg(workConn, &msg.StartWorkConn{ diff --git a/server/proxy/sudp.go b/server/proxy/sudp.go index f37fb4239fd..e75597ac21b 100644 --- a/server/proxy/sudp.go +++ b/server/proxy/sudp.go @@ -15,13 +15,11 @@ package proxy import ( - "reflect" - v1 "github.com/fatedier/frp/pkg/config/v1" ) func init() { - RegisterProxyFactory(reflect.TypeOf(&v1.SUDPProxyConfig{}), NewSUDPProxy) + //RegisterProxyFactory(reflect.TypeOf(&v1.SUDPProxyConfig{}), NewSUDPProxy) } type SUDPProxy struct { diff --git a/server/proxy/tcp.go b/server/proxy/tcp.go index a6eae3a9d6b..daba74ee8fd 100644 --- a/server/proxy/tcp.go +++ b/server/proxy/tcp.go @@ -17,14 +17,13 @@ package proxy import ( "fmt" "net" - "reflect" "strconv" v1 "github.com/fatedier/frp/pkg/config/v1" ) func init() { - RegisterProxyFactory(reflect.TypeOf(&v1.TCPProxyConfig{}), NewTCPProxy) + //RegisterProxyFactory(reflect.TypeOf(&v1.TCPProxyConfig{}), NewTCPProxy) } type TCPProxy struct { diff --git a/server/proxy/udp.go b/server/proxy/udp.go index 53a07d52676..04609bc0d74 100644 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -19,7 +19,6 @@ import ( "fmt" "io" "net" - "reflect" "strconv" "time" @@ -35,7 +34,7 @@ import ( ) func init() { - RegisterProxyFactory(reflect.TypeOf(&v1.UDPProxyConfig{}), NewUDPProxy) + //RegisterProxyFactory(reflect.TypeOf(&v1.UDPProxyConfig{}), NewUDPProxy) } type UDPProxy struct { diff --git a/server/proxy/xtcp.go b/server/proxy/xtcp.go index f69d0790d65..8ff0ad7182a 100644 --- a/server/proxy/xtcp.go +++ b/server/proxy/xtcp.go @@ -16,8 +16,6 @@ package proxy import ( "fmt" - "reflect" - "github.com/fatedier/golib/errors" v1 "github.com/fatedier/frp/pkg/config/v1" @@ -25,7 +23,7 @@ import ( ) func init() { - RegisterProxyFactory(reflect.TypeOf(&v1.XTCPProxyConfig{}), NewXTCPProxy) + //RegisterProxyFactory(reflect.TypeOf(&v1.XTCPProxyConfig{}), NewXTCPProxy) } type XTCPProxy struct { diff --git a/server/service.go b/server/service.go index 27c4110d92a..2659705929b 100644 --- a/server/service.go +++ b/server/service.go @@ -15,13 +15,12 @@ package server import ( - "bytes" "context" "crypto/tls" "fmt" + "github.com/fatedier/frp/server/visitor" "io" "net" - "net/http" "os" "strconv" "time" @@ -36,7 +35,6 @@ import ( v1 "github.com/fatedier/frp/pkg/config/v1" modelmetrics "github.com/fatedier/frp/pkg/metrics" "github.com/fatedier/frp/pkg/msg" - "github.com/fatedier/frp/pkg/nathole" plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/ssh" "github.com/fatedier/frp/pkg/transport" @@ -45,15 +43,11 @@ import ( netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/tcpmux" "github.com/fatedier/frp/pkg/util/util" - "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/vhost" "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" - "github.com/fatedier/frp/server/group" "github.com/fatedier/frp/server/metrics" - "github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/proxy" - "github.com/fatedier/frp/server/visitor" ) const ( @@ -156,16 +150,16 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { pluginManager: plugin.NewManager(), rc: &controller.ResourceController{ VisitorManager: visitor.NewManager(), - TCPPortManager: ports.NewManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts), - UDPPortManager: ports.NewManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts), + //TCPPortManager: ports.NewManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts), + //UDPPortManager: ports.NewManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts), }, - sshTunnelListener: netpkg.NewInternalListener(), - httpVhostRouter: vhost.NewRouters(), - authVerifier: auth.NewAuthVerifier(cfg.Auth), - webServer: webServer, - tlsConfig: tlsConfig, - cfg: cfg, - ctx: context.Background(), + //sshTunnelListener: netpkg.NewInternalListener(), + //httpVhostRouter: vhost.NewRouters(), + authVerifier: auth.NewAuthVerifier(cfg.Auth), + //webServer: webServer, + tlsConfig: tlsConfig, + cfg: cfg, + ctx: context.Background(), } if webServer != nil { webServer.RouteRegister(svr.registerRouteHandlers) @@ -195,29 +189,29 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { svr.rc.PluginManager = svr.pluginManager // Init group controller - svr.rc.TCPGroupCtl = group.NewTCPGroupCtl(svr.rc.TCPPortManager) + //svr.rc.TCPGroupCtl = group.NewTCPGroupCtl(svr.rc.TCPPortManager) // Init HTTP group controller - svr.rc.HTTPGroupCtl = group.NewHTTPGroupController(svr.httpVhostRouter) + //svr.rc.HTTPGroupCtl = group.NewHTTPGroupController(svr.httpVhostRouter) // Init TCP mux group controller - svr.rc.TCPMuxGroupCtl = group.NewTCPMuxGroupCtl(svr.rc.TCPMuxHTTPConnectMuxer) + //svr.rc.TCPMuxGroupCtl = group.NewTCPMuxGroupCtl(svr.rc.TCPMuxHTTPConnectMuxer) // Init 404 not found page - vhost.NotFoundPagePath = cfg.Custom404Page - - var ( - httpMuxOn bool - httpsMuxOn bool - ) - if cfg.BindAddr == cfg.ProxyBindAddr { - if cfg.BindPort == cfg.VhostHTTPPort { - httpMuxOn = true - } - if cfg.BindPort == cfg.VhostHTTPSPort { - httpsMuxOn = true - } - } + //vhost.NotFoundPagePath = cfg.Custom404Page + + //var ( + // httpMuxOn bool + // httpsMuxOn bool + //) + //if cfg.BindAddr == cfg.ProxyBindAddr { + // if cfg.BindPort == cfg.VhostHTTPPort { + // httpMuxOn = true + // } + // if cfg.BindPort == cfg.VhostHTTPSPort { + // httpsMuxOn = true + // } + //} // Listen for accepting connections from client. address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindPort)) @@ -238,105 +232,105 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { // Listen for accepting connections from client using kcp protocol. if cfg.KCPBindPort > 0 { - address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) - svr.kcpListener, err = netpkg.ListenKcp(address) - if err != nil { - return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err) - } - log.Infof("frps kcp listen on udp %s", address) + //address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) + //svr.kcpListener, err = netpkg.ListenKcp(address) + //if err != nil { + // return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err) + //} + //log.Infof("frps kcp listen on udp %s", address) } if cfg.QUICBindPort > 0 { - address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort)) - quicTLSCfg := tlsConfig.Clone() - quicTLSCfg.NextProtos = []string{"frp"} - svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{ - MaxIdleTimeout: time.Duration(cfg.Transport.QUIC.MaxIdleTimeout) * time.Second, - MaxIncomingStreams: int64(cfg.Transport.QUIC.MaxIncomingStreams), - KeepAlivePeriod: time.Duration(cfg.Transport.QUIC.KeepalivePeriod) * time.Second, - }) - if err != nil { - return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err) - } - log.Infof("frps quic listen on %s", address) - } - - if cfg.SSHTunnelGateway.BindPort > 0 { - sshGateway, err := ssh.NewGateway(cfg.SSHTunnelGateway, cfg.ProxyBindAddr, svr.sshTunnelListener) - if err != nil { - return nil, fmt.Errorf("create ssh gateway error: %v", err) - } - svr.sshTunnelGateway = sshGateway - log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort) - } + //address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort)) + //quicTLSCfg := tlsConfig.Clone() + //quicTLSCfg.NextProtos = []string{"frp"} + //svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{ + // MaxIdleTimeout: time.Duration(cfg.Transport.QUIC.MaxIdleTimeout) * time.Second, + // MaxIncomingStreams: int64(cfg.Transport.QUIC.MaxIncomingStreams), + // KeepAlivePeriod: time.Duration(cfg.Transport.QUIC.KeepalivePeriod) * time.Second, + //}) + //if err != nil { + // return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err) + //} + //log.Infof("frps quic listen on %s", address) + } + + //if cfg.SSHTunnelGateway.BindPort > 0 { + // sshGateway, err := ssh.NewGateway(cfg.SSHTunnelGateway, cfg.ProxyBindAddr, svr.sshTunnelListener) + // if err != nil { + // return nil, fmt.Errorf("create ssh gateway error: %v", err) + // } + // svr.sshTunnelGateway = sshGateway + // log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort) + //} // Listen for accepting connections from client using websocket protocol. - websocketPrefix := []byte("GET " + netpkg.FrpWebsocketPath) - websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool { - return bytes.Equal(data, websocketPrefix) - }) - svr.websocketListener = netpkg.NewWebsocketListener(websocketLn) + //websocketPrefix := []byte("GET " + netpkg.FrpWebsocketPath) + //websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool { + // return bytes.Equal(data, websocketPrefix) + //}) + //svr.websocketListener = netpkg.NewWebsocketListener(websocketLn) // Create http vhost muxer. if cfg.VhostHTTPPort > 0 { - rp := vhost.NewHTTPReverseProxy(vhost.HTTPReverseProxyOptions{ - ResponseHeaderTimeoutS: cfg.VhostHTTPTimeout, - }, svr.httpVhostRouter) - svr.rc.HTTPReverseProxy = rp - - address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort)) - server := &http.Server{ - Addr: address, - Handler: rp, - ReadHeaderTimeout: 60 * time.Second, - } - var l net.Listener - if httpMuxOn { - l = svr.muxer.ListenHTTP(1) - } else { - l, err = net.Listen("tcp", address) - if err != nil { - return nil, fmt.Errorf("create vhost http listener error, %v", err) - } - } - go func() { - _ = server.Serve(l) - }() - log.Infof("http service listen on %s", address) + //rp := vhost.NewHTTPReverseProxy(vhost.HTTPReverseProxyOptions{ + // ResponseHeaderTimeoutS: cfg.VhostHTTPTimeout, + //}, svr.httpVhostRouter) + //svr.rc.HTTPReverseProxy = rp + // + //address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort)) + //server := &http.Server{ + // Addr: address, + // Handler: rp, + // ReadHeaderTimeout: 60 * time.Second, + //} + //var l net.Listener + //if httpMuxOn { + // l = svr.muxer.ListenHTTP(1) + //} else { + // l, err = net.Listen("tcp", address) + // if err != nil { + // return nil, fmt.Errorf("create vhost http listener error, %v", err) + // } + //} + //go func() { + // _ = server.Serve(l) + //}() + //log.Infof("http service listen on %s", address) } // Create https vhost muxer. if cfg.VhostHTTPSPort > 0 { - var l net.Listener - if httpsMuxOn { - l = svr.muxer.ListenHTTPS(1) - } else { - address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) - l, err = net.Listen("tcp", address) - if err != nil { - return nil, fmt.Errorf("create server listener error, %v", err) - } - log.Infof("https service listen on %s", address) - } - - svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) - if err != nil { - return nil, fmt.Errorf("create vhost httpsMuxer error, %v", err) - } + //var l net.Listener + //if httpsMuxOn { + // l = svr.muxer.ListenHTTPS(1) + //} else { + // address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) + // l, err = net.Listen("tcp", address) + // if err != nil { + // return nil, fmt.Errorf("create server listener error, %v", err) + // } + // log.Infof("https service listen on %s", address) + //} + + //svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) + //if err != nil { + // return nil, fmt.Errorf("create vhost httpsMuxer error, %v", err) + //} } // frp tls listener - svr.tlsListener = svr.muxer.Listen(2, 1, func(data []byte) bool { + svr.tlsListener = svr.muxer.Listen(2, uint32(len(netpkg.FRPTLSHeadByte)), func(data []byte) bool { // tls first byte can be 0x16 only when vhost https port is not same with bind port - return int(data[0]) == netpkg.FRPTLSHeadByte || int(data[0]) == 0x16 + return netpkg.BytesEqual(data, netpkg.FRPTLSHeadByte) //|| int(data[0]) == 0x16 取消对原版FRPC的TLS兼容 }) // Create nat hole controller. - nc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour) - if err != nil { - return nil, fmt.Errorf("create nat hole controller error, %v", err) - } - svr.rc.NatHoleController = nc + //nc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour) + //if err != nil { + // return nil, fmt.Errorf("create nat hole controller error, %v", err) + //} + //svr.rc.NatHoleController = nc return svr, nil } @@ -355,7 +349,9 @@ func (svr *Service) Run(ctx context.Context) { }() } - go svr.HandleListener(svr.sshTunnelListener, true) + if svr.sshTunnelListener != nil { + go svr.HandleListener(svr.sshTunnelListener, true) + } if svr.kcpListener != nil { go svr.HandleListener(svr.kcpListener, false) @@ -363,7 +359,10 @@ func (svr *Service) Run(ctx context.Context) { if svr.quicListener != nil { go svr.HandleQUICListener(svr.quicListener) } - go svr.HandleListener(svr.websocketListener, false) + if svr.websocketListener != nil { + go svr.HandleListener(svr.websocketListener, false) + } + go svr.HandleListener(svr.tlsListener, false) if svr.rc.NatHoleController != nil { @@ -428,16 +427,21 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { - case *msg.Login: - // server plugin hook + case *msg.CryptoLogin: + login := svr.authVerifier.VerifyCrypto(m) + if login == nil { + log.Errorf("verify login failed,%s,%d", m.Sign, m.TimeStamp) + conn.Close() + return + } content := &plugin.LoginContent{ - Login: *m, + Login: *login, ClientAddress: conn.RemoteAddr().String(), } retContent, err := svr.pluginManager.Login(content) if err == nil { - m = &retContent.Login - err = svr.RegisterControl(conn, m, internal) + m1 := &retContent.Login + err = svr.RegisterControl(conn, m1, internal) } // If login failed, send error message there. @@ -445,11 +449,16 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna if err != nil { xl.Warnf("register control error: %v", err) _ = msg.WriteMsg(conn, &msg.LoginResp{ - Version: version.Full(), + //Version: version.Full(), + Version: "edgewize-msg-transport-v1", Error: util.GenerateResponseErrorString("register control error", err, lo.FromPtr(svr.cfg.DetailedErrorsToClient)), }) conn.Close() } + case *msg.Login: + // server plugin hook + log.Warnf("有人使用原生FRP登录!") + conn.Close() case *msg.NewWorkConn: if err := svr.RegisterWorkConn(conn, m); err != nil { conn.Close() @@ -502,6 +511,8 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) { originConn.Close() continue } + fmt.Println("is tls check:", isTLS) + fmt.Println("tls config:", svr.tlsConfig.Certificates) log.Tracef("check TLS connection success, isTLS: %v custom: %v internal: %v", isTLS, custom, internal) } From 9798cd0529fb36a5c087731ab2ab86054754b597 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Thu, 7 Nov 2024 15:07:30 +0800 Subject: [PATCH 04/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/transport/tls.go | 2 -- server/service.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 372748a3894..939c85a73b8 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -20,7 +20,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/pem" - "fmt" "math/big" "os" ) @@ -111,7 +110,6 @@ func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Conf } base.Certificates = []tls.Certificate{*cert} } - fmt.Println("tls config certificates", certPath, keyPath, base.Certificates) base.ServerName = serverName diff --git a/server/service.go b/server/service.go index 2659705929b..2673e5da6cb 100644 --- a/server/service.go +++ b/server/service.go @@ -511,8 +511,6 @@ func (svr *Service) HandleListener(l net.Listener, internal bool) { originConn.Close() continue } - fmt.Println("is tls check:", isTLS) - fmt.Println("tls config:", svr.tlsConfig.Certificates) log.Tracef("check TLS connection success, isTLS: %v custom: %v internal: %v", isTLS, custom, internal) } From 2b59f6205df1c4d39f4e47edf2f85034aec218ea Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Thu, 7 Nov 2024 15:14:32 +0800 Subject: [PATCH 05/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .circleci/config.yml | 16 ------ .github/FUNDING.yml | 4 -- .github/pull_request_template.md | 3 -- .github/workflows/build-and-push-image.yml | 59 +++------------------- .github/workflows/golangci-lint.yml | 42 --------------- .github/workflows/goreleaser.yml | 30 ----------- .github/workflows/stale.yml | 35 ------------- 7 files changed, 8 insertions(+), 181 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/pull_request_template.md delete mode 100644 .github/workflows/golangci-lint.yml delete mode 100644 .github/workflows/goreleaser.yml delete mode 100644 .github/workflows/stale.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 3dff8a52ca6..00000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 -jobs: - go-version-latest: - docker: - - image: cimg/go:1.22-node - resource_class: large - steps: - - checkout - - run: make - - run: make alltest - -workflows: - version: 2 - build_and_test: - jobs: - - go-version-latest diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 2d8fe2e060d..00000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: [fatedier] -custom: ["https://afdian.net/a/fatedier"] diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 7724848141f..00000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,3 +0,0 @@ -### WHY - - diff --git a/.github/workflows/build-and-push-image.yml b/.github/workflows/build-and-push-image.yml index c6caff6cd4b..7b4f3244dfe 100644 --- a/.github/workflows/build-and-push-image.yml +++ b/.github/workflows/build-and-push-image.yml @@ -29,55 +29,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - # get image tag name - - name: Get Image Tag Name + - name: Build and push docker images + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | - if [ x${{ github.event.inputs.tag }} == x"" ]; then - echo "TAG_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - else - echo "TAG_NAME=${{ github.event.inputs.tag }}" >> $GITHUB_ENV - fi - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Login to the GPR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GPR_TOKEN }} - - # prepare image tags - - name: Prepare Image Tags - run: | - echo "DOCKERFILE_FRPC_PATH=dockerfiles/Dockerfile-for-frpc" >> $GITHUB_ENV - echo "DOCKERFILE_FRPS_PATH=dockerfiles/Dockerfile-for-frps" >> $GITHUB_ENV - echo "TAG_FRPC=fatedier/frpc:${{ env.TAG_NAME }}" >> $GITHUB_ENV - echo "TAG_FRPS=fatedier/frps:${{ env.TAG_NAME }}" >> $GITHUB_ENV - echo "TAG_FRPC_GPR=ghcr.io/fatedier/frpc:${{ env.TAG_NAME }}" >> $GITHUB_ENV - echo "TAG_FRPS_GPR=ghcr.io/fatedier/frps:${{ env.TAG_NAME }}" >> $GITHUB_ENV - - - name: Build and push frpc - uses: docker/build-push-action@v5 - with: - context: . - file: ./dockerfiles/Dockerfile-for-frpc - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x - push: true - tags: | - ${{ env.TAG_FRPC }} - ${{ env.TAG_FRPC_GPR }} - - - name: Build and push frps - uses: docker/build-push-action@v5 - with: - context: . - file: ./dockerfiles/Dockerfile-for-frps - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x - push: true - tags: | - ${{ env.TAG_FRPS }} - ${{ env.TAG_FRPS_GPR }} + echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + ver=nightly-$(date '+%Y%m%d') + chmod -R 755 hack/ + REPO=edgewize VER=${ver} make docker \ No newline at end of file diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml deleted file mode 100644 index b3e2cb43c39..00000000000 --- a/.github/workflows/golangci-lint.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: golangci-lint -on: - push: - branches: - - master - - dev - pull_request: -permissions: - contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. - pull-requests: read -jobs: - golangci: - name: lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.22' - cache: false - - name: golangci-lint - uses: golangci/golangci-lint-action@v4 - with: - # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.57 - - # Optional: golangci-lint command line arguments. - # args: --issues-exit-code=0 - - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true - - # Optional: if set to true then the all caching functionality will be complete disabled, - # takes precedence over all other caching options. - # skip-cache: true - - # Optional: if set to true then the action don't cache or restore ~/go/pkg. - # skip-pkg-cache: true - - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - # skip-build-cache: true diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml deleted file mode 100644 index 7c01f3764a0..00000000000 --- a/.github/workflows/goreleaser.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: goreleaser - -on: - workflow_dispatch: - -jobs: - goreleaser: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.22' - - - name: Make All - run: | - ./package.sh - - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5 - with: - version: latest - args: release --clean --release-notes=./Release.md - env: - GITHUB_TOKEN: ${{ secrets.GPR_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index f5cc538f5e1..00000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: "Close stale issues" -on: - schedule: - - cron: "20 0 * * *" - workflow_dispatch: - inputs: - debug-only: - description: 'In debug mod' - required: false - default: 'false' -permissions: - contents: read - -jobs: - stale: - permissions: - issues: write # for actions/stale to close stale issues - pull-requests: write # for actions/stale to close stale PRs - actions: write - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v9 - with: - stale-issue-message: 'Issues go stale after 21d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.' - stale-pr-message: "PRs go stale after 21d of inactivity. Stale PRs rot after an additional 7d of inactivity and eventually close." - stale-issue-label: 'lifecycle/stale' - exempt-issue-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned' - stale-pr-label: 'lifecycle/stale' - exempt-pr-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned' - days-before-stale: 21 - days-before-close: 7 - debug-only: ${{ github.event.inputs.debug-only }} - exempt-all-pr-milestones: true - exempt-all-pr-assignees: true - operations-per-run: 200 From e48f5ab19699cf1cb00ac30c987bb4081ed090da Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Fri, 8 Nov 2024 14:20:07 +0800 Subject: [PATCH 06/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- cmd/{router-client => frpc}/main.go | 2 +- cmd/{router-client => frpc}/sub/admin.go | 0 cmd/{router-client => frpc}/sub/nathole.go | 0 cmd/{router-client => frpc}/sub/proxy.go | 0 cmd/{router-client => frpc}/sub/root.go | 4 +- cmd/{router-client => frpc}/sub/verify.go | 0 cmd/{router-server => frps}/main.go | 0 cmd/{router-server => frps}/root.go | 2 +- cmd/{router-server => frps}/verify.go | 0 pkg/auth/edgewize_oidc.go | 32 +++ pkg/auth/edgewize_pass.go | 7 + pkg/auth/edgewize_token.go | 32 +++ pkg/auth/oidc.go | 29 +-- pkg/auth/pass.go | 4 - pkg/auth/token.go | 25 -- pkg/config/legacy/client.go | 2 +- pkg/config/legacy/conversion.go | 11 +- pkg/config/legacy/edgewize_client.go | 11 + .../v1/validation/edgewize_validation.go | 9 + pkg/msg/edgewize_msg.go | 21 ++ pkg/msg/msg.go | 96 ++++---- pkg/plugin/server/manager.go | 30 +-- pkg/util/net/dial.go | 5 +- pkg/util/net/tls.go | 22 +- pkg/util/util/edgewize_util.go | 68 ++++++ pkg/util/util/util.go | 65 +----- pkg/util/version/version.go | 2 +- pkg/util/vhost/resource.go | 3 +- server/control.go | 4 +- server/dashboard_api.go | 4 +- server/edgewize_service.go | 112 +++++++++ server/proxy/proxy.go | 2 - server/service.go | 217 +++++++++--------- 34 files changed, 484 insertions(+), 341 deletions(-) rename cmd/{router-client => frpc}/main.go (94%) rename cmd/{router-client => frpc}/sub/admin.go (100%) rename cmd/{router-client => frpc}/sub/nathole.go (100%) rename cmd/{router-client => frpc}/sub/proxy.go (100%) rename cmd/{router-client => frpc}/sub/root.go (98%) rename cmd/{router-client => frpc}/sub/verify.go (100%) rename cmd/{router-server => frps}/main.go (100%) rename cmd/{router-server => frps}/root.go (98%) rename cmd/{router-server => frps}/verify.go (100%) create mode 100644 pkg/auth/edgewize_oidc.go create mode 100644 pkg/auth/edgewize_pass.go create mode 100644 pkg/auth/edgewize_token.go create mode 100644 pkg/config/legacy/edgewize_client.go create mode 100644 pkg/config/v1/validation/edgewize_validation.go create mode 100644 pkg/msg/edgewize_msg.go create mode 100644 pkg/util/util/edgewize_util.go create mode 100644 server/edgewize_service.go diff --git a/Makefile b/Makefile index ef592fe5abb..0deb8a54715 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,10 @@ vet: go vet ./... router-server: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-server ./cmd/router-server + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-server ./cmd/frps router-client: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-client ./cmd/router-client + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-client ./cmd/frpc test: gotest diff --git a/cmd/router-client/main.go b/cmd/frpc/main.go similarity index 94% rename from cmd/router-client/main.go rename to cmd/frpc/main.go index 7a7f52bd714..f7651bca169 100644 --- a/cmd/router-client/main.go +++ b/cmd/frpc/main.go @@ -16,7 +16,7 @@ package main import ( _ "github.com/fatedier/frp/assets/frpc" - "github.com/fatedier/frp/cmd/router-client/sub" + "github.com/fatedier/frp/cmd/frpc/sub" "github.com/fatedier/frp/pkg/util/system" ) diff --git a/cmd/router-client/sub/admin.go b/cmd/frpc/sub/admin.go similarity index 100% rename from cmd/router-client/sub/admin.go rename to cmd/frpc/sub/admin.go diff --git a/cmd/router-client/sub/nathole.go b/cmd/frpc/sub/nathole.go similarity index 100% rename from cmd/router-client/sub/nathole.go rename to cmd/frpc/sub/nathole.go diff --git a/cmd/router-client/sub/proxy.go b/cmd/frpc/sub/proxy.go similarity index 100% rename from cmd/router-client/sub/proxy.go rename to cmd/frpc/sub/proxy.go diff --git a/cmd/router-client/sub/root.go b/cmd/frpc/sub/root.go similarity index 98% rename from cmd/router-client/sub/root.go rename to cmd/frpc/sub/root.go index 41c5d700ef7..39a7a49b11a 100644 --- a/cmd/router-client/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -17,6 +17,7 @@ package sub import ( "context" "fmt" + "github.com/fatedier/frp/pkg/util/version" "io/fs" "os" "os/signal" @@ -53,8 +54,7 @@ var rootCmd = &cobra.Command{ Short: "frpc is the client of frp (https://github.com/fatedier/frp)", RunE: func(cmd *cobra.Command, args []string) error { if showVersion { - //fmt.Println(version.Full()) - fmt.Println("edgewize-msg-transport-v1") + fmt.Println(version.Full()) return nil } diff --git a/cmd/router-client/sub/verify.go b/cmd/frpc/sub/verify.go similarity index 100% rename from cmd/router-client/sub/verify.go rename to cmd/frpc/sub/verify.go diff --git a/cmd/router-server/main.go b/cmd/frps/main.go similarity index 100% rename from cmd/router-server/main.go rename to cmd/frps/main.go diff --git a/cmd/router-server/root.go b/cmd/frps/root.go similarity index 98% rename from cmd/router-server/root.go rename to cmd/frps/root.go index fff487d1074..2dbea578d11 100644 --- a/cmd/router-server/root.go +++ b/cmd/frps/root.go @@ -107,7 +107,7 @@ func runServer(cfg *v1.ServerConfig) (err error) { log.Infof("frps uses command line arguments for config") } - svr, err := server.NewService(cfg) + svr, err := server.NewEdgewizeService(cfg) if err != nil { return err } diff --git a/cmd/router-server/verify.go b/cmd/frps/verify.go similarity index 100% rename from cmd/router-server/verify.go rename to cmd/frps/verify.go diff --git a/pkg/auth/edgewize_oidc.go b/pkg/auth/edgewize_oidc.go new file mode 100644 index 00000000000..cb3ffec1e84 --- /dev/null +++ b/pkg/auth/edgewize_oidc.go @@ -0,0 +1,32 @@ +package auth + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "github.com/fatedier/frp/pkg/msg" + "github.com/fatedier/frp/pkg/util/util" + "strconv" +) + +func (auth *OidcAuthProvider) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { + bs, _ := json.Marshal(login) + c.Auth = util.RandomString(16) + key := util.GenerateAesKey(c.Auth)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) +} + +func (auth *OidcAuthConsumer) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + var login *msg.Login + bs, err := hex.DecodeString(c.Sign) + if err != nil { + fmt.Println("verify crypto error,", err) + return nil + } + key := util.GenerateAesKey(c.Auth)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + before := util.Decrypt(bs, key, []byte(iv)) + _ = json.Unmarshal(before, login) + return login +} diff --git a/pkg/auth/edgewize_pass.go b/pkg/auth/edgewize_pass.go new file mode 100644 index 00000000000..c254b748082 --- /dev/null +++ b/pkg/auth/edgewize_pass.go @@ -0,0 +1,7 @@ +package auth + +import "github.com/fatedier/frp/pkg/msg" + +func (p *alwaysPass) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + return nil +} diff --git a/pkg/auth/edgewize_token.go b/pkg/auth/edgewize_token.go new file mode 100644 index 00000000000..873d5dd5fe7 --- /dev/null +++ b/pkg/auth/edgewize_token.go @@ -0,0 +1,32 @@ +package auth + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "github.com/fatedier/frp/pkg/msg" + "github.com/fatedier/frp/pkg/util/util" + "strconv" +) + +func (auth *TokenAuthSetterVerifier) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { + bs, _ := json.Marshal(login) + key := util.GenerateAesKey(auth.token)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + c.Auth = util.RandomString(16) + c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) +} + +func (auth *TokenAuthSetterVerifier) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { + var login msg.Login + bs, err := hex.DecodeString(c.Sign) + if err != nil { + fmt.Println("verify crypto error,", err) + return nil + } + key := util.GenerateAesKey(auth.token)[:8] + iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] + before := util.Decrypt(bs, key, []byte(iv)) + _ = json.Unmarshal(before, &login) + return &login +} diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index 3b7eca20977..2881af9c0e6 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -16,15 +16,10 @@ package auth import ( "context" - "encoding/hex" - "encoding/json" "fmt" - "github.com/fatedier/frp/pkg/util/util" - "slices" - "strconv" - "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2/clientcredentials" + "slices" v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/msg" @@ -153,25 +148,3 @@ func (auth *OidcAuthConsumer) VerifyNewWorkConn(newWorkConnMsg *msg.NewWorkConn) return auth.verifyPostLoginToken(newWorkConnMsg.PrivilegeKey) } - -func (auth *OidcAuthProvider) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { - bs, _ := json.Marshal(login) - c.Auth = util.RandomString(16) - key := util.GenerateAesKey(c.Auth)[:8] - iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] - c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) -} - -func (auth *OidcAuthConsumer) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { - var login *msg.Login - bs, err := hex.DecodeString(c.Sign) - if err != nil { - fmt.Println("verify crypto error,", err) - return nil - } - key := util.GenerateAesKey(c.Auth)[:8] - iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] - before := util.Decrypt(bs, key, []byte(iv)) - _ = json.Unmarshal(before, login) - return login -} diff --git a/pkg/auth/pass.go b/pkg/auth/pass.go index ca0b1489046..2eaf3f0bd70 100644 --- a/pkg/auth/pass.go +++ b/pkg/auth/pass.go @@ -24,10 +24,6 @@ var _ Verifier = &alwaysPass{} type alwaysPass struct{} -func (p *alwaysPass) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { - return nil -} - func (*alwaysPass) VerifyLogin(*msg.Login) error { return nil } func (*alwaysPass) VerifyPing(*msg.Ping) error { return nil } diff --git a/pkg/auth/token.go b/pkg/auth/token.go index 982f1cf84b1..9ee993f9d50 100644 --- a/pkg/auth/token.go +++ b/pkg/auth/token.go @@ -15,11 +15,8 @@ package auth import ( - "encoding/hex" - "encoding/json" "fmt" "slices" - "strconv" "time" v1 "github.com/fatedier/frp/pkg/config/v1" @@ -92,25 +89,3 @@ func (auth *TokenAuthSetterVerifier) VerifyNewWorkConn(m *msg.NewWorkConn) error } return nil } - -func (auth *TokenAuthSetterVerifier) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { - bs, _ := json.Marshal(login) - key := util.GenerateAesKey(auth.token)[:8] - iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] - c.Auth = util.RandomString(16) - c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) -} - -func (auth *TokenAuthSetterVerifier) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { - var login msg.Login - bs, err := hex.DecodeString(c.Sign) - if err != nil { - fmt.Println("verify crypto error,", err) - return nil - } - key := util.GenerateAesKey(auth.token)[:8] - iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] - before := util.Decrypt(bs, key, []byte(iv)) - _ = json.Unmarshal(before, &login) - return &login -} diff --git a/pkg/config/legacy/client.go b/pkg/config/legacy/client.go index 7c16c73dbbe..9aca2d368fc 100644 --- a/pkg/config/legacy/client.go +++ b/pkg/config/legacy/client.go @@ -196,7 +196,7 @@ func UnmarshalClientConfFromIni(source interface{}) (ClientCommonConf, error) { common.Metas = GetMapWithoutPrefix(s.KeysHash(), "meta_") common.ClientConfig.OidcAdditionalEndpointParams = GetMapWithoutPrefix(s.KeysHash(), "oidc_additional_") - return common, nil + return ChangeClientConfFromIni(common), nil } // if len(startProxy) is 0, start all diff --git a/pkg/config/legacy/conversion.go b/pkg/config/legacy/conversion.go index e535793d270..dd8c4a11d91 100644 --- a/pkg/config/legacy/conversion.go +++ b/pkg/config/legacy/conversion.go @@ -57,10 +57,8 @@ func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConf out.Transport.QUIC.KeepalivePeriod = conf.QUICKeepalivePeriod out.Transport.QUIC.MaxIdleTimeout = conf.QUICMaxIdleTimeout out.Transport.QUIC.MaxIncomingStreams = conf.QUICMaxIncomingStreams - // 强制开启tls - out.Transport.TLS.Enable = lo.ToPtr(true) - // 强制启用TLS头字符 - out.Transport.TLS.DisableCustomTLSFirstByte = lo.ToPtr(false) + out.Transport.TLS.Enable = lo.ToPtr(conf.TLSEnable) + out.Transport.TLS.DisableCustomTLSFirstByte = lo.ToPtr(conf.DisableCustomTLSFirstByte) out.Transport.TLS.TLSConfig.CertFile = conf.TLSCertFile out.Transport.TLS.TLSConfig.KeyFile = conf.TLSKeyFile out.Transport.TLS.TLSConfig.TrustedCaFile = conf.TLSTrustedCaFile @@ -71,9 +69,8 @@ func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConf out.Log.MaxDays = conf.LogMaxDays out.Log.DisablePrintColor = conf.DisableLogColor - // 强制开启只监听本地端口的web server - out.WebServer.Addr = "127.0.0.1" - out.WebServer.Port = 2333 + out.WebServer.Addr = conf.AdminAddr + out.WebServer.Port = conf.AdminPort out.WebServer.User = conf.AdminUser out.WebServer.Password = conf.AdminPwd out.WebServer.AssetsDir = conf.AssetsDir diff --git a/pkg/config/legacy/edgewize_client.go b/pkg/config/legacy/edgewize_client.go new file mode 100644 index 00000000000..c3474fc37ed --- /dev/null +++ b/pkg/config/legacy/edgewize_client.go @@ -0,0 +1,11 @@ +package legacy + +func ChangeClientConfFromIni(common ClientCommonConf) ClientCommonConf { + common.TLSEnable = true + common.DisableCustomTLSFirstByte = false + + common.AdminAddr = "127.0.0.1" + common.AdminPort = 2333 + + return common +} diff --git a/pkg/config/v1/validation/edgewize_validation.go b/pkg/config/v1/validation/edgewize_validation.go new file mode 100644 index 00000000000..d5ba59f0dda --- /dev/null +++ b/pkg/config/v1/validation/edgewize_validation.go @@ -0,0 +1,9 @@ +package validation + +import splugin "github.com/fatedier/frp/pkg/plugin/server" + +func init() { + SupportedHTTPPluginOps = []string{ + splugin.OpLogin, + } +} diff --git a/pkg/msg/edgewize_msg.go b/pkg/msg/edgewize_msg.go new file mode 100644 index 00000000000..5d852f7001d --- /dev/null +++ b/pkg/msg/edgewize_msg.go @@ -0,0 +1,21 @@ +package msg + +const ( + TypeConnHead = 's' + TypeCryptoLogin = 't' +) + +func init() { + msgTypeMap[TypeConnHead] = ConnectHead{} + msgTypeMap[TypeCryptoLogin] = CryptoLogin{} +} + +type CryptoLogin struct { + TimeStamp int64 `json:"time_stamp,omitempty"` + Auth string `json:"auth"` + Sign string `json:"sign,omitempty"` +} + +type ConnectHead struct { + ServiceName string `json:"serviceName"` +} diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index eaf98dab95e..a6344d08fe3 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -20,26 +20,24 @@ import ( ) const ( - TypeLogin = 0x01 - TypeLoginResp = 0x02 - TypeNewProxy = 0x03 - TypeNewProxyResp = 0x04 - TypeCloseProxy = 0x05 - TypeNewWorkConn = 0x06 - TypeReqWorkConn = 0x07 - TypeStartWorkConn = 0x08 - TypeNewVisitorConn = 0x09 - TypeNewVisitorConnResp = 0x0a - TypePing = 0x0b - TypePong = 0x0c - TypeUDPPacket = 0x0d - TypeNatHoleVisitor = 0x0e - TypeNatHoleClient = 0x10 - TypeNatHoleResp = 0x11 - TypeNatHoleSid = 0x12 - TypeNatHoleReport = 0x0f - TypeConnHead = 0x13 - TypeCryptoLogin = 0xf8 + TypeLogin = 'o' + TypeLoginResp = '1' + TypeNewProxy = 'p' + TypeNewProxyResp = '2' + TypeCloseProxy = 'c' + TypeNewWorkConn = 'w' + TypeReqWorkConn = 'r' + TypeStartWorkConn = 's' + TypeNewVisitorConn = 'v' + TypeNewVisitorConnResp = '3' + TypePing = 'h' + TypePong = '4' + TypeUDPPacket = 'u' + TypeNatHoleVisitor = 'i' + TypeNatHoleClient = 'n' + TypeNatHoleResp = 'm' + TypeNatHoleSid = '5' + TypeNatHoleReport = '6' ) var msgTypeMap = map[byte]interface{}{ @@ -61,8 +59,6 @@ var msgTypeMap = map[byte]interface{}{ TypeNatHoleResp: NatHoleResp{}, TypeNatHoleSid: NatHoleSid{}, TypeNatHoleReport: NatHoleReport{}, - TypeConnHead: ConnectHead{}, - TypeCryptoLogin: CryptoLogin{}, } var TypeNameNatHoleResp = reflect.TypeOf(&NatHoleResp{}).Elem().Name() @@ -73,38 +69,32 @@ type ClientSpec struct { // Optional values: ssh-tunnel Type string `json:"type,omitempty"` // If the value is true, the client will not require authentication. - AlwaysAuthPass bool `json:"auth_type,omitempty"` -} - -type CryptoLogin struct { - TimeStamp int64 `json:"time_stamp,omitempty"` - Auth string `json:"auth"` - Sign string `json:"sign,omitempty"` + AlwaysAuthPass bool `json:"always_auth_pass,omitempty"` } // When frpc start, client send this message to login to server. type Login struct { - Version string `json:"tag,omitempty"` - Hostname string `json:"path,omitempty"` - Os string `json:"system,omitempty"` - Arch string `json:"types,omitempty"` - User string `json:"people,omitempty"` - PrivilegeKey string `json:"identify,omitempty"` - Timestamp int64 `json:"time_second,omitempty"` - RunID string `json:"self_id,omitempty"` - Metas map[string]string `json:"data_bucket,omitempty"` + Version string `json:"version,omitempty"` + Hostname string `json:"hostname,omitempty"` + Os string `json:"os,omitempty"` + Arch string `json:"arch,omitempty"` + User string `json:"user,omitempty"` + PrivilegeKey string `json:"privilege_key,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` + RunID string `json:"run_id,omitempty"` + Metas map[string]string `json:"metas,omitempty"` // Currently only effective for VirtualClient. - ClientSpec ClientSpec `json:"other_data,omitempty"` + ClientSpec ClientSpec `json:"client_spec,omitempty"` // Some global configures. - PoolCount int `json:"count,omitempty"` + PoolCount int `json:"pool_count,omitempty"` } type LoginResp struct { - Version string `json:"tag,omitempty"` - RunID string `json:"self_id,omitempty"` - Error string `json:"error_msg,omitempty"` + Version string `json:"version,omitempty"` + RunID string `json:"run_id,omitempty"` + Error string `json:"error,omitempty"` } // When frpc login success, send this message to frps for running a new proxy. @@ -170,17 +160,17 @@ type StartWorkConn struct { } type NewVisitorConn struct { - RunID string `json:"dog_name,omitempty"` - ProxyName string `json:"cat_name,omitempty"` - SignKey string `json:"elephant_name,omitempty"` - Timestamp int64 `json:"duck_name,omitempty"` - UseEncryption bool `json:"monkey_name,omitempty"` - UseCompression bool `json:"snake_name,omitempty"` + RunID string `json:"run_id,omitempty"` + ProxyName string `json:"proxy_name,omitempty"` + SignKey string `json:"sign_key,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` + UseEncryption bool `json:"use_encryption,omitempty"` + UseCompression bool `json:"use_compression,omitempty"` } type NewVisitorConnResp struct { - ProxyName string `json:"panda_name,omitempty"` - Error string `json:"something,omitempty"` + ProxyName string `json:"proxy_name,omitempty"` + Error string `json:"error,omitempty"` } type Ping struct { @@ -254,7 +244,3 @@ type NatHoleReport struct { Sid string `json:"sid,omitempty"` Success bool `json:"success,omitempty"` } - -type ConnectHead struct { - ServiceName string `json:"serviceName"` -} diff --git a/pkg/plugin/server/manager.go b/pkg/plugin/server/manager.go index b3f66421460..ed96444ac22 100644 --- a/pkg/plugin/server/manager.go +++ b/pkg/plugin/server/manager.go @@ -48,21 +48,21 @@ func (m *Manager) Register(p Plugin) { if p.IsSupport(OpLogin) { m.loginPlugins = append(m.loginPlugins, p) } - //if p.IsSupport(OpNewProxy) { - // m.newProxyPlugins = append(m.newProxyPlugins, p) - //} - //if p.IsSupport(OpCloseProxy) { - // m.closeProxyPlugins = append(m.closeProxyPlugins, p) - //} - //if p.IsSupport(OpPing) { - // m.pingPlugins = append(m.pingPlugins, p) - //} - //if p.IsSupport(OpNewWorkConn) { - // m.newWorkConnPlugins = append(m.newWorkConnPlugins, p) - //} - //if p.IsSupport(OpNewUserConn) { - // m.newUserConnPlugins = append(m.newUserConnPlugins, p) - //} + if p.IsSupport(OpNewProxy) { + m.newProxyPlugins = append(m.newProxyPlugins, p) + } + if p.IsSupport(OpCloseProxy) { + m.closeProxyPlugins = append(m.closeProxyPlugins, p) + } + if p.IsSupport(OpPing) { + m.pingPlugins = append(m.pingPlugins, p) + } + if p.IsSupport(OpNewWorkConn) { + m.newWorkConnPlugins = append(m.newWorkConnPlugins, p) + } + if p.IsSupport(OpNewUserConn) { + m.newUserConnPlugins = append(m.newUserConnPlugins, p) + } } func (m *Manager) Login(content *LoginContent) (*LoginContent, error) { diff --git a/pkg/util/net/dial.go b/pkg/util/net/dial.go index 6f29200cb9c..1a3859edfa7 100644 --- a/pkg/util/net/dial.go +++ b/pkg/util/net/dial.go @@ -11,9 +11,8 @@ import ( func DialHookCustomTLSHeadByte(enableTLS bool, disableCustomTLSHeadByte bool) libnet.AfterHookFunc { return func(ctx context.Context, c net.Conn, addr string) (context.Context, net.Conn, error) { - if enableTLS { - //_, err := c.Write([]byte{byte(FRPTLSHeadByte)}) - _, err := c.Write(FRPTLSHeadByte) + if enableTLS && !disableCustomTLSHeadByte { + _, err := c.Write([]byte{byte(FRPTLSHeadByte)}) if err != nil { return nil, nil, err } diff --git a/pkg/util/net/tls.go b/pkg/util/net/tls.go index 8311b78f72b..89b9d9656d8 100644 --- a/pkg/util/net/tls.go +++ b/pkg/util/net/tls.go @@ -23,13 +23,13 @@ import ( libnet "github.com/fatedier/golib/net" ) -var FRPTLSHeadByte = []byte{'e', 'd', 'g', 'e', 'w', 'i', 'z', 'e', 't', 'l', 's'} +var FRPTLSHeadByte = 0x8f func CheckAndEnableTLSServerConnWithTimeout( c net.Conn, tlsConfig *tls.Config, tlsOnly bool, timeout time.Duration, ) (out net.Conn, isTLS bool, custom bool, err error) { sc, r := libnet.NewSharedConnSize(c, 2) - buf := make([]byte, len(FRPTLSHeadByte)) + buf := make([]byte, 1) var n int _ = c.SetReadDeadline(time.Now().Add(timeout)) n, err = r.Read(buf) @@ -39,14 +39,10 @@ func CheckAndEnableTLSServerConnWithTimeout( } switch { - case n == len(FRPTLSHeadByte) && BytesEqual(buf, FRPTLSHeadByte): + case n == 1 && int(buf[0]) == FRPTLSHeadByte: out = tls.Server(c, tlsConfig) isTLS = true custom = true - // 取消对原版frpc的tls兼容 - //case n == 1 && int(buf[0]) == 0x16: - // out = tls.Server(sc, tlsConfig) - // isTLS = true default: if tlsOnly { err = fmt.Errorf("non-TLS connection received on a TlsOnly server") @@ -56,15 +52,3 @@ func CheckAndEnableTLSServerConnWithTimeout( } return } - -func BytesEqual(a, b []byte) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true -} diff --git a/pkg/util/util/edgewize_util.go b/pkg/util/util/edgewize_util.go new file mode 100644 index 00000000000..b55f62aafa4 --- /dev/null +++ b/pkg/util/util/edgewize_util.go @@ -0,0 +1,68 @@ +package util + +import ( + "bytes" + "crypto/cipher" + "crypto/des" + "crypto/md5" + "encoding/hex" + mathrand "math/rand/v2" +) + +func Encrypt(src, key string, iv []byte) []byte { + data := []byte(src) + keyByte := []byte(key) + block, err := des.NewCipher(keyByte) + if err != nil { + panic(err) + } + //data = padding.PKCS7Padding(data, block.BlockSize()) + data = PKCS7Padding(data, block.BlockSize()) + mode := cipher.NewCBCEncrypter(block, iv) + out := make([]byte, len(data)) + mode.CryptBlocks(out, data) + return out +} + +func Decrypt(data []byte, key string, iv []byte) []byte { + keyByte := []byte(key) + block, err := des.NewCipher(keyByte) + if err != nil { + panic(err) + } + mode := cipher.NewCBCDecrypter(block, iv) + plaintext := make([]byte, len(data)) + mode.CryptBlocks(plaintext, data) + //plaintext = padding.PKCS5UnPadding(plaintext) + plaintext = PKCS7UnPadding(plaintext, block.BlockSize()) + return plaintext +} + +func PKCS7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +func PKCS7UnPadding(plantText []byte, blockSize int) []byte { + length := len(plantText) + unpadding := int(plantText[length-1]) + return plantText[:(length - unpadding)] +} + +func GenerateAesKey(k string) string { + m := md5.New() + m.Write([]byte(k)) + return hex.EncodeToString(m.Sum(nil)) +} + +var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + +func RandomString(length int) string { + result := make([]byte, length) + for i := 0; i < length; i++ { + result[i] = chars[mathrand.IntN(len(chars))] + } + + return string(result) +} diff --git a/pkg/util/util/util.go b/pkg/util/util/util.go index da44a2372b0..7758054d948 100644 --- a/pkg/util/util/util.go +++ b/pkg/util/util/util.go @@ -15,9 +15,6 @@ package util import ( - "bytes" - "crypto/cipher" - "crypto/des" "crypto/md5" "crypto/rand" "crypto/subtle" @@ -55,9 +52,7 @@ func GetAuthKey(token string, timestamp int64) (key string) { md5Ctx.Write([]byte(token)) md5Ctx.Write([]byte(strconv.FormatInt(timestamp, 10))) data := md5Ctx.Sum(nil) - after := hex.EncodeToString(data) - fmt.Println(fmt.Sprintf("token=%s, timestamp=%d,data=%s", token, timestamp, after)) - return after + return hex.EncodeToString(data) } func CanonicalAddr(host string, port int) (addr string) { @@ -139,61 +134,3 @@ func RandomSleep(duration time.Duration, minRatio, maxRatio float64) time.Durati func ConstantTimeEqString(a, b string) bool { return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1 } - -func Encrypt(src, key string, iv []byte) []byte { - data := []byte(src) - keyByte := []byte(key) - block, err := des.NewCipher(keyByte) - if err != nil { - panic(err) - } - //data = padding.PKCS7Padding(data, block.BlockSize()) - data = PKCS7Padding(data, block.BlockSize()) - mode := cipher.NewCBCEncrypter(block, iv) - out := make([]byte, len(data)) - mode.CryptBlocks(out, data) - return out -} - -func Decrypt(data []byte, key string, iv []byte) []byte { - keyByte := []byte(key) - block, err := des.NewCipher(keyByte) - if err != nil { - panic(err) - } - mode := cipher.NewCBCDecrypter(block, iv) - plaintext := make([]byte, len(data)) - mode.CryptBlocks(plaintext, data) - //plaintext = padding.PKCS5UnPadding(plaintext) - plaintext = PKCS7UnPadding(plaintext, block.BlockSize()) - return plaintext -} - -func PKCS7Padding(ciphertext []byte, blockSize int) []byte { - padding := blockSize - len(ciphertext)%blockSize - padtext := bytes.Repeat([]byte{byte(padding)}, padding) - return append(ciphertext, padtext...) -} - -func PKCS7UnPadding(plantText []byte, blockSize int) []byte { - length := len(plantText) - unpadding := int(plantText[length-1]) - return plantText[:(length - unpadding)] -} - -func GenerateAesKey(k string) string { - m := md5.New() - m.Write([]byte(k)) - return hex.EncodeToString(m.Sum(nil)) -} - -var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - -func RandomString(length int) string { - result := make([]byte, length) - for i := 0; i < length; i++ { - result[i] = chars[mathrand.IntN(len(chars))] - } - - return string(result) -} diff --git a/pkg/util/version/version.go b/pkg/util/version/version.go index 561a52e702b..64fcc7f0581 100644 --- a/pkg/util/version/version.go +++ b/pkg/util/version/version.go @@ -14,7 +14,7 @@ package version -var version = "0.59.0" +var version = "edgewize-transporter:v0.0.1" func Full() string { return version diff --git a/pkg/util/vhost/resource.go b/pkg/util/vhost/resource.go index f39d00aa1f9..be41694332a 100644 --- a/pkg/util/vhost/resource.go +++ b/pkg/util/vhost/resource.go @@ -16,6 +16,7 @@ package vhost import ( "bytes" + "github.com/fatedier/frp/pkg/util/version" "io" "net/http" "os" @@ -68,7 +69,7 @@ func getNotFoundPageContent() []byte { func NotFoundResponse() *http.Response { header := make(http.Header) - //header.Set("server", "frp/"+version.Full()) + header.Set("server", "transporter/"+version.Full()) header.Set("Content-Type", "text/html") content := getNotFoundPageContent() diff --git a/server/control.go b/server/control.go index ea9114f35ad..4b46813c29e 100644 --- a/server/control.go +++ b/server/control.go @@ -17,6 +17,7 @@ package server import ( "context" "fmt" + "github.com/fatedier/frp/pkg/util/version" "net" "runtime/debug" "sync" @@ -201,8 +202,7 @@ func NewControl( // Start send a login success message to client and start working. func (ctl *Control) Start() { loginRespMsg := &msg.LoginResp{ - //Version: version.Full(), - Version: "edgewize-msg-transport-v1", + Version: version.Full(), RunID: ctl.runID, Error: "", } diff --git a/server/dashboard_api.go b/server/dashboard_api.go index b14b851466f..f0f0ee99760 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -17,6 +17,7 @@ package server import ( "cmp" "encoding/json" + "github.com/fatedier/frp/pkg/util/version" "net/http" "slices" @@ -106,8 +107,7 @@ func (svr *Service) apiServerInfo(w http.ResponseWriter, r *http.Request) { log.Infof("Http request: [%s]", r.URL.Path) serverStats := mem.StatsCollector.GetServer() svrResp := serverInfoResp{ - //Version: version.Full(), - Version: "edgewize-msg-transport-v1", + Version: version.Full(), BindPort: svr.cfg.BindPort, VhostHTTPPort: svr.cfg.VhostHTTPPort, VhostHTTPSPort: svr.cfg.VhostHTTPSPort, diff --git a/server/edgewize_service.go b/server/edgewize_service.go new file mode 100644 index 00000000000..165314eb46b --- /dev/null +++ b/server/edgewize_service.go @@ -0,0 +1,112 @@ +package server + +import ( + "context" + "fmt" + "github.com/fatedier/frp/server/visitor" + "net" + "strconv" + "time" + + "github.com/fatedier/frp/pkg/auth" + v1 "github.com/fatedier/frp/pkg/config/v1" + modelmetrics "github.com/fatedier/frp/pkg/metrics" + plugin "github.com/fatedier/frp/pkg/plugin/server" + "github.com/fatedier/frp/pkg/transport" + httppkg "github.com/fatedier/frp/pkg/util/http" + "github.com/fatedier/frp/pkg/util/log" + netpkg "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/tcpmux" + "github.com/fatedier/frp/server/controller" + "github.com/fatedier/frp/server/proxy" + "github.com/fatedier/golib/net/mux" +) + +func NewEdgewizeService(cfg *v1.ServerConfig) (*Service, error) { + tlsConfig, err := transport.NewServerTLSConfig( + cfg.Transport.TLS.CertFile, + cfg.Transport.TLS.KeyFile, + cfg.Transport.TLS.TrustedCaFile) + if err != nil { + return nil, err + } + + var webServer *httppkg.Server + if cfg.WebServer.Port > 0 { + ws, err := httppkg.NewServer(cfg.WebServer) + if err != nil { + return nil, err + } + webServer = ws + + modelmetrics.EnableMem() + if cfg.EnablePrometheus { + modelmetrics.EnablePrometheus() + } + } + + svr := &Service{ + ctlManager: NewControlManager(), + pxyManager: proxy.NewManager(), + pluginManager: plugin.NewManager(), + rc: &controller.ResourceController{ + VisitorManager: visitor.NewManager(), + }, + authVerifier: auth.NewAuthVerifier(cfg.Auth), + tlsConfig: tlsConfig, + cfg: cfg, + ctx: context.Background(), + } + if webServer != nil { + webServer.RouteRegister(svr.registerRouteHandlers) + } + + // Create tcpmux httpconnect multiplexer. + if cfg.TCPMuxHTTPConnectPort > 0 { + var l net.Listener + address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.TCPMuxHTTPConnectPort)) + l, err = net.Listen("tcp", address) + if err != nil { + return nil, fmt.Errorf("create server listener error, %v", err) + } + + svr.rc.TCPMuxHTTPConnectMuxer, err = tcpmux.NewHTTPConnectTCPMuxer(l, cfg.TCPMuxPassthrough, vhostReadWriteTimeout) + if err != nil { + return nil, fmt.Errorf("create vhost tcpMuxer error, %v", err) + } + log.Infof("tcpmux httpconnect multiplexer listen on %s, passthough: %v", address, cfg.TCPMuxPassthrough) + } + + // Init all plugins + for _, p := range cfg.HTTPPlugins { + svr.pluginManager.Register(plugin.NewHTTPPluginOptions(p)) + log.Infof("plugin [%s] has been registered", p.Name) + } + svr.rc.PluginManager = svr.pluginManager + + // Listen for accepting connections from client. + address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindPort)) + ln, err := net.Listen("tcp", address) + if err != nil { + return nil, fmt.Errorf("create server listener error, %v", err) + } + + svr.muxer = mux.NewMux(ln) + svr.muxer.SetKeepAlive(time.Duration(cfg.Transport.TCPKeepAlive) * time.Second) + go func() { + _ = svr.muxer.Serve() + }() + ln = svr.muxer.DefaultListener() + + svr.listener = ln + log.Infof("frps tcp listen on %s", address) + + // Create https vhost muxer. + + // frp tls listener + svr.tlsListener = svr.muxer.Listen(2, 1, func(data []byte) bool { + // tls first byte can be 0x16 only when vhost https port is not same with bind port + return int(data[0]) == netpkg.FRPTLSHeadByte + }) + return svr, nil +} diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go index fe8bb89bfe9..d5ab0f13ae5 100644 --- a/server/proxy/proxy.go +++ b/server/proxy/proxy.go @@ -143,12 +143,10 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn, if src != nil { srcAddr, srcPortStr, _ = net.SplitHostPort(src.String()) - srcAddr = "1.2.3.4" srcPort, _ = strconv.Atoi(srcPortStr) } if dst != nil { dstAddr, dstPortStr, _ = net.SplitHostPort(dst.String()) - dstAddr = "4.3.2.1" dstPort, _ = strconv.Atoi(dstPortStr) } err := msg.WriteMsg(workConn, &msg.StartWorkConn{ diff --git a/server/service.go b/server/service.go index 2673e5da6cb..5c005afc1da 100644 --- a/server/service.go +++ b/server/service.go @@ -15,12 +15,17 @@ package server import ( + "bytes" "context" "crypto/tls" "fmt" + "github.com/fatedier/frp/pkg/nathole" + "github.com/fatedier/frp/server/group" + "github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/visitor" "io" "net" + "net/http" "os" "strconv" "time" @@ -150,16 +155,16 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { pluginManager: plugin.NewManager(), rc: &controller.ResourceController{ VisitorManager: visitor.NewManager(), - //TCPPortManager: ports.NewManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts), - //UDPPortManager: ports.NewManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts), + TCPPortManager: ports.NewManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts), + UDPPortManager: ports.NewManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts), }, - //sshTunnelListener: netpkg.NewInternalListener(), - //httpVhostRouter: vhost.NewRouters(), - authVerifier: auth.NewAuthVerifier(cfg.Auth), - //webServer: webServer, - tlsConfig: tlsConfig, - cfg: cfg, - ctx: context.Background(), + sshTunnelListener: netpkg.NewInternalListener(), + httpVhostRouter: vhost.NewRouters(), + authVerifier: auth.NewAuthVerifier(cfg.Auth), + webServer: webServer, + tlsConfig: tlsConfig, + cfg: cfg, + ctx: context.Background(), } if webServer != nil { webServer.RouteRegister(svr.registerRouteHandlers) @@ -189,29 +194,29 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { svr.rc.PluginManager = svr.pluginManager // Init group controller - //svr.rc.TCPGroupCtl = group.NewTCPGroupCtl(svr.rc.TCPPortManager) + svr.rc.TCPGroupCtl = group.NewTCPGroupCtl(svr.rc.TCPPortManager) // Init HTTP group controller - //svr.rc.HTTPGroupCtl = group.NewHTTPGroupController(svr.httpVhostRouter) + svr.rc.HTTPGroupCtl = group.NewHTTPGroupController(svr.httpVhostRouter) // Init TCP mux group controller - //svr.rc.TCPMuxGroupCtl = group.NewTCPMuxGroupCtl(svr.rc.TCPMuxHTTPConnectMuxer) + svr.rc.TCPMuxGroupCtl = group.NewTCPMuxGroupCtl(svr.rc.TCPMuxHTTPConnectMuxer) // Init 404 not found page - //vhost.NotFoundPagePath = cfg.Custom404Page - - //var ( - // httpMuxOn bool - // httpsMuxOn bool - //) - //if cfg.BindAddr == cfg.ProxyBindAddr { - // if cfg.BindPort == cfg.VhostHTTPPort { - // httpMuxOn = true - // } - // if cfg.BindPort == cfg.VhostHTTPSPort { - // httpsMuxOn = true - // } - //} + vhost.NotFoundPagePath = cfg.Custom404Page + + var ( + httpMuxOn bool + httpsMuxOn bool + ) + if cfg.BindAddr == cfg.ProxyBindAddr { + if cfg.BindPort == cfg.VhostHTTPPort { + httpMuxOn = true + } + if cfg.BindPort == cfg.VhostHTTPSPort { + httpsMuxOn = true + } + } // Listen for accepting connections from client. address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.BindPort)) @@ -232,105 +237,105 @@ func NewService(cfg *v1.ServerConfig) (*Service, error) { // Listen for accepting connections from client using kcp protocol. if cfg.KCPBindPort > 0 { - //address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) - //svr.kcpListener, err = netpkg.ListenKcp(address) - //if err != nil { - // return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err) - //} - //log.Infof("frps kcp listen on udp %s", address) + address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.KCPBindPort)) + svr.kcpListener, err = netpkg.ListenKcp(address) + if err != nil { + return nil, fmt.Errorf("listen on kcp udp address %s error: %v", address, err) + } + log.Infof("frps kcp listen on udp %s", address) } if cfg.QUICBindPort > 0 { - //address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort)) - //quicTLSCfg := tlsConfig.Clone() - //quicTLSCfg.NextProtos = []string{"frp"} - //svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{ - // MaxIdleTimeout: time.Duration(cfg.Transport.QUIC.MaxIdleTimeout) * time.Second, - // MaxIncomingStreams: int64(cfg.Transport.QUIC.MaxIncomingStreams), - // KeepAlivePeriod: time.Duration(cfg.Transport.QUIC.KeepalivePeriod) * time.Second, - //}) - //if err != nil { - // return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err) - //} - //log.Infof("frps quic listen on %s", address) - } - - //if cfg.SSHTunnelGateway.BindPort > 0 { - // sshGateway, err := ssh.NewGateway(cfg.SSHTunnelGateway, cfg.ProxyBindAddr, svr.sshTunnelListener) - // if err != nil { - // return nil, fmt.Errorf("create ssh gateway error: %v", err) - // } - // svr.sshTunnelGateway = sshGateway - // log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort) - //} + address := net.JoinHostPort(cfg.BindAddr, strconv.Itoa(cfg.QUICBindPort)) + quicTLSCfg := tlsConfig.Clone() + quicTLSCfg.NextProtos = []string{"frp"} + svr.quicListener, err = quic.ListenAddr(address, quicTLSCfg, &quic.Config{ + MaxIdleTimeout: time.Duration(cfg.Transport.QUIC.MaxIdleTimeout) * time.Second, + MaxIncomingStreams: int64(cfg.Transport.QUIC.MaxIncomingStreams), + KeepAlivePeriod: time.Duration(cfg.Transport.QUIC.KeepalivePeriod) * time.Second, + }) + if err != nil { + return nil, fmt.Errorf("listen on quic udp address %s error: %v", address, err) + } + log.Infof("frps quic listen on %s", address) + } + + if cfg.SSHTunnelGateway.BindPort > 0 { + sshGateway, err := ssh.NewGateway(cfg.SSHTunnelGateway, cfg.ProxyBindAddr, svr.sshTunnelListener) + if err != nil { + return nil, fmt.Errorf("create ssh gateway error: %v", err) + } + svr.sshTunnelGateway = sshGateway + log.Infof("frps sshTunnelGateway listen on port %d", cfg.SSHTunnelGateway.BindPort) + } // Listen for accepting connections from client using websocket protocol. - //websocketPrefix := []byte("GET " + netpkg.FrpWebsocketPath) - //websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool { - // return bytes.Equal(data, websocketPrefix) - //}) - //svr.websocketListener = netpkg.NewWebsocketListener(websocketLn) + websocketPrefix := []byte("GET " + netpkg.FrpWebsocketPath) + websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool { + return bytes.Equal(data, websocketPrefix) + }) + svr.websocketListener = netpkg.NewWebsocketListener(websocketLn) // Create http vhost muxer. if cfg.VhostHTTPPort > 0 { - //rp := vhost.NewHTTPReverseProxy(vhost.HTTPReverseProxyOptions{ - // ResponseHeaderTimeoutS: cfg.VhostHTTPTimeout, - //}, svr.httpVhostRouter) - //svr.rc.HTTPReverseProxy = rp - // - //address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort)) - //server := &http.Server{ - // Addr: address, - // Handler: rp, - // ReadHeaderTimeout: 60 * time.Second, - //} - //var l net.Listener - //if httpMuxOn { - // l = svr.muxer.ListenHTTP(1) - //} else { - // l, err = net.Listen("tcp", address) - // if err != nil { - // return nil, fmt.Errorf("create vhost http listener error, %v", err) - // } - //} - //go func() { - // _ = server.Serve(l) - //}() - //log.Infof("http service listen on %s", address) + rp := vhost.NewHTTPReverseProxy(vhost.HTTPReverseProxyOptions{ + ResponseHeaderTimeoutS: cfg.VhostHTTPTimeout, + }, svr.httpVhostRouter) + svr.rc.HTTPReverseProxy = rp + + address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort)) + server := &http.Server{ + Addr: address, + Handler: rp, + ReadHeaderTimeout: 60 * time.Second, + } + var l net.Listener + if httpMuxOn { + l = svr.muxer.ListenHTTP(1) + } else { + l, err = net.Listen("tcp", address) + if err != nil { + return nil, fmt.Errorf("create vhost http listener error, %v", err) + } + } + go func() { + _ = server.Serve(l) + }() + log.Infof("http service listen on %s", address) } // Create https vhost muxer. if cfg.VhostHTTPSPort > 0 { - //var l net.Listener - //if httpsMuxOn { - // l = svr.muxer.ListenHTTPS(1) - //} else { - // address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) - // l, err = net.Listen("tcp", address) - // if err != nil { - // return nil, fmt.Errorf("create server listener error, %v", err) - // } - // log.Infof("https service listen on %s", address) - //} - - //svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) - //if err != nil { - // return nil, fmt.Errorf("create vhost httpsMuxer error, %v", err) - //} + var l net.Listener + if httpsMuxOn { + l = svr.muxer.ListenHTTPS(1) + } else { + address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort)) + l, err = net.Listen("tcp", address) + if err != nil { + return nil, fmt.Errorf("create server listener error, %v", err) + } + log.Infof("https service listen on %s", address) + } + + svr.rc.VhostHTTPSMuxer, err = vhost.NewHTTPSMuxer(l, vhostReadWriteTimeout) + if err != nil { + return nil, fmt.Errorf("create vhost httpsMuxer error, %v", err) + } } // frp tls listener - svr.tlsListener = svr.muxer.Listen(2, uint32(len(netpkg.FRPTLSHeadByte)), func(data []byte) bool { + svr.tlsListener = svr.muxer.Listen(2, 1, func(data []byte) bool { // tls first byte can be 0x16 only when vhost https port is not same with bind port - return netpkg.BytesEqual(data, netpkg.FRPTLSHeadByte) //|| int(data[0]) == 0x16 取消对原版FRPC的TLS兼容 + return int(data[0]) == netpkg.FRPTLSHeadByte || int(data[0]) == 0x16 }) // Create nat hole controller. - //nc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour) - //if err != nil { - // return nil, fmt.Errorf("create nat hole controller error, %v", err) - //} - //svr.rc.NatHoleController = nc + nc, err := nathole.NewController(time.Duration(cfg.NatHoleAnalysisDataReserveHours) * time.Hour) + if err != nil { + return nil, fmt.Errorf("create nat hole controller error, %v", err) + } + svr.rc.NatHoleController = nc return svr, nil } From 01d37aad3ebfa8446df24f25bd932949c1a4427f Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Fri, 8 Nov 2024 14:33:50 +0800 Subject: [PATCH 07/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/admin_api.go | 26 +++++++++++++------------- client/service.go | 3 ++- client/visitor/stcp.go | 8 +++++--- cmd/frpc/sub/root.go | 2 +- pkg/auth/oidc.go | 3 ++- pkg/transport/tls.go | 1 + pkg/util/vhost/resource.go | 2 +- server/control.go | 2 +- server/dashboard_api.go | 2 +- server/service.go | 8 ++++---- 10 files changed, 31 insertions(+), 26 deletions(-) diff --git a/client/admin_api.go b/client/admin_api.go index dfeac95ef71..708b2cbd9e6 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -31,6 +31,7 @@ import ( "github.com/fatedier/frp/pkg/config/v1/validation" httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" + netpkg "github.com/fatedier/frp/pkg/util/net" ) type GeneralResponse struct { @@ -39,27 +40,26 @@ type GeneralResponse struct { } func (svr *Service) registerRouteHandlers(helper *httppkg.RouterRegisterHelper) { - //helper.Router.HandleFunc("/healthz", svr.healthz) + helper.Router.HandleFunc("/healthz", svr.healthz) subRouter := helper.Router.NewRoute().Subrouter() subRouter.Use(helper.AuthMiddleware.Middleware) // api, see admin_api.go - // 取消reload以外的所有开放api subRouter.HandleFunc("/api/reload", svr.apiReload).Methods("GET") - //subRouter.HandleFunc("/api/stop", svr.apiStop).Methods("POST") - //subRouter.HandleFunc("/api/status", svr.apiStatus).Methods("GET") - //subRouter.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET") - //subRouter.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT") + subRouter.HandleFunc("/api/stop", svr.apiStop).Methods("POST") + subRouter.HandleFunc("/api/status", svr.apiStatus).Methods("GET") + subRouter.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET") + subRouter.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT") // view - //subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET") - //subRouter.PathPrefix("/static/").Handler( - // netpkg.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(helper.AssetsFS))), - //).Methods("GET") - //subRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // http.Redirect(w, r, "/static/", http.StatusMovedPermanently) - //}) + subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET") + subRouter.PathPrefix("/static/").Handler( + netpkg.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(helper.AssetsFS))), + ).Methods("GET") + subRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/static/", http.StatusMovedPermanently) + }) } // /healthz diff --git a/client/service.go b/client/service.go index 75a9cf6e2b8..c87292aa5e8 100644 --- a/client/service.go +++ b/client/service.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "github.com/fatedier/frp/pkg/util/version" "net" "os" "runtime" @@ -248,7 +249,7 @@ func (svr *Service) login() (conn net.Conn, connector Connector, err error) { Os: runtime.GOOS, PoolCount: svr.common.Transport.PoolCount, User: svr.common.User, - Version: "edgewize-msg-transport-v1", + Version: version.Full(), Timestamp: time.Now().Unix(), RunID: svr.runID, Metas: svr.common.Metadatas, diff --git a/client/visitor/stcp.go b/client/visitor/stcp.go index 43e33e053b9..31386517937 100644 --- a/client/visitor/stcp.go +++ b/client/visitor/stcp.go @@ -79,9 +79,6 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { xl := xlog.FromContextSafe(sv.ctx) defer userConn.Close() - var head msg.ConnectHead - _ = msg.ReadMsgInto(userConn, &head) - xl.Debugf("get a new stcp user connection") visitorConn, err := sv.helper.ConnectServer() if err != nil { @@ -98,9 +95,14 @@ func (sv *STCPVisitor) handleConn(userConn net.Conn) { UseEncryption: sv.cfg.Transport.UseEncryption, UseCompression: sv.cfg.Transport.UseCompression, } + + // 支持单个frpc端口监听多个frpc目的服务 + var head msg.ConnectHead + _ = msg.ReadMsgInto(userConn, &head) if head.ServiceName != "" { newVisitorConnMsg.ProxyName = head.ServiceName } + err = msg.WriteMsg(visitorConn, newVisitorConnMsg) if err != nil { xl.Warnf("send newVisitorConnMsg to server error: %v", err) diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index 39a7a49b11a..b844ddfd5e9 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -17,7 +17,6 @@ package sub import ( "context" "fmt" - "github.com/fatedier/frp/pkg/util/version" "io/fs" "os" "os/signal" @@ -33,6 +32,7 @@ import ( v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/config/v1/validation" "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/pkg/util/version" ) var ( diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index 2881af9c0e6..d87420ff764 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -17,9 +17,10 @@ package auth import ( "context" "fmt" + "slices" + "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2/clientcredentials" - "slices" v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/msg" diff --git a/pkg/transport/tls.go b/pkg/transport/tls.go index 939c85a73b8..5bc75921cbd 100644 --- a/pkg/transport/tls.go +++ b/pkg/transport/tls.go @@ -108,6 +108,7 @@ func NewClientTLSConfig(certPath, keyPath, caPath, serverName string) (*tls.Conf if err != nil { return nil, err } + base.Certificates = []tls.Certificate{*cert} } diff --git a/pkg/util/vhost/resource.go b/pkg/util/vhost/resource.go index be41694332a..5981c192e34 100644 --- a/pkg/util/vhost/resource.go +++ b/pkg/util/vhost/resource.go @@ -16,12 +16,12 @@ package vhost import ( "bytes" - "github.com/fatedier/frp/pkg/util/version" "io" "net/http" "os" "github.com/fatedier/frp/pkg/util/log" + "github.com/fatedier/frp/pkg/util/version" ) var NotFoundPagePath = "" diff --git a/server/control.go b/server/control.go index 4b46813c29e..0b6b31741b0 100644 --- a/server/control.go +++ b/server/control.go @@ -17,7 +17,6 @@ package server import ( "context" "fmt" - "github.com/fatedier/frp/pkg/util/version" "net" "runtime/debug" "sync" @@ -35,6 +34,7 @@ import ( "github.com/fatedier/frp/pkg/transport" netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" + "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/wait" "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" diff --git a/server/dashboard_api.go b/server/dashboard_api.go index f0f0ee99760..f34da4ef513 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -17,7 +17,6 @@ package server import ( "cmp" "encoding/json" - "github.com/fatedier/frp/pkg/util/version" "net/http" "slices" @@ -30,6 +29,7 @@ import ( httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" netpkg "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/version" ) type GeneralResponse struct { diff --git a/server/service.go b/server/service.go index 5c005afc1da..f9fd3e2231c 100644 --- a/server/service.go +++ b/server/service.go @@ -19,10 +19,6 @@ import ( "context" "crypto/tls" "fmt" - "github.com/fatedier/frp/pkg/nathole" - "github.com/fatedier/frp/server/group" - "github.com/fatedier/frp/server/ports" - "github.com/fatedier/frp/server/visitor" "io" "net" "net/http" @@ -40,6 +36,7 @@ import ( v1 "github.com/fatedier/frp/pkg/config/v1" modelmetrics "github.com/fatedier/frp/pkg/metrics" "github.com/fatedier/frp/pkg/msg" + "github.com/fatedier/frp/pkg/nathole" plugin "github.com/fatedier/frp/pkg/plugin/server" "github.com/fatedier/frp/pkg/ssh" "github.com/fatedier/frp/pkg/transport" @@ -51,8 +48,11 @@ import ( "github.com/fatedier/frp/pkg/util/vhost" "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" + "github.com/fatedier/frp/server/group" "github.com/fatedier/frp/server/metrics" + "github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/proxy" + "github.com/fatedier/frp/server/visitor" ) const ( From 25d9e025b350bc92ed8c1c3fad1d3075ea02c686 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Fri, 8 Nov 2024 14:46:35 +0800 Subject: [PATCH 08/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/service.go | 2 +- server/service.go | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/service.go b/client/service.go index c87292aa5e8..bccf0dd62f3 100644 --- a/client/service.go +++ b/client/service.go @@ -18,7 +18,6 @@ import ( "context" "errors" "fmt" - "github.com/fatedier/frp/pkg/util/version" "net" "os" "runtime" @@ -35,6 +34,7 @@ import ( httppkg "github.com/fatedier/frp/pkg/util/http" "github.com/fatedier/frp/pkg/util/log" netpkg "github.com/fatedier/frp/pkg/util/net" + "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/wait" "github.com/fatedier/frp/pkg/util/xlog" ) diff --git a/server/service.go b/server/service.go index f9fd3e2231c..8b56d9a6812 100644 --- a/server/service.go +++ b/server/service.go @@ -45,6 +45,7 @@ import ( netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/tcpmux" "github.com/fatedier/frp/pkg/util/util" + "github.com/fatedier/frp/pkg/util/version" "github.com/fatedier/frp/pkg/util/vhost" "github.com/fatedier/frp/pkg/util/xlog" "github.com/fatedier/frp/server/controller" @@ -432,6 +433,7 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna _ = conn.SetReadDeadline(time.Time{}) switch m := rawMsg.(type) { + // 修改接入流程。需要先读出登录的加密信息,然后解密得到登录的完整信息,最后才能按照原登录逻辑处理 case *msg.CryptoLogin: login := svr.authVerifier.VerifyCrypto(m) if login == nil { @@ -454,15 +456,15 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna if err != nil { xl.Warnf("register control error: %v", err) _ = msg.WriteMsg(conn, &msg.LoginResp{ - //Version: version.Full(), - Version: "edgewize-msg-transport-v1", + Version: version.Full(), Error: util.GenerateResponseErrorString("register control error", err, lo.FromPtr(svr.cfg.DetailedErrorsToClient)), }) conn.Close() } case *msg.Login: + // 禁止原生frp接入,不接受直接的登录信息输入 // server plugin hook - log.Warnf("有人使用原生FRP登录!") + log.Warnf("Error message type for the new connection [%s]", conn.RemoteAddr().String()) conn.Close() case *msg.NewWorkConn: if err := svr.RegisterWorkConn(conn, m); err != nil { From 5af342ddad65f0bbe785daf26ff6082ccb85535c Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Fri, 8 Nov 2024 17:10:52 +0800 Subject: [PATCH 09/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 10 +++++----- cmd/{frpc => transporter-client}/main.go | 2 +- cmd/{frpc => transporter-client}/sub/admin.go | 0 cmd/{frpc => transporter-client}/sub/nathole.go | 10 +++++----- cmd/{frpc => transporter-client}/sub/proxy.go | 12 ++++++------ cmd/{frpc => transporter-client}/sub/root.go | 6 +++--- cmd/{frpc => transporter-client}/sub/verify.go | 2 +- cmd/{frps => transporter-server}/main.go | 0 cmd/{frps => transporter-server}/root.go | 4 ++-- cmd/{frps => transporter-server}/verify.go | 0 pkg/msg/edgewize_msg.go | 8 +++++--- 11 files changed, 28 insertions(+), 26 deletions(-) rename cmd/{frpc => transporter-client}/main.go (93%) rename cmd/{frpc => transporter-client}/sub/admin.go (100%) rename cmd/{frpc => transporter-client}/sub/nathole.go (87%) rename cmd/{frpc => transporter-client}/sub/proxy.go (96%) rename cmd/{frpc => transporter-client}/sub/root.go (96%) rename cmd/{frpc => transporter-client}/sub/verify.go (97%) rename cmd/{frps => transporter-server}/main.go (100%) rename cmd/{frps => transporter-server}/root.go (97%) rename cmd/{frps => transporter-server}/verify.go (100%) diff --git a/Makefile b/Makefile index 0deb8a54715..86f3254526d 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,10 @@ vet: go vet ./... router-server: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-server ./cmd/frps + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-server ./cmd/transporter-server router-client: - env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-client ./cmd/frpc + env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/router-client ./cmd/transporter-client test: gotest @@ -71,14 +71,14 @@ clean: rm -rf ./lastversion router-server-images: - docker build . --file build/server/Dockerfile --tag $(REPO)/router-server:$(VER) --push + docker build . --file build/server/Dockerfile --tag $(REPO)/router-server:$(TAG) --push router-client-images: - docker build . --file build/client/Dockerfile --tag $(REPO)/router-client:$(VER) --push + docker build . --file build/client/Dockerfile --tag $(REPO)/router-client:$(TAG) --push image-all: router-server-images router-client-images -# make docker REPO=harbor.dev.thingsdao.com/edgewize VER=v0.1.13 +# make docker REPO=harbor.dev.thingsdao.com/edgewize TAG=v0.1.13 docker: make build make image-all diff --git a/cmd/frpc/main.go b/cmd/transporter-client/main.go similarity index 93% rename from cmd/frpc/main.go rename to cmd/transporter-client/main.go index f7651bca169..85ea6dd5211 100644 --- a/cmd/frpc/main.go +++ b/cmd/transporter-client/main.go @@ -16,7 +16,7 @@ package main import ( _ "github.com/fatedier/frp/assets/frpc" - "github.com/fatedier/frp/cmd/frpc/sub" + "github.com/fatedier/frp/cmd/transporter-client/sub" "github.com/fatedier/frp/pkg/util/system" ) diff --git a/cmd/frpc/sub/admin.go b/cmd/transporter-client/sub/admin.go similarity index 100% rename from cmd/frpc/sub/admin.go rename to cmd/transporter-client/sub/admin.go diff --git a/cmd/frpc/sub/nathole.go b/cmd/transporter-client/sub/nathole.go similarity index 87% rename from cmd/frpc/sub/nathole.go rename to cmd/transporter-client/sub/nathole.go index fb5b08078c2..a8f5a69580e 100644 --- a/cmd/frpc/sub/nathole.go +++ b/cmd/transporter-client/sub/nathole.go @@ -31,11 +31,11 @@ var ( ) func init() { - rootCmd.AddCommand(natholeCmd) - natholeCmd.AddCommand(natholeDiscoveryCmd) - - natholeCmd.PersistentFlags().StringVarP(&natHoleSTUNServer, "nat_hole_stun_server", "", "", "STUN server address for nathole") - natholeCmd.PersistentFlags().StringVarP(&natHoleLocalAddr, "nat_hole_local_addr", "l", "", "local address to connect STUN server") + //rootCmd.AddCommand(natholeCmd) + //natholeCmd.AddCommand(natholeDiscoveryCmd) + // + //natholeCmd.PersistentFlags().StringVarP(&natHoleSTUNServer, "nat_hole_stun_server", "", "", "STUN server address for nathole") + //natholeCmd.PersistentFlags().StringVarP(&natHoleLocalAddr, "nat_hole_local_addr", "l", "", "local address to connect STUN server") } var natholeCmd = &cobra.Command{ diff --git a/cmd/frpc/sub/proxy.go b/cmd/transporter-client/sub/proxy.go similarity index 96% rename from cmd/frpc/sub/proxy.go rename to cmd/transporter-client/sub/proxy.go index c5d76b1e3b3..4754c9690cd 100644 --- a/cmd/frpc/sub/proxy.go +++ b/cmd/transporter-client/sub/proxy.go @@ -28,19 +28,19 @@ import ( var proxyTypes = []v1.ProxyType{ v1.ProxyTypeTCP, - v1.ProxyTypeUDP, - v1.ProxyTypeTCPMUX, + //v1.ProxyTypeUDP, + //v1.ProxyTypeTCPMUX, v1.ProxyTypeHTTP, v1.ProxyTypeHTTPS, v1.ProxyTypeSTCP, - v1.ProxyTypeSUDP, - v1.ProxyTypeXTCP, + //v1.ProxyTypeSUDP, + //v1.ProxyTypeXTCP, } var visitorTypes = []v1.VisitorType{ v1.VisitorTypeSTCP, - v1.VisitorTypeSUDP, - v1.VisitorTypeXTCP, + //v1.VisitorTypeSUDP, + //v1.VisitorTypeXTCP, } func init() { diff --git a/cmd/frpc/sub/root.go b/cmd/transporter-client/sub/root.go similarity index 96% rename from cmd/frpc/sub/root.go rename to cmd/transporter-client/sub/root.go index b844ddfd5e9..9361ca3166a 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/transporter-client/sub/root.go @@ -50,8 +50,8 @@ func init() { } var rootCmd = &cobra.Command{ - Use: "frpc", - Short: "frpc is the client of frp (https://github.com/fatedier/frp)", + Use: "transporter-client", + Short: "this is transporter-client", RunE: func(cmd *cobra.Command, args []string) error { if showVersion { fmt.Println(version.Full()) @@ -87,7 +87,7 @@ func runMultipleClients(cfgDir string) error { defer wg.Done() err := runClient(path) if err != nil { - fmt.Printf("frpc service error for config file [%s]\n", path) + fmt.Printf("transporter-client service error for config file [%s]\n", path) } }() return nil diff --git a/cmd/frpc/sub/verify.go b/cmd/transporter-client/sub/verify.go similarity index 97% rename from cmd/frpc/sub/verify.go rename to cmd/transporter-client/sub/verify.go index 4b971f531c7..53bf231c5c0 100644 --- a/cmd/frpc/sub/verify.go +++ b/cmd/transporter-client/sub/verify.go @@ -25,7 +25,7 @@ import ( ) func init() { - rootCmd.AddCommand(verifyCmd) + //rootCmd.AddCommand(verifyCmd) } var verifyCmd = &cobra.Command{ diff --git a/cmd/frps/main.go b/cmd/transporter-server/main.go similarity index 100% rename from cmd/frps/main.go rename to cmd/transporter-server/main.go diff --git a/cmd/frps/root.go b/cmd/transporter-server/root.go similarity index 97% rename from cmd/frps/root.go rename to cmd/transporter-server/root.go index 2dbea578d11..96c9a119c3e 100644 --- a/cmd/frps/root.go +++ b/cmd/transporter-server/root.go @@ -46,8 +46,8 @@ func init() { } var rootCmd = &cobra.Command{ - Use: "frps", - Short: "frps is the server of frp (https://github.com/fatedier/frp)", + Use: "transporter-server", + Short: "this is transporter-server", RunE: func(cmd *cobra.Command, args []string) error { if showVersion { fmt.Println(version.Full()) diff --git a/cmd/frps/verify.go b/cmd/transporter-server/verify.go similarity index 100% rename from cmd/frps/verify.go rename to cmd/transporter-server/verify.go diff --git a/pkg/msg/edgewize_msg.go b/pkg/msg/edgewize_msg.go index 5d852f7001d..8591f8fc92b 100644 --- a/pkg/msg/edgewize_msg.go +++ b/pkg/msg/edgewize_msg.go @@ -1,13 +1,15 @@ package msg const ( - TypeConnHead = 's' - TypeCryptoLogin = 't' + TypeConnHead = '~' + TypeCryptoLogin = '!' ) func init() { msgTypeMap[TypeConnHead] = ConnectHead{} msgTypeMap[TypeCryptoLogin] = CryptoLogin{} + msgCtl.RegisterMsg(TypeConnHead, ConnectHead{}) + msgCtl.RegisterMsg(TypeCryptoLogin, CryptoLogin{}) } type CryptoLogin struct { @@ -17,5 +19,5 @@ type CryptoLogin struct { } type ConnectHead struct { - ServiceName string `json:"serviceName"` + ServiceName string `json:"service_name"` } From e15bb68e40278a788a60f9684764d1ee09f43b7e Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Mon, 11 Nov 2024 09:48:23 +0800 Subject: [PATCH 10/12] =?UTF-8?q?frp=E7=A7=81=E6=9C=89=E5=8C=96=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/service.go | 7 ++++--- pkg/auth/auth.go | 4 ++-- pkg/auth/edgewize_oidc.go | 12 +++++++----- pkg/auth/edgewize_pass.go | 4 ++-- pkg/auth/edgewize_token.go | 10 ++++++---- server/service.go | 4 ++-- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/client/service.go b/client/service.go index bccf0dd62f3..536e35b950f 100644 --- a/client/service.go +++ b/client/service.go @@ -262,10 +262,11 @@ func (svr *Service) login() (conn net.Conn, connector Connector, err error) { if err = svr.authSetter.SetLogin(loginMsg); err != nil { return } - var cryp = new(msg.CryptoLogin) - svr.authSetter.SetCrypto(cryp, loginMsg) - if err = msg.WriteMsg(conn, cryp); err != nil { + cryp := svr.authSetter.SetCrypto(loginMsg) + cryp.TimeStamp = time.Now().Unix() + + if err = msg.WriteMsg(conn, &cryp); err != nil { return } diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index a5a2574128c..e3e66372878 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -25,7 +25,7 @@ type Setter interface { SetLogin(*msg.Login) error SetPing(*msg.Ping) error SetNewWorkConn(*msg.NewWorkConn) error - SetCrypto(c *msg.CryptoLogin, login *msg.Login) + SetCrypto(login *msg.Login) msg.CryptoLogin } func NewAuthSetter(cfg v1.AuthClientConfig) (authProvider Setter) { @@ -44,7 +44,7 @@ type Verifier interface { VerifyLogin(*msg.Login) error VerifyPing(*msg.Ping) error VerifyNewWorkConn(*msg.NewWorkConn) error - VerifyCrypto(c *msg.CryptoLogin) *msg.Login + VerifyCrypto(c *msg.CryptoLogin) msg.Login } func NewAuthVerifier(cfg v1.AuthServerConfig) (authVerifier Verifier) { diff --git a/pkg/auth/edgewize_oidc.go b/pkg/auth/edgewize_oidc.go index cb3ffec1e84..b802fc90790 100644 --- a/pkg/auth/edgewize_oidc.go +++ b/pkg/auth/edgewize_oidc.go @@ -9,24 +9,26 @@ import ( "strconv" ) -func (auth *OidcAuthProvider) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { +func (auth *OidcAuthProvider) SetCrypto(login *msg.Login) msg.CryptoLogin { + var c msg.CryptoLogin bs, _ := json.Marshal(login) c.Auth = util.RandomString(16) key := util.GenerateAesKey(c.Auth)[:8] iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) + return c } -func (auth *OidcAuthConsumer) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { - var login *msg.Login +func (auth *OidcAuthConsumer) VerifyCrypto(c *msg.CryptoLogin) msg.Login { + var login msg.Login bs, err := hex.DecodeString(c.Sign) if err != nil { fmt.Println("verify crypto error,", err) - return nil + return msg.Login{} } key := util.GenerateAesKey(c.Auth)[:8] iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] before := util.Decrypt(bs, key, []byte(iv)) - _ = json.Unmarshal(before, login) + _ = json.Unmarshal(before, &login) return login } diff --git a/pkg/auth/edgewize_pass.go b/pkg/auth/edgewize_pass.go index c254b748082..de4c3db3cc6 100644 --- a/pkg/auth/edgewize_pass.go +++ b/pkg/auth/edgewize_pass.go @@ -2,6 +2,6 @@ package auth import "github.com/fatedier/frp/pkg/msg" -func (p *alwaysPass) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { - return nil +func (p *alwaysPass) VerifyCrypto(c *msg.CryptoLogin) msg.Login { + return msg.Login{} } diff --git a/pkg/auth/edgewize_token.go b/pkg/auth/edgewize_token.go index 873d5dd5fe7..428b62c6fff 100644 --- a/pkg/auth/edgewize_token.go +++ b/pkg/auth/edgewize_token.go @@ -9,24 +9,26 @@ import ( "strconv" ) -func (auth *TokenAuthSetterVerifier) SetCrypto(c *msg.CryptoLogin, login *msg.Login) { +func (auth *TokenAuthSetterVerifier) SetCrypto(login *msg.Login) msg.CryptoLogin { + var c msg.CryptoLogin bs, _ := json.Marshal(login) key := util.GenerateAesKey(auth.token)[:8] iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] c.Auth = util.RandomString(16) c.Sign = hex.EncodeToString(util.Encrypt(string(bs), key, []byte(iv))) + return c } -func (auth *TokenAuthSetterVerifier) VerifyCrypto(c *msg.CryptoLogin) *msg.Login { +func (auth *TokenAuthSetterVerifier) VerifyCrypto(c *msg.CryptoLogin) msg.Login { var login msg.Login bs, err := hex.DecodeString(c.Sign) if err != nil { fmt.Println("verify crypto error,", err) - return nil + return msg.Login{} } key := util.GenerateAesKey(auth.token)[:8] iv := util.GenerateAesKey(strconv.FormatInt(c.TimeStamp, 16))[:8] before := util.Decrypt(bs, key, []byte(iv)) _ = json.Unmarshal(before, &login) - return &login + return login } diff --git a/server/service.go b/server/service.go index 8b56d9a6812..0a201a6f3fb 100644 --- a/server/service.go +++ b/server/service.go @@ -436,13 +436,13 @@ func (svr *Service) handleConnection(ctx context.Context, conn net.Conn, interna // 修改接入流程。需要先读出登录的加密信息,然后解密得到登录的完整信息,最后才能按照原登录逻辑处理 case *msg.CryptoLogin: login := svr.authVerifier.VerifyCrypto(m) - if login == nil { + if login.Timestamp == 0 { log.Errorf("verify login failed,%s,%d", m.Sign, m.TimeStamp) conn.Close() return } content := &plugin.LoginContent{ - Login: *login, + Login: login, ClientAddress: conn.RemoteAddr().String(), } retContent, err := svr.pluginManager.Login(content) From c85294a3e569275a65164004ff97771d841fb8c5 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Mon, 11 Nov 2024 13:23:14 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E5=8E=BB=E6=8E=89frp=E5=85=B3=E9=94=AE?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/transporter-client/sub/proxy.go | 4 ++-- pkg/config/flags.go | 4 ++-- pkg/metrics/prometheus/server.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/transporter-client/sub/proxy.go b/cmd/transporter-client/sub/proxy.go index 4754c9690cd..d71a0ec6965 100644 --- a/cmd/transporter-client/sub/proxy.go +++ b/cmd/transporter-client/sub/proxy.go @@ -71,7 +71,7 @@ func init() { func NewProxyCommand(name string, c v1.ProxyConfigurer, clientCfg *v1.ClientCommonConfig) *cobra.Command { return &cobra.Command{ Use: name, - Short: fmt.Sprintf("Run frpc with a single %s proxy", name), + Short: fmt.Sprintf("Run transporter-client with a single %s proxy", name), Run: func(cmd *cobra.Command, args []string) { clientCfg.Complete() if _, err := validation.ValidateClientCommonConfig(clientCfg); err != nil { @@ -97,7 +97,7 @@ func NewProxyCommand(name string, c v1.ProxyConfigurer, clientCfg *v1.ClientComm func NewVisitorCommand(name string, c v1.VisitorConfigurer, clientCfg *v1.ClientCommonConfig) *cobra.Command { return &cobra.Command{ Use: "visitor", - Short: fmt.Sprintf("Run frpc with a single %s visitor", name), + Short: fmt.Sprintf("Run transporter with a single %s visitor", name), Run: func(cmd *cobra.Command, args []string) { clientCfg.Complete() if _, err := validation.ValidateClientCommonConfig(clientCfg); err != nil { diff --git a/pkg/config/flags.go b/pkg/config/flags.go index 98f617be481..575829f8be7 100644 --- a/pkg/config/flags.go +++ b/pkg/config/flags.go @@ -161,7 +161,7 @@ func RegisterClientCommonConfigFlags(cmd *cobra.Command, c *v1.ClientCommonConfi cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console") cmd.PersistentFlags().StringVarP(&c.Transport.TLS.ServerName, "tls_server_name", "", "", "specify the custom server name of tls certificate") cmd.PersistentFlags().StringVarP(&c.DNSServer, "dns_server", "", "", "specify dns server instead of using system default one") - c.Transport.TLS.Enable = cmd.PersistentFlags().BoolP("tls_enable", "", true, "enable frpc tls") + c.Transport.TLS.Enable = cmd.PersistentFlags().BoolP("tls_enable", "", true, "enable transporter-client tls") } cmd.PersistentFlags().StringVarP(&c.User, "user", "u", "", "user") cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token") @@ -243,7 +243,7 @@ func RegisterServerConfigFlags(cmd *cobra.Command, c *v1.ServerConfig, opts ...R cmd.PersistentFlags().StringVarP(&c.SubDomainHost, "subdomain_host", "", "", "subdomain host") cmd.PersistentFlags().VarP(&PortsRangeSliceFlag{V: &c.AllowPorts}, "allow_ports", "", "allow ports") cmd.PersistentFlags().Int64VarP(&c.MaxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client") - cmd.PersistentFlags().BoolVarP(&c.Transport.TLS.Force, "tls_only", "", false, "frps tls only") + cmd.PersistentFlags().BoolVarP(&c.Transport.TLS.Force, "tls_only", "", false, "transporter-server tls only") webServerTLS := v1.TLSConfig{} cmd.PersistentFlags().StringVarP(&webServerTLS.CertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file") diff --git a/pkg/metrics/prometheus/server.go b/pkg/metrics/prometheus/server.go index 56dea6e82fe..3c8d8a5c226 100644 --- a/pkg/metrics/prometheus/server.go +++ b/pkg/metrics/prometheus/server.go @@ -7,7 +7,7 @@ import ( ) const ( - namespace = "frp" + namespace = "transporter" serverSubsystem = "server" ) @@ -59,7 +59,7 @@ func newServerMetrics() *serverMetrics { Namespace: namespace, Subsystem: serverSubsystem, Name: "client_counts", - Help: "The current client counts of frps", + Help: "The current client counts of transporter-server", }), proxyCount: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, From 8d9f7032d553007142d8badd15080b4691fa5cf5 Mon Sep 17 00:00:00 2001 From: "xuesongzuo@yunify.com" Date: Mon, 11 Nov 2024 13:44:49 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E5=8E=BB=E6=8E=89frp=E5=85=B3=E9=94=AE?= =?UTF-8?q?=E5=AD=97=EF=BC=8C=E5=88=A0=E9=99=A4=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84=E6=8C=87=E4=BB=A4=E5=92=8C=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/admin_api.go | 6 +++--- client/visitor/sudp.go | 8 ++++---- cmd/transporter-client/sub/admin.go | 14 +------------- cmd/transporter-client/sub/nathole.go | 8 -------- cmd/transporter-client/sub/proxy.go | 6 ------ cmd/transporter-client/sub/root.go | 10 +++++----- cmd/transporter-client/sub/verify.go | 6 +++--- 7 files changed, 16 insertions(+), 42 deletions(-) diff --git a/client/admin_api.go b/client/admin_api.go index 708b2cbd9e6..3962a7e493e 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -89,20 +89,20 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { if err != nil { res.Code = 400 res.Msg = err.Error() - log.Warnf("reload frpc proxy config error: %s", res.Msg) + log.Warnf("reload transporter-client proxy config error: %s", res.Msg) return } if _, err := validation.ValidateAllClientConfig(cliCfg, proxyCfgs, visitorCfgs); err != nil { res.Code = 400 res.Msg = err.Error() - log.Warnf("reload frpc proxy config error: %s", res.Msg) + log.Warnf("reload transporter-client proxy config error: %s", res.Msg) return } if err := svr.UpdateAllConfigurer(proxyCfgs, visitorCfgs); err != nil { res.Code = 500 res.Msg = err.Error() - log.Warnf("reload frpc proxy config error: %s", res.Msg) + log.Warnf("reload transporter-client proxy config error: %s", res.Msg) return } log.Infof("success reload conf") diff --git a/client/visitor/sudp.go b/client/visitor/sudp.go index 284aee10915..f3d926ed20c 100644 --- a/client/visitor/sudp.go +++ b/client/visitor/sudp.go @@ -84,17 +84,17 @@ func (sv *SUDPVisitor) dispatcher() { select { case firstPacket = <-sv.sendCh: if firstPacket == nil { - xl.Infof("frpc sudp visitor proxy is closed") + xl.Infof("transporter-client sudp visitor proxy is closed") return } case <-sv.checkCloseCh: - xl.Infof("frpc sudp visitor proxy is closed") + xl.Infof("transporter-client sudp visitor proxy is closed") return } visitorConn, err = sv.getNewVisitorConn() if err != nil { - xl.Warnf("newVisitorConn to frps error: %v, try to reconnect", err) + xl.Warnf("newVisitorConn to transporter-server error: %v, try to reconnect", err) continue } @@ -201,7 +201,7 @@ func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) { xl := xlog.FromContextSafe(sv.ctx) visitorConn, err := sv.helper.ConnectServer() if err != nil { - return nil, fmt.Errorf("frpc connect frps error: %v", err) + return nil, fmt.Errorf("transporter-client connect transporter-server error: %v", err) } now := time.Now().Unix() diff --git a/cmd/transporter-client/sub/admin.go b/cmd/transporter-client/sub/admin.go index 5d478d44a58..2f42fb8c8d0 100644 --- a/cmd/transporter-client/sub/admin.go +++ b/cmd/transporter-client/sub/admin.go @@ -30,21 +30,9 @@ import ( func init() { rootCmd.AddCommand(NewAdminCommand( "reload", - "Hot-Reload frpc configuration", + "Hot-Reload transporter-client configuration", ReloadHandler, )) - - rootCmd.AddCommand(NewAdminCommand( - "status", - "Overview of all proxies status", - StatusHandler, - )) - - rootCmd.AddCommand(NewAdminCommand( - "stop", - "Stop the running frpc", - StopHandler, - )) } func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) error) *cobra.Command { diff --git a/cmd/transporter-client/sub/nathole.go b/cmd/transporter-client/sub/nathole.go index a8f5a69580e..7529fdbe0f9 100644 --- a/cmd/transporter-client/sub/nathole.go +++ b/cmd/transporter-client/sub/nathole.go @@ -30,14 +30,6 @@ var ( natHoleLocalAddr string ) -func init() { - //rootCmd.AddCommand(natholeCmd) - //natholeCmd.AddCommand(natholeDiscoveryCmd) - // - //natholeCmd.PersistentFlags().StringVarP(&natHoleSTUNServer, "nat_hole_stun_server", "", "", "STUN server address for nathole") - //natholeCmd.PersistentFlags().StringVarP(&natHoleLocalAddr, "nat_hole_local_addr", "l", "", "local address to connect STUN server") -} - var natholeCmd = &cobra.Command{ Use: "nathole", Short: "Actions about nathole", diff --git a/cmd/transporter-client/sub/proxy.go b/cmd/transporter-client/sub/proxy.go index d71a0ec6965..986c1550395 100644 --- a/cmd/transporter-client/sub/proxy.go +++ b/cmd/transporter-client/sub/proxy.go @@ -28,19 +28,13 @@ import ( var proxyTypes = []v1.ProxyType{ v1.ProxyTypeTCP, - //v1.ProxyTypeUDP, - //v1.ProxyTypeTCPMUX, v1.ProxyTypeHTTP, v1.ProxyTypeHTTPS, v1.ProxyTypeSTCP, - //v1.ProxyTypeSUDP, - //v1.ProxyTypeXTCP, } var visitorTypes = []v1.VisitorType{ v1.VisitorTypeSTCP, - //v1.VisitorTypeSUDP, - //v1.VisitorTypeXTCP, } func init() { diff --git a/cmd/transporter-client/sub/root.go b/cmd/transporter-client/sub/root.go index 9361ca3166a..ab9af5526f4 100644 --- a/cmd/transporter-client/sub/root.go +++ b/cmd/transporter-client/sub/root.go @@ -43,9 +43,9 @@ var ( ) func init() { - rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc") - rootCmd.PersistentFlags().StringVarP(&cfgDir, "config_dir", "", "", "config directory, run one frpc service for each file in config directory") - rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./client.ini", "config file of transporter-client") + rootCmd.PersistentFlags().StringVarP(&cfgDir, "config_dir", "", "", "config directory, run one transporter-client service for each file in config directory") + rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of transporter-client") rootCmd.PersistentFlags().BoolVarP(&strictConfigMode, "strict_config", "", true, "strict config parsing mode, unknown fields will cause an errors") } @@ -139,8 +139,8 @@ func startService( log.InitLogger(cfg.Log.To, cfg.Log.Level, int(cfg.Log.MaxDays), cfg.Log.DisablePrintColor) if cfgFile != "" { - log.Infof("start frpc service for config file [%s]", cfgFile) - defer log.Infof("frpc service for config file [%s] stopped", cfgFile) + log.Infof("start transporter-client service for config file [%s]", cfgFile) + defer log.Infof("transporter-client service for config file [%s] stopped", cfgFile) } svr, err := client.NewService(client.ServiceOptions{ Common: cfg, diff --git a/cmd/transporter-client/sub/verify.go b/cmd/transporter-client/sub/verify.go index 53bf231c5c0..9848817e996 100644 --- a/cmd/transporter-client/sub/verify.go +++ b/cmd/transporter-client/sub/verify.go @@ -25,7 +25,7 @@ import ( ) func init() { - //rootCmd.AddCommand(verifyCmd) + rootCmd.AddCommand(verifyCmd) } var verifyCmd = &cobra.Command{ @@ -33,7 +33,7 @@ var verifyCmd = &cobra.Command{ Short: "Verify that the configures is valid", RunE: func(cmd *cobra.Command, args []string) error { if cfgFile == "" { - fmt.Println("frpc: the configuration file is not specified") + fmt.Println("transporter-client: the configuration file is not specified") return nil } @@ -51,7 +51,7 @@ var verifyCmd = &cobra.Command{ os.Exit(1) } - fmt.Printf("frpc: the configuration file %s syntax is ok\n", cfgFile) + fmt.Printf("transporter-client: the configuration file %s syntax is ok\n", cfgFile) return nil }, }