From 6a1f15b25ed3fe5b71b097a187d0975c31445a73 Mon Sep 17 00:00:00 2001
From: fatedier
Date: Thu, 25 Apr 2019 12:01:57 +0800
Subject: [PATCH 1/3] support proxy protocol in unix_domain_socket
---
client/proxy/proxy.go | 65 ++++++++++++++++-------------
models/plugin/http_proxy.go | 2 +-
models/plugin/https2http.go | 7 +---
models/plugin/plugin.go | 2 +-
models/plugin/socks5.go | 2 +-
models/plugin/static_file.go | 2 +-
models/plugin/unix_domain_socket.go | 5 ++-
7 files changed, 45 insertions(+), 40 deletions(-)
diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go
index c68fe70..bc230f4 100644
--- a/client/proxy/proxy.go
+++ b/client/proxy/proxy.go
@@ -503,10 +503,43 @@ func HandleTcpWorkConnection(localInfo *config.LocalSvrConf, proxyPlugin plugin.
remote = frpIo.WithCompression(remote)
}
+ // check if we need to send proxy protocol info
+ var extraInfo []byte
+ if baseInfo.ProxyProtocolVersion != "" {
+ if m.SrcAddr != "" && m.SrcPort != 0 {
+ if m.DstAddr == "" {
+ m.DstAddr = "127.0.0.1"
+ }
+ h := &pp.Header{
+ Command: pp.PROXY,
+ SourceAddress: net.ParseIP(m.SrcAddr),
+ SourcePort: m.SrcPort,
+ DestinationAddress: net.ParseIP(m.DstAddr),
+ DestinationPort: m.DstPort,
+ }
+
+ if h.SourceAddress.To16() == nil {
+ h.TransportProtocol = pp.TCPv4
+ } else {
+ h.TransportProtocol = pp.TCPv6
+ }
+
+ if baseInfo.ProxyProtocolVersion == "v1" {
+ h.Version = 1
+ } else if baseInfo.ProxyProtocolVersion == "v2" {
+ h.Version = 2
+ }
+
+ buf := bytes.NewBuffer(nil)
+ h.WriteTo(buf)
+ extraInfo = buf.Bytes()
+ }
+ }
+
if proxyPlugin != nil {
// if plugin is set, let plugin handle connections first
workConn.Debug("handle by plugin: %s", proxyPlugin.Name())
- proxyPlugin.Handle(remote, workConn)
+ proxyPlugin.Handle(remote, workConn, extraInfo)
workConn.Debug("handle by plugin finished")
return
} else {
@@ -520,34 +553,8 @@ func HandleTcpWorkConnection(localInfo *config.LocalSvrConf, proxyPlugin plugin.
workConn.Debug("join connections, localConn(l[%s] r[%s]) workConn(l[%s] r[%s])", localConn.LocalAddr().String(),
localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String())
- // check if we need to send proxy protocol info
- if baseInfo.ProxyProtocolVersion != "" {
- if m.SrcAddr != "" && m.SrcPort != 0 {
- if m.DstAddr == "" {
- m.DstAddr = "127.0.0.1"
- }
- h := &pp.Header{
- Command: pp.PROXY,
- SourceAddress: net.ParseIP(m.SrcAddr),
- SourcePort: m.SrcPort,
- DestinationAddress: net.ParseIP(m.DstAddr),
- DestinationPort: m.DstPort,
- }
-
- if h.SourceAddress.To16() == nil {
- h.TransportProtocol = pp.TCPv4
- } else {
- h.TransportProtocol = pp.TCPv6
- }
-
- if baseInfo.ProxyProtocolVersion == "v1" {
- h.Version = 1
- } else if baseInfo.ProxyProtocolVersion == "v2" {
- h.Version = 2
- }
-
- h.WriteTo(localConn)
- }
+ if len(extraInfo) > 0 {
+ localConn.Write(extraInfo)
}
frpIo.Join(localConn, remote)
diff --git a/models/plugin/http_proxy.go b/models/plugin/http_proxy.go
index a9ff6ef..3afa2cb 100644
--- a/models/plugin/http_proxy.go
+++ b/models/plugin/http_proxy.go
@@ -64,7 +64,7 @@ func (hp *HttpProxy) Name() string {
return PluginHttpProxy
}
-func (hp *HttpProxy) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+func (hp *HttpProxy) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte) {
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
sc, rd := gnet.NewSharedConn(wrapConn)
diff --git a/models/plugin/https2http.go b/models/plugin/https2http.go
index 746995f..6e84ad6 100644
--- a/models/plugin/https2http.go
+++ b/models/plugin/https2http.go
@@ -100,16 +100,11 @@ func (p *HTTPS2HTTPPlugin) genTLSConfig() (*tls.Config, error) {
return config, nil
}
-func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+func (p *HTTPS2HTTPPlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte) {
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
p.l.PutConn(wrapConn)
}
-func (p *HTTPS2HTTPPlugin) handleRequest(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("hello"))
- return
-}
-
func (p *HTTPS2HTTPPlugin) Name() string {
return PluginHTTPS2HTTP
}
diff --git a/models/plugin/plugin.go b/models/plugin/plugin.go
index 653e48a..cfad551 100644
--- a/models/plugin/plugin.go
+++ b/models/plugin/plugin.go
@@ -46,7 +46,7 @@ func Create(name string, params map[string]string) (p Plugin, err error) {
type Plugin interface {
Name() string
- Handle(conn io.ReadWriteCloser, realConn frpNet.Conn)
+ Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte)
Close() error
}
diff --git a/models/plugin/socks5.go b/models/plugin/socks5.go
index fba9f5d..447602a 100644
--- a/models/plugin/socks5.go
+++ b/models/plugin/socks5.go
@@ -53,7 +53,7 @@ func NewSocks5Plugin(params map[string]string) (p Plugin, err error) {
return
}
-func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+func (sp *Socks5Plugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte) {
defer conn.Close()
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
sp.Server.ServeConn(wrapConn)
diff --git a/models/plugin/static_file.go b/models/plugin/static_file.go
index 52b0c0c..080ff74 100644
--- a/models/plugin/static_file.go
+++ b/models/plugin/static_file.go
@@ -72,7 +72,7 @@ func NewStaticFilePlugin(params map[string]string) (Plugin, error) {
return sp, nil
}
-func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+func (sp *StaticFilePlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte) {
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
sp.l.PutConn(wrapConn)
}
diff --git a/models/plugin/unix_domain_socket.go b/models/plugin/unix_domain_socket.go
index b1ce622..86833e2 100644
--- a/models/plugin/unix_domain_socket.go
+++ b/models/plugin/unix_domain_socket.go
@@ -53,11 +53,14 @@ func NewUnixDomainSocketPlugin(params map[string]string) (p Plugin, err error) {
return
}
-func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn) {
+func (uds *UnixDomainSocketPlugin) Handle(conn io.ReadWriteCloser, realConn frpNet.Conn, extraBufToLocal []byte) {
localConn, err := net.DialUnix("unix", nil, uds.UnixAddr)
if err != nil {
return
}
+ if len(extraBufToLocal) > 0 {
+ localConn.Write(extraBufToLocal)
+ }
frpIo.Join(localConn, conn)
}
From 0dfd3a421cc40717ba8f19aa43a4117aec233952 Mon Sep 17 00:00:00 2001
From: fatedier
Date: Thu, 25 Apr 2019 12:29:34 +0800
Subject: [PATCH 2/3] frps: support custom_404_page
---
conf/frps_full.ini | 3 +++
models/config/server_common.go | 6 ++++++
server/service.go | 3 +++
utils/vhost/resource.go | 27 +++++++++++++++++++++++++--
utils/vhost/reverseproxy.go | 3 ++-
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/conf/frps_full.ini b/conf/frps_full.ini
index d45bb0a..a8c0e63 100644
--- a/conf/frps_full.ini
+++ b/conf/frps_full.ini
@@ -65,3 +65,6 @@ subdomain_host = frps.com
# if tcp stream multiplexing is used, default is true
tcp_mux = true
+
+# custom 404 page for HTTP requests
+# custom_404_page = /path/to/404.html
diff --git a/models/config/server_common.go b/models/config/server_common.go
index d468376..1e54bdd 100644
--- a/models/config/server_common.go
+++ b/models/config/server_common.go
@@ -69,6 +69,7 @@ type ServerCommonConf struct {
Token string `json:"token"`
SubDomainHost string `json:"subdomain_host"`
TcpMux bool `json:"tcp_mux"`
+ Custom404Page string `json:"custom_404_page"`
AllowPorts map[int]struct{}
MaxPoolCount int64 `json:"max_pool_count"`
@@ -104,6 +105,7 @@ func GetDefaultServerConf() *ServerCommonConf {
MaxPortsPerClient: 0,
HeartBeatTimeout: 90,
UserConnTimeout: 10,
+ Custom404Page: "",
}
}
@@ -293,6 +295,10 @@ func UnmarshalServerConfFromIni(defaultCfg *ServerCommonConf, content string) (c
cfg.TcpMux = true
}
+ if tmpStr, ok = conf.Get("common", "custom_404_page"); ok {
+ cfg.Custom404Page = tmpStr
+ }
+
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
if errRet != nil {
diff --git a/server/service.go b/server/service.go
index ac5602a..6cd8e50 100644
--- a/server/service.go
+++ b/server/service.go
@@ -108,6 +108,9 @@ func NewService() (svr *Service, err error) {
return
}
+ // Init 404 not found page
+ vhost.NotFoundPagePath = cfg.Custom404Page
+
var (
httpMuxOn bool
httpsMuxOn bool
diff --git a/utils/vhost/resource.go b/utils/vhost/resource.go
index 40cb952..9553e7e 100644
--- a/utils/vhost/resource.go
+++ b/utils/vhost/resource.go
@@ -15,13 +15,18 @@
package vhost
import (
+ "bytes"
"io/ioutil"
"net/http"
- "strings"
+ frpLog "github.com/fatedier/frp/utils/log"
"github.com/fatedier/frp/utils/version"
)
+var (
+ NotFoundPagePath = ""
+)
+
const (
NotFound = `
@@ -46,10 +51,28 @@ Please try again later.
`
)
+func getNotFoundPageContent() []byte {
+ var (
+ buf []byte
+ err error
+ )
+ if NotFoundPagePath != "" {
+ buf, err = ioutil.ReadFile(NotFoundPagePath)
+ if err != nil {
+ frpLog.Warn("read custom 404 page error: %v", err)
+ buf = []byte(NotFound)
+ }
+ } else {
+ buf = []byte(NotFound)
+ }
+ return buf
+}
+
func notFoundResponse() *http.Response {
header := make(http.Header)
header.Set("server", "frp/"+version.Full())
header.Set("Content-Type", "text/html")
+
res := &http.Response{
Status: "Not Found",
StatusCode: 404,
@@ -57,7 +80,7 @@ func notFoundResponse() *http.Response {
ProtoMajor: 1,
ProtoMinor: 0,
Header: header,
- Body: ioutil.NopCloser(strings.NewReader(NotFound)),
+ Body: ioutil.NopCloser(bytes.NewReader(getNotFoundPageContent())),
}
return res
}
diff --git a/utils/vhost/reverseproxy.go b/utils/vhost/reverseproxy.go
index 5662589..45f25be 100644
--- a/utils/vhost/reverseproxy.go
+++ b/utils/vhost/reverseproxy.go
@@ -254,7 +254,8 @@ func (p *ReverseProxy) serveHTTP(rw http.ResponseWriter, req *http.Request) {
if err != nil {
p.logf("http: proxy error: %v", err)
rw.WriteHeader(http.StatusNotFound)
- rw.Write([]byte(NotFound))
+
+ rw.Write(getNotFoundPageContent())
return
}
From 285d1eba0dfc900b41e34bd94d0e15f43cfef9cc Mon Sep 17 00:00:00 2001
From: fatedier
Date: Thu, 25 Apr 2019 12:31:20 +0800
Subject: [PATCH 3/3] bump version to v0.27.0
---
utils/version/version.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utils/version/version.go b/utils/version/version.go
index d2bd46c..9bc4934 100644
--- a/utils/version/version.go
+++ b/utils/version/version.go
@@ -19,7 +19,7 @@ import (
"strings"
)
-var version string = "0.26.0"
+var version string = "0.27.0"
func Full() string {
return version