From cd8adaea067bb8c8ee936d00e4ce8823db3786f8 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 25 Sep 2022 10:49:07 +0300 Subject: [PATCH 01/24] bump version --- client/control.go | 7 +++++++ cmd/frpc/sub/http.go | 2 ++ cmd/frpc/sub/root.go | 1 + conf/frpc.ini | 19 ++++++++++++------- conf/frps.ini | 15 ++++++++++++++- go.mod | 3 ++- go.sum | 10 ++++++++++ pkg/config/proxy.go | 3 +++ pkg/msg/msg.go | 1 + pkg/util/vhost/http.go | 29 +++++++++++++++++++++++++++++ pkg/util/vhost/reverseproxy.go | 2 ++ pkg/util/vhost/vhost.go | 3 +++ server/proxy/http.go | 3 +++ server/service.go | 2 ++ 14 files changed, 91 insertions(+), 9 deletions(-) diff --git a/client/control.go b/client/control.go index ccec2feda7e..ade1eb03175 100644 --- a/client/control.go +++ b/client/control.go @@ -145,10 +145,13 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { m := &msg.NewWorkConn{ RunID: ctl.runID, } + xl.Info("SetNewWorkConn") if err = ctl.authSetter.SetNewWorkConn(m); err != nil { xl.Warn("error during NewWorkConn authentication: %v", err) return } + xl.Info("WriteMsg - NewWorkConn") + if err = msg.WriteMsg(workConn, m); err != nil { xl.Warn("work connection write to server error: %v", err) workConn.Close() @@ -156,17 +159,20 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { } var startMsg msg.StartWorkConn + xl.Info("Starting to read - NewWorkConn") if err = msg.ReadMsgInto(workConn, &startMsg); err != nil { xl.Error("work connection closed before response StartWorkConn message: %v", err) workConn.Close() return } + xl.Info("Finished to read - NewWorkConn") if startMsg.Error != "" { xl.Error("StartWorkConn contains error: %s", startMsg.Error) workConn.Close() return } + xl.Info("Call to HandleWorkConn") // dispatch this work connection to related proxy ctl.pm.HandleWorkConn(startMsg.ProxyName, workConn, &startMsg) } @@ -398,6 +404,7 @@ func (ctl *Control) msgHandler() { switch m := rawMsg.(type) { case *msg.ReqWorkConn: + xl.Info("ReqWorkConn msg") go ctl.HandleReqWorkConn(m) case *msg.NewProxyResp: ctl.HandleNewProxyResp(m) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 2e19fce4f67..f0e21d844e6 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -36,6 +36,7 @@ func init() { httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") + httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "ips allow list - supports subnet mask for example - 192.168.0.0/16, 255.255.0.0") httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") @@ -67,6 +68,7 @@ var httpCmd = &cobra.Command{ cfg.Locations = strings.Split(locations, ",") cfg.HTTPUser = httpUser cfg.HTTPPwd = httpPwd + cfg.IpsAllowList = strings.Split(ipsAllowList, ",") cfg.HostHeaderRewrite = hostHeaderRewrite cfg.UseEncryption = useEncryption cfg.UseCompression = useCompression diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index 3bde61fd9f4..8e56fa7123c 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -64,6 +64,7 @@ var ( subDomain string httpUser string httpPwd string + ipsAllowList string locations string hostHeaderRewrite string role string diff --git a/conf/frpc.ini b/conf/frpc.ini index 13a8e5f6fc9..f043f37b305 100644 --- a/conf/frpc.ini +++ b/conf/frpc.ini @@ -1,9 +1,14 @@ [common] -server_addr = 127.0.0.1 -server_port = 7000 +server_addr = tunnel.io +server_port = 7005 +protocol = websocket +log_level = debug -[ssh] -type = tcp -local_ip = 127.0.0.1 -local_port = 22 -remote_port = 6000 +[web] +type = http +local_port = 3002 +meta_Authorization = {{ .Envs.AUTHORIZATION }} +subdomain = ziv +;ips_allow_list = "127.0.0.2/32,192.198.100.10" +;http_user = abc +;http_pwd = abc \ No newline at end of file diff --git a/conf/frps.ini b/conf/frps.ini index 229567a9d6b..a919c3d6224 100644 --- a/conf/frps.ini +++ b/conf/frps.ini @@ -1,2 +1,15 @@ [common] -bind_port = 7000 +bind_port = 7005 +vhost_http_port=82 +subdomain_host=tunnel.io +log_level = trace + +;[plugin.codefresh] +;addr = 127.0.0.1:7200 +;path = /newProxy +;ops = NewProxy + +;[plugin.codefresh] +;addr = 127.0.0.1:7200 +;path = /newWorkConn +;ops = Ping \ No newline at end of file diff --git a/go.mod b/go.mod index 0a92dfb5a65..1a87ec3abfa 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c + github.com/jpillora/ipfilter v1.2.7 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.13.0 @@ -21,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect diff --git a/go.sum b/go.sum index 433f03e281a..0ead46b7b73 100644 --- a/go.sum +++ b/go.sum @@ -222,6 +222,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jpillora/ipfilter v1.2.7 h1:fB+fIa/VtgjOrHjkR3Sw47dHYhZGCae/dIWc/Vur++U= +github.com/jpillora/ipfilter v1.2.7/go.mod h1:QS0miOgSqkxAsnTKLADlahASDOExe2K2pdoswGRt+FM= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -300,6 +302,8 @@ github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phuslu/iploc v1.0.20220730 h1:Ly2Casvb9LVnaDg06RfkET6AwkMCUXrNANKJX40vsoE= +github.com/phuslu/iploc v1.0.20220730/go.mod h1:gsgExGWldwv1AEzZm+Ki9/vGfyjkL33pbSr9HGpt2Xg= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -366,6 +370,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -373,6 +378,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= @@ -381,6 +388,8 @@ github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mn github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= @@ -667,6 +676,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/config/proxy.go b/pkg/config/proxy.go index e168520d377..9275e649238 100644 --- a/pkg/config/proxy.go +++ b/pkg/config/proxy.go @@ -162,6 +162,7 @@ type HTTPProxyConf struct { Locations []string `ini:"locations" json:"locations"` HTTPUser string `ini:"http_user" json:"http_user"` HTTPPwd string `ini:"http_pwd" json:"http_pwd"` + IpsAllowList []string `ini:"ips_allow_list" json:"ips_allow_list"` HostHeaderRewrite string `ini:"host_header_rewrite" json:"host_header_rewrite"` Headers map[string]string `ini:"-" json:"headers"` RouteByHTTPUser string `ini:"route_by_http_user" json:"route_by_http_user"` @@ -760,6 +761,7 @@ func (cfg *HTTPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) { cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite cfg.HTTPUser = pMsg.HTTPUser cfg.HTTPPwd = pMsg.HTTPPwd + cfg.IpsAllowList = pMsg.IpsAllowList cfg.Headers = pMsg.Headers cfg.RouteByHTTPUser = pMsg.RouteByHTTPUser } @@ -774,6 +776,7 @@ func (cfg *HTTPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) { pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite pMsg.HTTPUser = cfg.HTTPUser pMsg.HTTPPwd = cfg.HTTPPwd + pMsg.IpsAllowList = cfg.IpsAllowList pMsg.Headers = cfg.Headers pMsg.RouteByHTTPUser = cfg.RouteByHTTPUser } diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go index ba6dd63e450..4f1c8798adb 100644 --- a/pkg/msg/msg.go +++ b/pkg/msg/msg.go @@ -102,6 +102,7 @@ type NewProxy struct { Locations []string `json:"locations,omitempty"` HTTPUser string `json:"http_user,omitempty"` HTTPPwd string `json:"http_pwd,omitempty"` + IpsAllowList []string `json:"ips_allow_list,omitempty"` HostHeaderRewrite string `json:"host_header_rewrite,omitempty"` Headers map[string]string `json:"headers,omitempty"` RouteByHTTPUser string `json:"route_by_http_user,omitempty"` diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index bfbd16ea9b6..10e9673b665 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -20,6 +20,7 @@ import ( "encoding/base64" "errors" "fmt" + "github.com/jpillora/ipfilter" "log" "net" "net/http" @@ -60,6 +61,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * proxy := &ReverseProxy{ // Modify incoming requests by route policies. Director: func(req *http.Request) { + frpLog.Info("Director *********************") req.URL.Scheme = "http" url := req.Context().Value(RouteInfoURL).(string) routeByHTTPUser := req.Context().Value(RouteInfoHTTPUser).(string) @@ -88,6 +90,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * ResponseHeaderTimeout: rp.responseHeaderTimeout, IdleConnTimeout: 60 * time.Second, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + frpLog.Info("DialContext *********************") url := ctx.Value(RouteInfoURL).(string) host, _ := util.CanonicalHost(ctx.Value(RouteInfoHost).(string)) routerByHTTPUser := ctx.Value(RouteInfoHTTPUser).(string) @@ -102,6 +105,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * // Normal: // GET / HTTP/1.1 // Host: example.com + frpLog.Info("Proxy *********************") urlHost := req.Context().Value(RouteInfoURLHost).(string) if urlHost != "" { return req.URL, nil @@ -163,6 +167,8 @@ func (rp *HTTPReverseProxy) GetHeaders(domain, location, routeByHTTPUser string) // CreateConnection create a new connection by route config func (rp *HTTPReverseProxy) CreateConnection(domain, location, routeByHTTPUser string, remoteAddr string) (net.Conn, error) { + frpLog.Info("CreateConnection *********************") + vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { fn := vr.payload.(*RouteConfig).CreateConnFn @@ -185,6 +191,23 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p return true } +func (rp *HTTPReverseProxy) CheckRemoteAddress(domain, location, routeByHTTPUser, remoteAdd string) bool { + remoteAddWithoutPort := strings.Split(remoteAdd, ":")[0] + vr, ok := rp.getVhost(domain, location, routeByHTTPUser) + if ok { + ipsAllowList := vr.payload.(*RouteConfig).IpsAllowList + if ipsAllowList != nil { + // perhaps it's better to configure it once and check the remote address here + f := ipfilter.New(ipfilter.Options{ + AllowedIPs: vr.payload.(*RouteConfig).IpsAllowList, + BlockByDefault: true, + }) + return f.Allowed(remoteAddWithoutPort) + } + } + return true +} + // getVhost trys to get vhost router by route policy. func (rp *HTTPReverseProxy) getVhost(domain, location, routeByHTTPUser string) (*Router, bool) { findRouter := func(inDomain, inLocation, inRouteByHTTPUser string) (*Router, bool) { @@ -293,6 +316,12 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } + remoteAdd := req.RemoteAddr + if !rp.CheckRemoteAddress(domain, location, user, remoteAdd) { + http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) + return + } + newreq := rp.injectRequestInfoToCtx(req) if req.Method == http.MethodConnect { rp.connectHandler(rw, newreq) diff --git a/pkg/util/vhost/reverseproxy.go b/pkg/util/vhost/reverseproxy.go index 975f1d14ecf..e10222fe5b5 100644 --- a/pkg/util/vhost/reverseproxy.go +++ b/pkg/util/vhost/reverseproxy.go @@ -10,6 +10,7 @@ import ( "context" "encoding/base64" "fmt" + frpLog "github.com/fatedier/frp/pkg/util/log" "io" "log" "net" @@ -229,6 +230,7 @@ func parseBasicAuth(auth string) (username, password string, ok bool) { } func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + frpLog.Info("ServeHTTP *********************") transport := p.Transport if transport == nil { transport = http.DefaultTransport diff --git a/pkg/util/vhost/vhost.go b/pkg/util/vhost/vhost.go index 2957cec4e78..d4c975dc1d4 100644 --- a/pkg/util/vhost/vhost.go +++ b/pkg/util/vhost/vhost.go @@ -84,6 +84,7 @@ type RouteConfig struct { Username string Password string Headers map[string]string + IpsAllowList []string RouteByHTTPUser string CreateConnFn CreateConnFunc @@ -98,6 +99,7 @@ func (v *Muxer) Listen(ctx context.Context, cfg *RouteConfig) (l *Listener, err routeByHTTPUser: cfg.RouteByHTTPUser, rewriteHost: cfg.RewriteHost, userName: cfg.Username, + ipsAllowList: cfg.IpsAllowList, passWord: cfg.Password, mux: v, accept: make(chan net.Conn), @@ -234,6 +236,7 @@ type Listener struct { rewriteHost string userName string passWord string + ipsAllowList []string mux *Muxer // for closing Muxer accept chan net.Conn ctx context.Context diff --git a/server/proxy/http.go b/server/proxy/http.go index e0e2f23cb50..bd2c3c27be8 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -15,6 +15,7 @@ package proxy import ( + frpLog "github.com/fatedier/frp/pkg/util/log" "io" "net" "strings" @@ -43,6 +44,7 @@ func (pxy *HTTPProxy) Run() (remoteAddr string, err error) { Headers: pxy.cfg.Headers, Username: pxy.cfg.HTTPUser, Password: pxy.cfg.HTTPPwd, + IpsAllowList: pxy.cfg.IpsAllowList, CreateConnFn: pxy.GetRealConn, } @@ -136,6 +138,7 @@ func (pxy *HTTPProxy) GetConf() config.ProxyConf { } func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err error) { + frpLog.Info("GetRealConn *********************") xl := pxy.xl rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr) if errRet != nil { diff --git a/server/service.go b/server/service.go index c3d398b2749..71bd1c9a581 100644 --- a/server/service.go +++ b/server/service.go @@ -317,6 +317,7 @@ func (svr *Service) Run() { } func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { + log.Info("handleConnection! ") xl := xlog.FromContextSafe(ctx) var ( @@ -406,6 +407,7 @@ func (svr *Service) HandleListener(l net.Listener) { // Start a new goroutine to handle connection. go func(ctx context.Context, frpConn net.Conn) { + log.Info("server - handle connection goroutine ") if svr.cfg.TCPMux { fmuxCfg := fmux.DefaultConfig() fmuxCfg.KeepAliveInterval = time.Duration(svr.cfg.TCPMuxKeepaliveInterval) * time.Second From 43aa89403019f76c20262fae6fc05a66e415f6d8 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 25 Sep 2022 10:55:01 +0300 Subject: [PATCH 02/24] init --- client/control.go | 7 ------- conf/frpc.ini | 19 +++++++------------ conf/frps.ini | 15 +-------------- go.mod | 2 +- pkg/util/vhost/http.go | 5 ----- pkg/util/vhost/reverseproxy.go | 2 -- server/proxy/http.go | 2 -- server/service.go | 2 -- 8 files changed, 9 insertions(+), 45 deletions(-) diff --git a/client/control.go b/client/control.go index ade1eb03175..ccec2feda7e 100644 --- a/client/control.go +++ b/client/control.go @@ -145,13 +145,10 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { m := &msg.NewWorkConn{ RunID: ctl.runID, } - xl.Info("SetNewWorkConn") if err = ctl.authSetter.SetNewWorkConn(m); err != nil { xl.Warn("error during NewWorkConn authentication: %v", err) return } - xl.Info("WriteMsg - NewWorkConn") - if err = msg.WriteMsg(workConn, m); err != nil { xl.Warn("work connection write to server error: %v", err) workConn.Close() @@ -159,20 +156,17 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) { } var startMsg msg.StartWorkConn - xl.Info("Starting to read - NewWorkConn") if err = msg.ReadMsgInto(workConn, &startMsg); err != nil { xl.Error("work connection closed before response StartWorkConn message: %v", err) workConn.Close() return } - xl.Info("Finished to read - NewWorkConn") if startMsg.Error != "" { xl.Error("StartWorkConn contains error: %s", startMsg.Error) workConn.Close() return } - xl.Info("Call to HandleWorkConn") // dispatch this work connection to related proxy ctl.pm.HandleWorkConn(startMsg.ProxyName, workConn, &startMsg) } @@ -404,7 +398,6 @@ func (ctl *Control) msgHandler() { switch m := rawMsg.(type) { case *msg.ReqWorkConn: - xl.Info("ReqWorkConn msg") go ctl.HandleReqWorkConn(m) case *msg.NewProxyResp: ctl.HandleNewProxyResp(m) diff --git a/conf/frpc.ini b/conf/frpc.ini index f043f37b305..13a8e5f6fc9 100644 --- a/conf/frpc.ini +++ b/conf/frpc.ini @@ -1,14 +1,9 @@ [common] -server_addr = tunnel.io -server_port = 7005 -protocol = websocket -log_level = debug +server_addr = 127.0.0.1 +server_port = 7000 -[web] -type = http -local_port = 3002 -meta_Authorization = {{ .Envs.AUTHORIZATION }} -subdomain = ziv -;ips_allow_list = "127.0.0.2/32,192.198.100.10" -;http_user = abc -;http_pwd = abc \ No newline at end of file +[ssh] +type = tcp +local_ip = 127.0.0.1 +local_port = 22 +remote_port = 6000 diff --git a/conf/frps.ini b/conf/frps.ini index a919c3d6224..229567a9d6b 100644 --- a/conf/frps.ini +++ b/conf/frps.ini @@ -1,15 +1,2 @@ [common] -bind_port = 7005 -vhost_http_port=82 -subdomain_host=tunnel.io -log_level = trace - -;[plugin.codefresh] -;addr = 127.0.0.1:7200 -;path = /newProxy -;ops = NewProxy - -;[plugin.codefresh] -;addr = 127.0.0.1:7200 -;path = /newWorkConn -;ops = Ping \ No newline at end of file +bind_port = 7000 diff --git a/go.mod b/go.mod index 1a87ec3abfa..6280aba320e 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 10e9673b665..f6fd3e1cb6e 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -61,7 +61,6 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * proxy := &ReverseProxy{ // Modify incoming requests by route policies. Director: func(req *http.Request) { - frpLog.Info("Director *********************") req.URL.Scheme = "http" url := req.Context().Value(RouteInfoURL).(string) routeByHTTPUser := req.Context().Value(RouteInfoHTTPUser).(string) @@ -90,7 +89,6 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * ResponseHeaderTimeout: rp.responseHeaderTimeout, IdleConnTimeout: 60 * time.Second, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - frpLog.Info("DialContext *********************") url := ctx.Value(RouteInfoURL).(string) host, _ := util.CanonicalHost(ctx.Value(RouteInfoHost).(string)) routerByHTTPUser := ctx.Value(RouteInfoHTTPUser).(string) @@ -105,7 +103,6 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * // Normal: // GET / HTTP/1.1 // Host: example.com - frpLog.Info("Proxy *********************") urlHost := req.Context().Value(RouteInfoURLHost).(string) if urlHost != "" { return req.URL, nil @@ -167,8 +164,6 @@ func (rp *HTTPReverseProxy) GetHeaders(domain, location, routeByHTTPUser string) // CreateConnection create a new connection by route config func (rp *HTTPReverseProxy) CreateConnection(domain, location, routeByHTTPUser string, remoteAddr string) (net.Conn, error) { - frpLog.Info("CreateConnection *********************") - vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { fn := vr.payload.(*RouteConfig).CreateConnFn diff --git a/pkg/util/vhost/reverseproxy.go b/pkg/util/vhost/reverseproxy.go index e10222fe5b5..975f1d14ecf 100644 --- a/pkg/util/vhost/reverseproxy.go +++ b/pkg/util/vhost/reverseproxy.go @@ -10,7 +10,6 @@ import ( "context" "encoding/base64" "fmt" - frpLog "github.com/fatedier/frp/pkg/util/log" "io" "log" "net" @@ -230,7 +229,6 @@ func parseBasicAuth(auth string) (username, password string, ok bool) { } func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - frpLog.Info("ServeHTTP *********************") transport := p.Transport if transport == nil { transport = http.DefaultTransport diff --git a/server/proxy/http.go b/server/proxy/http.go index bd2c3c27be8..2e054349eae 100644 --- a/server/proxy/http.go +++ b/server/proxy/http.go @@ -15,7 +15,6 @@ package proxy import ( - frpLog "github.com/fatedier/frp/pkg/util/log" "io" "net" "strings" @@ -138,7 +137,6 @@ func (pxy *HTTPProxy) GetConf() config.ProxyConf { } func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err error) { - frpLog.Info("GetRealConn *********************") xl := pxy.xl rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr) if errRet != nil { diff --git a/server/service.go b/server/service.go index 71bd1c9a581..c3d398b2749 100644 --- a/server/service.go +++ b/server/service.go @@ -317,7 +317,6 @@ func (svr *Service) Run() { } func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) { - log.Info("handleConnection! ") xl := xlog.FromContextSafe(ctx) var ( @@ -407,7 +406,6 @@ func (svr *Service) HandleListener(l net.Listener) { // Start a new goroutine to handle connection. go func(ctx context.Context, frpConn net.Conn) { - log.Info("server - handle connection goroutine ") if svr.cfg.TCPMux { fmuxCfg := fmux.DefaultConfig() fmuxCfg.KeepAliveInterval = time.Duration(svr.cfg.TCPMuxKeepaliveInterval) * time.Second From 2e6e38cab2432546f65dddcc10d631f4fe4d9d78 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 25 Sep 2022 11:02:18 +0300 Subject: [PATCH 03/24] init --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6280aba320e..1a87ec3abfa 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect From 9cca1613a5c26de5861e082051da607ec4bf5fd1 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 25 Sep 2022 12:38:38 +0300 Subject: [PATCH 04/24] move ipfilter to router config --- conf/frpc.ini | 18 ++++++++++++------ conf/frps.ini | 15 ++++++++++++++- pkg/util/vhost/http.go | 11 ++--------- pkg/util/vhost/router.go | 29 ++++++++++++++++++++++------- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/conf/frpc.ini b/conf/frpc.ini index 13a8e5f6fc9..278dc631539 100644 --- a/conf/frpc.ini +++ b/conf/frpc.ini @@ -1,9 +1,15 @@ [common] -server_addr = 127.0.0.1 -server_port = 7000 +server_addr = tunnel.io +server_port = 7005 +;protocol = websocket +log_level = debug -[ssh] +[web] type = tcp -local_ip = 127.0.0.1 -local_port = 22 -remote_port = 6000 +local_port = 3002 +remote_port = 84 +meta_Authorization = {{ .Envs.AUTHORIZATION }} +subdomain = ziv +ips_allow_list = "127.0.1.1/16,192.198.100.10" +;http_user = abc +;http_pwd = abc \ No newline at end of file diff --git a/conf/frps.ini b/conf/frps.ini index 229567a9d6b..a919c3d6224 100644 --- a/conf/frps.ini +++ b/conf/frps.ini @@ -1,2 +1,15 @@ [common] -bind_port = 7000 +bind_port = 7005 +vhost_http_port=82 +subdomain_host=tunnel.io +log_level = trace + +;[plugin.codefresh] +;addr = 127.0.0.1:7200 +;path = /newProxy +;ops = NewProxy + +;[plugin.codefresh] +;addr = 127.0.0.1:7200 +;path = /newWorkConn +;ops = Ping \ No newline at end of file diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index f6fd3e1cb6e..503c5eccf43 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -20,7 +20,6 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/jpillora/ipfilter" "log" "net" "net/http" @@ -190,14 +189,8 @@ func (rp *HTTPReverseProxy) CheckRemoteAddress(domain, location, routeByHTTPUser remoteAddWithoutPort := strings.Split(remoteAdd, ":")[0] vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { - ipsAllowList := vr.payload.(*RouteConfig).IpsAllowList - if ipsAllowList != nil { - // perhaps it's better to configure it once and check the remote address here - f := ipfilter.New(ipfilter.Options{ - AllowedIPs: vr.payload.(*RouteConfig).IpsAllowList, - BlockByDefault: true, - }) - return f.Allowed(remoteAddWithoutPort) + if vr.ipValidator != nil { + return vr.ipValidator.Allowed(remoteAddWithoutPort) } } return true diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 768420a47e7..645c1bcc0a6 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -2,9 +2,13 @@ package vhost import ( "errors" + "fmt" "sort" "strings" "sync" + "unsafe" + + "github.com/jpillora/ipfilter" ) var ( @@ -20,9 +24,10 @@ type Routers struct { } type Router struct { - domain string - location string - httpUser string + domain string + location string + httpUser string + ipValidator *ipfilter.IPFilter // store any object here payload interface{} @@ -51,12 +56,22 @@ func (r *Routers) Add(domain, location, httpUser string, payload interface{}) er vrs = make([]*Router, 0, 1) } + var ipValidator *ipfilter.IPFilter + if payload.(*RouteConfig).IpsAllowList != nil { + ipValidator = ipfilter.New(ipfilter.Options{ + AllowedIPs: payload.(*RouteConfig).IpsAllowList, + BlockByDefault: true, + }) + } + vr := &Router{ - domain: domain, - location: location, - httpUser: httpUser, - payload: payload, + domain: domain, + location: location, + httpUser: httpUser, + ipValidator: ipValidator, + payload: payload, } + fmt.Printf("Size of %T struct: %d bytes", vr, unsafe.Sizeof(*vr)) vrs = append(vrs, vr) sort.Sort(sort.Reverse(ByLocation(vrs))) From eabd886ee36870c6a02bbf1caf79d91222ca1822 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Wed, 28 Sep 2022 16:53:08 +0300 Subject: [PATCH 05/24] wip --- pkg/util/vhost/router.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 645c1bcc0a6..1e502f605f1 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -2,11 +2,9 @@ package vhost import ( "errors" - "fmt" "sort" "strings" "sync" - "unsafe" "github.com/jpillora/ipfilter" ) @@ -71,7 +69,6 @@ func (r *Routers) Add(domain, location, httpUser string, payload interface{}) er ipValidator: ipValidator, payload: payload, } - fmt.Printf("Size of %T struct: %d bytes", vr, unsafe.Sizeof(*vr)) vrs = append(vrs, vr) sort.Sort(sort.Reverse(ByLocation(vrs))) From 679a6933aefe70b5a36d7a8fb397c8cf2ebe763f Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Wed, 28 Sep 2022 17:04:46 +0300 Subject: [PATCH 06/24] update description --- cmd/frpc/sub/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index f0e21d844e6..87ccd552194 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -36,7 +36,7 @@ func init() { httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") - httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "ips allow list - supports subnet mask for example - 192.168.0.0/16, 255.255.0.0") + httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "ips allow list - lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\")") httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") From 063bbb9e66eb276d909a7838f32a6bbaaafa8008 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Wed, 28 Sep 2022 17:06:07 +0300 Subject: [PATCH 07/24] update description --- cmd/frpc/sub/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 87ccd552194..43881ee0b15 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -36,7 +36,7 @@ func init() { httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") - httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "ips allow list - lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\")") + httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\")") httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") From 39053cc86e6baf3c9f7e278bd0c33e428f42e6ee Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Wed, 28 Sep 2022 17:11:24 +0300 Subject: [PATCH 08/24] wip --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1a87ec3abfa..6280aba320e 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect From 1760279ce8e36a103d958b1faa15151670a6d4e6 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Wed, 28 Sep 2022 17:22:10 +0300 Subject: [PATCH 09/24] wip --- go.mod | 4 ++-- go.sum | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6280aba320e..da28f531bbc 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c - github.com/jpillora/ipfilter v1.2.7 // indirect + github.com/jpillora/ipfilter v1.2.7 github.com/leodido/go-urn v1.2.1 // indirect github.com/onsi/ginkgo v1.16.4 github.com/onsi/gomega v1.13.0 @@ -22,7 +22,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/rodaine/table v1.0.1 github.com/spf13/cobra v1.1.3 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.0 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect diff --git a/go.sum b/go.sum index 0ead46b7b73..d13d6241945 100644 --- a/go.sum +++ b/go.sum @@ -376,9 +376,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU= @@ -674,8 +673,8 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 975f8bc78790adba1c8c175b2f7e822b2bdf62b0 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 13:26:43 +0300 Subject: [PATCH 10/24] wip --- cmd/frpc/sub/http.go | 4 +++- pkg/util/vhost/http.go | 2 +- pkg/util/vhost/router.go | 6 +++--- pkg/util/vhost/vhost.go | 2 +- server/group/http.go | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 43881ee0b15..fdd8067c8e3 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -68,10 +68,12 @@ var httpCmd = &cobra.Command{ cfg.Locations = strings.Split(locations, ",") cfg.HTTPUser = httpUser cfg.HTTPPwd = httpPwd - cfg.IpsAllowList = strings.Split(ipsAllowList, ",") cfg.HostHeaderRewrite = hostHeaderRewrite cfg.UseEncryption = useEncryption cfg.UseCompression = useCompression + if ipsAllowList != "" { + cfg.IpsAllowList = strings.Split(ipsAllowList, ",") + } err = cfg.CheckForCli() if err != nil { diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 503c5eccf43..043201872be 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -124,7 +124,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) * // Register register the route config to reverse proxy // reverse proxy will use CreateConnFn from routeCfg to create a connection to the remote service func (rp *HTTPReverseProxy) Register(routeCfg RouteConfig) error { - err := rp.vhostRouter.Add(routeCfg.Domain, routeCfg.Location, routeCfg.RouteByHTTPUser, &routeCfg) + err := rp.vhostRouter.Add(routeCfg.Domain, routeCfg.Location, routeCfg.RouteByHTTPUser, routeCfg.IpsAllowList, &routeCfg) if err != nil { return err } diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 1e502f605f1..72d1785c10f 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -37,7 +37,7 @@ func NewRouters() *Routers { } } -func (r *Routers) Add(domain, location, httpUser string, payload interface{}) error { +func (r *Routers) Add(domain, location, httpUser string, ipAllowList []string, payload interface{}) error { r.mutex.Lock() defer r.mutex.Unlock() @@ -55,9 +55,9 @@ func (r *Routers) Add(domain, location, httpUser string, payload interface{}) er } var ipValidator *ipfilter.IPFilter - if payload.(*RouteConfig).IpsAllowList != nil { + if ipAllowList != nil { ipValidator = ipfilter.New(ipfilter.Options{ - AllowedIPs: payload.(*RouteConfig).IpsAllowList, + AllowedIPs: ipAllowList, BlockByDefault: true, }) } diff --git a/pkg/util/vhost/vhost.go b/pkg/util/vhost/vhost.go index d4c975dc1d4..4e0a23b62bc 100644 --- a/pkg/util/vhost/vhost.go +++ b/pkg/util/vhost/vhost.go @@ -105,7 +105,7 @@ func (v *Muxer) Listen(ctx context.Context, cfg *RouteConfig) (l *Listener, err accept: make(chan net.Conn), ctx: ctx, } - err = v.registryRouter.Add(cfg.Domain, cfg.Location, cfg.RouteByHTTPUser, l) + err = v.registryRouter.Add(cfg.Domain, cfg.Location, cfg.RouteByHTTPUser, cfg.IpsAllowList, l) if err != nil { return } diff --git a/server/group/http.go b/server/group/http.go index fb00f0c7086..82c774c96dd 100644 --- a/server/group/http.go +++ b/server/group/http.go @@ -93,7 +93,7 @@ func (g *HTTPGroup) Register( // the first proxy in this group tmp := routeConfig // copy object tmp.CreateConnFn = g.createConn - err = g.ctl.vhostRouter.Add(routeConfig.Domain, routeConfig.Location, routeConfig.RouteByHTTPUser, &tmp) + err = g.ctl.vhostRouter.Add(routeConfig.Domain, routeConfig.Location, routeConfig.RouteByHTTPUser, routeConfig.IpsAllowList, &tmp) if err != nil { return } From ce7eda813732d9a286483d900e409f9db9a8e058 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 13:35:50 +0300 Subject: [PATCH 11/24] revert conf --- conf/frpc.ini | 18 ++++++------------ conf/frps.ini | 15 +-------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/conf/frpc.ini b/conf/frpc.ini index 278dc631539..13a8e5f6fc9 100644 --- a/conf/frpc.ini +++ b/conf/frpc.ini @@ -1,15 +1,9 @@ [common] -server_addr = tunnel.io -server_port = 7005 -;protocol = websocket -log_level = debug +server_addr = 127.0.0.1 +server_port = 7000 -[web] +[ssh] type = tcp -local_port = 3002 -remote_port = 84 -meta_Authorization = {{ .Envs.AUTHORIZATION }} -subdomain = ziv -ips_allow_list = "127.0.1.1/16,192.198.100.10" -;http_user = abc -;http_pwd = abc \ No newline at end of file +local_ip = 127.0.0.1 +local_port = 22 +remote_port = 6000 diff --git a/conf/frps.ini b/conf/frps.ini index a919c3d6224..229567a9d6b 100644 --- a/conf/frps.ini +++ b/conf/frps.ini @@ -1,15 +1,2 @@ [common] -bind_port = 7005 -vhost_http_port=82 -subdomain_host=tunnel.io -log_level = trace - -;[plugin.codefresh] -;addr = 127.0.0.1:7200 -;path = /newProxy -;ops = NewProxy - -;[plugin.codefresh] -;addr = 127.0.0.1:7200 -;path = /newWorkConn -;ops = Ping \ No newline at end of file +bind_port = 7000 From 541aeea285e826b0f79b0bffe626c8fd6b317844 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 14:00:04 +0300 Subject: [PATCH 12/24] rename to ipFilter --- pkg/util/vhost/http.go | 4 ++-- pkg/util/vhost/router.go | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 043201872be..3a31ba5ca74 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -189,8 +189,8 @@ func (rp *HTTPReverseProxy) CheckRemoteAddress(domain, location, routeByHTTPUser remoteAddWithoutPort := strings.Split(remoteAdd, ":")[0] vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { - if vr.ipValidator != nil { - return vr.ipValidator.Allowed(remoteAddWithoutPort) + if vr.ipFilter != nil { + return vr.ipFilter.Allowed(remoteAddWithoutPort) } } return true diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 72d1785c10f..36df46bf7f0 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -22,10 +22,10 @@ type Routers struct { } type Router struct { - domain string - location string - httpUser string - ipValidator *ipfilter.IPFilter + domain string + location string + httpUser string + ipFilter *ipfilter.IPFilter // store any object here payload interface{} @@ -54,20 +54,20 @@ func (r *Routers) Add(domain, location, httpUser string, ipAllowList []string, p vrs = make([]*Router, 0, 1) } - var ipValidator *ipfilter.IPFilter + var ipFilter *ipfilter.IPFilter if ipAllowList != nil { - ipValidator = ipfilter.New(ipfilter.Options{ + ipFilter = ipfilter.New(ipfilter.Options{ AllowedIPs: ipAllowList, BlockByDefault: true, }) } vr := &Router{ - domain: domain, - location: location, - httpUser: httpUser, - ipValidator: ipValidator, - payload: payload, + domain: domain, + location: location, + httpUser: httpUser, + ipFilter: ipFilter, + payload: payload, } vrs = append(vrs, vr) sort.Sort(sort.Reverse(ByLocation(vrs))) From 7608ad413584a09d2bbede217b9a98f05301da17 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 16:09:44 +0300 Subject: [PATCH 13/24] add ip allow list test --- test/e2e/basic/http.go | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/e2e/basic/http.go b/test/e2e/basic/http.go index 8fe73594958..193064c217c 100644 --- a/test/e2e/basic/http.go +++ b/test/e2e/basic/http.go @@ -373,4 +373,51 @@ var _ = Describe("[Feature: HTTP]", func() { framework.ExpectNoError(err) framework.ExpectEqualValues(consts.TestString, string(msg)) }) + + It("Ip allow list", func() { + vhostHTTPPort := f.AllocPort() + serverConf := getDefaultServerConf(vhostHTTPPort) + serverConf += ` + subdomain_host = example.com + ` + + fooPort := f.AllocPort() + f.RunServer("", newHTTPServer(fooPort, "foo")) + + barPort := f.AllocPort() + f.RunServer("", newHTTPServer(barPort, "bar")) + + clientConf := consts.DefaultClientConfig + clientConf += fmt.Sprintf(` + [foo] + type = http + local_port = %d + subdomain = foo + ips_allow_list = "127.0.0.1/16" + + + [bar] + type = http + local_port = %d + subdomain = bar + ips_allow_list = "127.1.0.1/16" + `, fooPort, barPort) + + f.RunProcesses([]string{serverConf}, []string{clientConf}) + + // The request should pass and return the expected response + framework.NewRequestExpect(f).Explain("foo subdomain").Port(vhostHTTPPort). + RequestModify(func(r *request.Request) { + r.HTTP().HTTPHost("foo.example.com") + }). + ExpectResp([]byte("foo")). + Ensure() + + // The request should fail with 403 status code due to invalid ip + framework.NewRequestExpect(f).Explain("bar subdomain").Port(vhostHTTPPort). + RequestModify(func(r *request.Request) { + r.HTTP().HTTPHost("bar.example.com") + }). + Ensure(framework.ExpectResponseCode(403)) + }) }) From 170e7a530a7f293099dcfc895c9a3523d2aee77d Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 16:18:30 +0300 Subject: [PATCH 14/24] add ip allow list test --- test/e2e/basic/http.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/e2e/basic/http.go b/test/e2e/basic/http.go index 193064c217c..8d784a07fc5 100644 --- a/test/e2e/basic/http.go +++ b/test/e2e/basic/http.go @@ -387,25 +387,34 @@ var _ = Describe("[Feature: HTTP]", func() { barPort := f.AllocPort() f.RunServer("", newHTTPServer(barPort, "bar")) + bazPort := f.AllocPort() + f.RunServer("", newHTTPServer(barPort, "baz")) + clientConf := consts.DefaultClientConfig clientConf += fmt.Sprintf(` [foo] type = http local_port = %d subdomain = foo - ips_allow_list = "127.0.0.1/16" + ips_allow_list = "" [bar] type = http local_port = %d subdomain = bar + ips_allow_list = "127.0.0.1/16" + + [baz] + type = http + local_port = %d + subdomain = baz ips_allow_list = "127.1.0.1/16" - `, fooPort, barPort) + `, fooPort, barPort, bazPort) f.RunProcesses([]string{serverConf}, []string{clientConf}) - // The request should pass and return the expected response + // The request should pass in case in allow list is empty string framework.NewRequestExpect(f).Explain("foo subdomain").Port(vhostHTTPPort). RequestModify(func(r *request.Request) { r.HTTP().HTTPHost("foo.example.com") @@ -413,6 +422,14 @@ var _ = Describe("[Feature: HTTP]", func() { ExpectResp([]byte("foo")). Ensure() + // The request should pass and return the expected response in case the ip match to the provided allow list + framework.NewRequestExpect(f).Explain("bar subdomain").Port(vhostHTTPPort). + RequestModify(func(r *request.Request) { + r.HTTP().HTTPHost("bar.example.com") + }). + ExpectResp([]byte("bar")). + Ensure() + // The request should fail with 403 status code due to invalid ip framework.NewRequestExpect(f).Explain("bar subdomain").Port(vhostHTTPPort). RequestModify(func(r *request.Request) { From af1649598c14cdef1c1759a3d3923596eb92da18 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 29 Sep 2022 16:21:14 +0300 Subject: [PATCH 15/24] add ip allow list test --- test/e2e/basic/http.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/basic/http.go b/test/e2e/basic/http.go index 8d784a07fc5..d3b9bce2f85 100644 --- a/test/e2e/basic/http.go +++ b/test/e2e/basic/http.go @@ -388,7 +388,7 @@ var _ = Describe("[Feature: HTTP]", func() { f.RunServer("", newHTTPServer(barPort, "bar")) bazPort := f.AllocPort() - f.RunServer("", newHTTPServer(barPort, "baz")) + f.RunServer("", newHTTPServer(bazPort, "baz")) clientConf := consts.DefaultClientConfig clientConf += fmt.Sprintf(` @@ -431,9 +431,9 @@ var _ = Describe("[Feature: HTTP]", func() { Ensure() // The request should fail with 403 status code due to invalid ip - framework.NewRequestExpect(f).Explain("bar subdomain").Port(vhostHTTPPort). + framework.NewRequestExpect(f).Explain("baz subdomain").Port(vhostHTTPPort). RequestModify(func(r *request.Request) { - r.HTTP().HTTPHost("bar.example.com") + r.HTTP().HTTPHost("baz.example.com") }). Ensure(framework.ExpectResponseCode(403)) }) From b51ebe1b08f847df309a2d11d842ab606ec9cf1b Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Tue, 4 Oct 2022 12:19:50 +0300 Subject: [PATCH 16/24] test forwardref --- pkg/util/vhost/http.go | 22 +++++++++++++++++----- pkg/util/vhost/router.go | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 3a31ba5ca74..67ba7b5abbf 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -185,12 +185,13 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p return true } -func (rp *HTTPReverseProxy) CheckRemoteAddress(domain, location, routeByHTTPUser, remoteAdd string) bool { - remoteAddWithoutPort := strings.Split(remoteAdd, ":")[0] +func (rp *HTTPReverseProxy) CheckClientOriginIp(domain, location, routeByHTTPUser, ip string) bool { + ipWithoutPort := strings.Split(ip, ":")[0] vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { if vr.ipFilter != nil { - return vr.ipFilter.Allowed(remoteAddWithoutPort) + frpLog.Debug("validating client origin ip %s", ipWithoutPort) + return vr.ipFilter.Allowed(ipWithoutPort) } } return true @@ -304,8 +305,19 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } - remoteAdd := req.RemoteAddr - if !rp.CheckRemoteAddress(domain, location, user, remoteAdd) { + fwdAddress := req.Header.Get("X-Forwarded-For") + var address = "" + if fwdAddress != "" { + address = fwdAddress + frpLog.Debug(address) + ips := strings.Split(fwdAddress, ", ") + if len(ips) > 1 { + address = ips[0] + } + } else { + address = req.RemoteAddr + } + if !rp.CheckClientOriginIp(domain, location, user, address) { http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 36df46bf7f0..2a2bbfe7924 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -2,6 +2,7 @@ package vhost import ( "errors" + frpLog "github.com/fatedier/frp/pkg/util/log" "sort" "strings" "sync" @@ -55,6 +56,7 @@ func (r *Routers) Add(domain, location, httpUser string, ipAllowList []string, p } var ipFilter *ipfilter.IPFilter + frpLog.Debug("adding allow list %s", ipAllowList) if ipAllowList != nil { ipFilter = ipfilter.New(ipfilter.Options{ AllowedIPs: ipAllowList, From 6a84c202ae2543aaf8b8a7574d078cf7be57f649 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 6 Oct 2022 14:32:47 +0300 Subject: [PATCH 17/24] small refactor --- pkg/util/vhost/http.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 67ba7b5abbf..6924058c441 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -185,8 +185,19 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p return true } -func (rp *HTTPReverseProxy) CheckClientOriginIp(domain, location, routeByHTTPUser, ip string) bool { - ipWithoutPort := strings.Split(ip, ":")[0] +// CheckClientOriginIpAddr To prevent IP spoofing, be sure to delete any pre-existing X-Forwarded-For header coming from the client or an untrusted proxy. +func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTTPUser, fwdIpAdd string) bool { + var addr = "" + if fwdIpAdd != "" { + addr = fwdIpAdd + frpLog.Debug("Received client ip addr list: %s", fwdIpAdd) + ips := strings.Split(fwdIpAdd, ", ") + if len(ips) > 1 { + // Selecting the first ip in the list, it's safe to take it once we ensured the first ip cannot be set by untrusted proxies or the client + addr = ips[0] + } + } + ipWithoutPort := strings.Split(addr, ":")[0] vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { if vr.ipFilter != nil { @@ -305,19 +316,8 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } - fwdAddress := req.Header.Get("X-Forwarded-For") - var address = "" - if fwdAddress != "" { - address = fwdAddress - frpLog.Debug(address) - ips := strings.Split(fwdAddress, ", ") - if len(ips) > 1 { - address = ips[0] - } - } else { - address = req.RemoteAddr - } - if !rp.CheckClientOriginIp(domain, location, user, address) { + fwdIpAddr := req.Header.Get("X-Forwarded-For") + if !rp.CheckClientOriginIpAddr(domain, location, user, fwdIpAddr) { http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } From 65345c5443ee248314527f3e1369eb9ed7243a08 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 6 Oct 2022 15:06:49 +0300 Subject: [PATCH 18/24] small refactor --- pkg/util/vhost/http.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 6924058c441..35a5485d38c 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -186,12 +186,10 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p } // CheckClientOriginIpAddr To prevent IP spoofing, be sure to delete any pre-existing X-Forwarded-For header coming from the client or an untrusted proxy. -func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTTPUser, fwdIpAdd string) bool { - var addr = "" - if fwdIpAdd != "" { - addr = fwdIpAdd - frpLog.Debug("Received client ip addr list: %s", fwdIpAdd) - ips := strings.Split(fwdIpAdd, ", ") +func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTTPUser, addr string) bool { + if addr != "" { + frpLog.Debug("Received client ip addr list: %s", addr) + ips := strings.Split(addr, ", ") if len(ips) > 1 { // Selecting the first ip in the list, it's safe to take it once we ensured the first ip cannot be set by untrusted proxies or the client addr = ips[0] @@ -316,8 +314,13 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } - fwdIpAddr := req.Header.Get("X-Forwarded-For") - if !rp.CheckClientOriginIpAddr(domain, location, user, fwdIpAddr) { + // identifying the originating IP address of a client connecting to a web server through a proxy server + addr := req.Header.Get("X-Forwarded-For") + // For direct access to the server + if addr == "" { + addr = req.RemoteAddr + } + if !rp.CheckClientOriginIpAddr(domain, location, user, addr) { http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } From 0228aa230ceffc67f1eeafa9591fb9e02c5075f4 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Thu, 6 Oct 2022 18:15:07 +0300 Subject: [PATCH 19/24] fix comments --- pkg/util/vhost/http.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 35a5485d38c..48d4ba964db 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -185,7 +185,7 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p return true } -// CheckClientOriginIpAddr To prevent IP spoofing, be sure to delete any pre-existing X-Forwarded-For header coming from the client or an untrusted proxy. +// CheckClientOriginIpAddr to prevent IP spoofing, be sure to delete any pre-existing X-Forwarded-For header coming from the client or an untrusted proxy. func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTTPUser, addr string) bool { if addr != "" { frpLog.Debug("Received client ip addr list: %s", addr) @@ -314,10 +314,10 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) return } - // identifying the originating IP address of a client connecting to a web server through a proxy server + // Identifying the originating IP address of a client connecting to a web server through a proxy server addr := req.Header.Get("X-Forwarded-For") - // For direct access to the server if addr == "" { + // For server direct access addr = req.RemoteAddr } if !rp.CheckClientOriginIpAddr(domain, location, user, addr) { From caeef6935da3a6f169f95da139e0f971a420a878 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 9 Oct 2022 09:24:23 +0300 Subject: [PATCH 20/24] rename --- pkg/util/vhost/router.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index 2a2bbfe7924..f9828689533 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -38,7 +38,7 @@ func NewRouters() *Routers { } } -func (r *Routers) Add(domain, location, httpUser string, ipAllowList []string, payload interface{}) error { +func (r *Routers) Add(domain, location, httpUser string, ipsAllowList []string, payload interface{}) error { r.mutex.Lock() defer r.mutex.Unlock() @@ -56,10 +56,10 @@ func (r *Routers) Add(domain, location, httpUser string, ipAllowList []string, p } var ipFilter *ipfilter.IPFilter - frpLog.Debug("adding allow list %s", ipAllowList) - if ipAllowList != nil { + frpLog.Debug("adding allow list %s", ipsAllowList) + if ipsAllowList != nil { ipFilter = ipfilter.New(ipfilter.Options{ - AllowedIPs: ipAllowList, + AllowedIPs: ipsAllowList, BlockByDefault: true, }) } From 9776c073928bdebdee159893a87a817891c92e18 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 9 Oct 2022 10:09:50 +0300 Subject: [PATCH 21/24] use custom function for spliting host and port --- pkg/util/vhost/http.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 48d4ba964db..81d8298fd4c 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -195,12 +195,15 @@ func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTT addr = ips[0] } } - ipWithoutPort := strings.Split(addr, ":")[0] + host, _, err := net.SplitHostPort(addr) + if err != nil { + return false + } vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { if vr.ipFilter != nil { - frpLog.Debug("validating client origin ip %s", ipWithoutPort) - return vr.ipFilter.Allowed(ipWithoutPort) + frpLog.Debug("validating client origin ip %s", host) + return vr.ipFilter.Allowed(host) } } return true From e4fbe2a28dd92ac79413cea3d778c3d43e39d1c7 Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 9 Oct 2022 13:49:39 +0300 Subject: [PATCH 22/24] wip --- pkg/util/vhost/http.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 81d8298fd4c..3fd235664f3 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -197,6 +197,7 @@ func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTT } host, _, err := net.SplitHostPort(addr) if err != nil { + frpLog.Error("address is invalid %s", err) return false } vr, ok := rp.getVhost(domain, location, routeByHTTPUser) From ed30af2c75739bb970bd2afac8e57371db69706a Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 9 Oct 2022 15:01:47 +0300 Subject: [PATCH 23/24] wip --- cmd/frpc/sub/http.go | 2 +- pkg/util/vhost/http.go | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index fdd8067c8e3..71d4b7df870 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -36,7 +36,7 @@ func init() { httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") - httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\")") + httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\") - IPv4/IPv6 support") httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression") diff --git a/pkg/util/vhost/http.go b/pkg/util/vhost/http.go index 3fd235664f3..b9555ba9879 100644 --- a/pkg/util/vhost/http.go +++ b/pkg/util/vhost/http.go @@ -188,23 +188,18 @@ func (rp *HTTPReverseProxy) CheckAuth(domain, location, routeByHTTPUser, user, p // CheckClientOriginIpAddr to prevent IP spoofing, be sure to delete any pre-existing X-Forwarded-For header coming from the client or an untrusted proxy. func (rp *HTTPReverseProxy) CheckClientOriginIpAddr(domain, location, routeByHTTPUser, addr string) bool { if addr != "" { - frpLog.Debug("Received client ip addr list: %s", addr) + frpLog.Debug("Received client ip addr: %s", addr) ips := strings.Split(addr, ", ") if len(ips) > 1 { // Selecting the first ip in the list, it's safe to take it once we ensured the first ip cannot be set by untrusted proxies or the client addr = ips[0] } } - host, _, err := net.SplitHostPort(addr) - if err != nil { - frpLog.Error("address is invalid %s", err) - return false - } vr, ok := rp.getVhost(domain, location, routeByHTTPUser) if ok { if vr.ipFilter != nil { - frpLog.Debug("validating client origin ip %s", host) - return vr.ipFilter.Allowed(host) + frpLog.Debug("validating client origin ip %s", addr) + return vr.ipFilter.Allowed(addr) } } return true @@ -321,8 +316,8 @@ func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) // Identifying the originating IP address of a client connecting to a web server through a proxy server addr := req.Header.Get("X-Forwarded-For") if addr == "" { - // For server direct access - addr = req.RemoteAddr + // For server direct access, remote address is in "IP:port" format + addr, _, _ = net.SplitHostPort(req.RemoteAddr) } if !rp.CheckClientOriginIpAddr(domain, location, user, addr) { http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) From 3425adefbf56d69726202febc31d1576ae20846f Mon Sep 17 00:00:00 2001 From: ziv-codefresh Date: Sun, 9 Oct 2022 15:49:00 +0300 Subject: [PATCH 24/24] fix desc --- cmd/frpc/sub/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 71d4b7df870..824a5e329c7 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -36,7 +36,7 @@ func init() { httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations") httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "", "http auth user") httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "", "http auth password") - httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\") - IPv4/IPv6 support") + httpCmd.PersistentFlags().StringVarP(&ipsAllowList, "ips_allow_list", "", "", "lists the rules to configure which IP addresses and subnet masks can access your client (e.g \"192.168.0.0/16, 255.255.0.0\")- IPv4/IPv6 support") httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite") httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption") httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")