Skip to content

Commit

Permalink
Merge pull request #2782 from fatedier/dev
Browse files Browse the repository at this point in the history
bump version
  • Loading branch information
fatedier authored Jan 26, 2022
2 parents 1437509 + 9ca2b58 commit 2dab5d0
Show file tree
Hide file tree
Showing 35 changed files with 513 additions and 530 deletions.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ frp is a fast reverse proxy to help you expose a local server behind a NAT or fi

frp also has a P2P connect mode.

<h3 align="center">Platinum Sponsors</h3>
<!--platinum sponsors start-->

<p align="center">
<a href="https://www.doppler.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="400px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_doppler.png">
</a>
</p>

<!--platinum sponsors end-->

<h3 align="center">Silver Sponsors</h3>

* Sakura Frp - 欢迎点击 "加入我们"

## Table of Contents

<!-- vim-markdown-toc GFM -->
Expand Down Expand Up @@ -77,7 +92,9 @@ frp also has a P2P connect mode.

frp is under development. Try the latest release version in the `master` branch, or use the `dev` branch for the version in development.

**The protocol might change at a release and we don't promise backwards compatibility. Please check the release log when upgrading the client and the server.**
We are working on v2 version and trying to do some code refactor and improvements. It won't be compatible with v1.

We will switch v0 to v1 at the right time and only accept bug fixes and improvements instead of big feature requirements.

## Architecture

Expand Down Expand Up @@ -867,7 +884,7 @@ In this example, it will set header `X-From-Where: frp` in the HTTP request.

This feature is for http proxy only.

You can get user's real IP from HTTP request headers `X-Forwarded-For` and `X-Real-IP`.
You can get user's real IP from HTTP request headers `X-Forwarded-For`.

#### Proxy Protocol

Expand Down Expand Up @@ -983,11 +1000,13 @@ server_port = 7000
type = tcpmux
multiplexer = httpconnect
custom_domains = test1
local_port = 80

[proxy2]
type = tcpmux
multiplexer = httpconnect
custom_domains = test2
local_port = 8080
```

In the above configuration - frps can be contacted on port 1337 with a HTTP CONNECT header such as:
Expand Down
19 changes: 19 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

<h3 align="center">Platinum Sponsors</h3>
<!--platinum sponsors start-->

<p align="center">
<a href="https://www.doppler.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
<img width="400px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_doppler.png">
</a>
</p>

<!--platinum sponsors end-->

<h3 align="center">Silver Sponsors</h3>

* Sakura Frp - 欢迎点击 "加入我们"

## 为什么使用 frp ?

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:
Expand All @@ -25,6 +40,10 @@ frp 目前已被很多公司广泛用于测试、生产环境。

master 分支用于发布稳定版本,dev 分支用于开发,您可以尝试下载最新的 release 版本进行测试。

我们正在进行 v2 大版本的开发,将会尝试在各个方面进行重构和升级,且不会与 v1 版本进行兼容,预计会持续一段时间。

现在的 v0 版本将会在合适的时间切换为 v1 版本并且保证兼容性,后续只做 bug 修复和优化,不再进行大的功能性更新。

## 文档

完整文档已经迁移至 [https://gofrp.org](https://gofrp.org/docs)
Expand Down
10 changes: 7 additions & 3 deletions Release.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
### New

* Add `/healthz` API.
* frpc support `disable_custom_tls_first_byte` .If set true, frpc will not send custom header byte.
* Added `connect_server_local_ip` in frpc to specify local IP connected to frps.
* Added `tcp_mux_keepalive_interval` both in frpc and frps to set `tcp_mux` keepalive interval seconds if `tcp_mux` is enabled. After using this params, you can set `heartbeat_interval` to `-1` to disable application layer heartbeat to reduce traffic usage(Make sure frps is in the latest version).

### Improve

* Use go standard embed package instead of statik.
* Server Plugin: Added `client_address` in Login Operation.

### Fix

* Remove authentication for healthz api.
20 changes: 11 additions & 9 deletions client/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ func (svr *Service) RunAdminServer(address string) (err error) {
// url router
router := mux.NewRouter()

router.HandleFunc("/healthz", svr.healthz)

subRouter := router.NewRoute().Subrouter()
user, passwd := svr.cfg.AdminUser, svr.cfg.AdminPwd
router.Use(frpNet.NewHTTPAuthMiddleware(user, passwd).Middleware)
subRouter.Use(frpNet.NewHTTPAuthMiddleware(user, passwd).Middleware)

// api, see admin_api.go
router.HandleFunc("/healthz", svr.healthz)
router.HandleFunc("/api/reload", svr.apiReload).Methods("GET")
router.HandleFunc("/api/status", svr.apiStatus).Methods("GET")
router.HandleFunc("/api/config", svr.apiGetConfig).Methods("GET")
router.HandleFunc("/api/config", svr.apiPutConfig).Methods("PUT")
subRouter.HandleFunc("/api/reload", svr.apiReload).Methods("GET")
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
router.Handle("/favicon.ico", http.FileServer(assets.FileSystem)).Methods("GET")
router.PathPrefix("/static/").Handler(frpNet.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))).Methods("GET")
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
subRouter.Handle("/favicon.ico", http.FileServer(assets.FileSystem)).Methods("GET")
subRouter.PathPrefix("/static/").Handler(frpNet.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))).Methods("GET")
subRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/static/", http.StatusMovedPermanently)
})

Expand Down
58 changes: 47 additions & 11 deletions client/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

"github.com/fatedier/golib/control/shutdown"
"github.com/fatedier/golib/crypto"
libdial "github.com/fatedier/golib/net/dial"
fmux "github.com/hashicorp/yamux"
)

Expand Down Expand Up @@ -234,12 +235,36 @@ func (ctl *Control) connectServer() (conn net.Conn, err error) {
}
}

address := net.JoinHostPort(ctl.clientCfg.ServerAddr, strconv.Itoa(ctl.clientCfg.ServerPort))
conn, err = frpNet.ConnectServerByProxyWithTLS(ctl.clientCfg.HTTPProxy, ctl.clientCfg.Protocol, address, tlsConfig, ctl.clientCfg.DisableCustomTLSFirstByte)

proxyType, addr, auth, err := libdial.ParseProxyURL(ctl.clientCfg.HTTPProxy)
if err != nil {
xl.Error("fail to parse proxy url")
return nil, err
}
dialOptions := []libdial.DialOption{}
protocol := ctl.clientCfg.Protocol
if protocol == "websocket" {
protocol = "tcp"
dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: frpNet.DialHookWebsocket()}))
}
if ctl.clientCfg.ConnectServerLocalIP != "" {
dialOptions = append(dialOptions, libdial.WithLocalAddr(ctl.clientCfg.ConnectServerLocalIP))
}
dialOptions = append(dialOptions,
libdial.WithProtocol(protocol),
libdial.WithProxy(proxyType, addr),
libdial.WithProxyAuth(auth),
libdial.WithTLSConfig(tlsConfig),
libdial.WithAfterHook(libdial.AfterHook{
Hook: frpNet.DialHookCustomTLSHeadByte(tlsConfig != nil, ctl.clientCfg.DisableCustomTLSFirstByte),
}),
)
conn, err = libdial.Dial(
net.JoinHostPort(ctl.clientCfg.ServerAddr, strconv.Itoa(ctl.clientCfg.ServerPort)),
dialOptions...,
)
if err != nil {
xl.Warn("start new connection to server error: %v", err)
return
return nil, err
}
}
return
Expand Down Expand Up @@ -308,16 +333,27 @@ func (ctl *Control) msgHandler() {
}()
defer ctl.msgHandlerShutdown.Done()

hbSend := time.NewTicker(time.Duration(ctl.clientCfg.HeartbeatInterval) * time.Second)
defer hbSend.Stop()
hbCheck := time.NewTicker(time.Second)
defer hbCheck.Stop()
var hbSendCh <-chan time.Time
// TODO(fatedier): disable heartbeat if TCPMux is enabled.
// Just keep it here to keep compatible with old version frps.
if ctl.clientCfg.HeartbeatInterval > 0 {
hbSend := time.NewTicker(time.Duration(ctl.clientCfg.HeartbeatInterval) * time.Second)
defer hbSend.Stop()
hbSendCh = hbSend.C
}

ctl.lastPong = time.Now()
var hbCheckCh <-chan time.Time
// Check heartbeat timeout only if TCPMux is not enabled and users don't disable heartbeat feature.
if ctl.clientCfg.HeartbeatInterval > 0 && ctl.clientCfg.HeartbeatTimeout > 0 && !ctl.clientCfg.TCPMux {
hbCheck := time.NewTicker(time.Second)
defer hbCheck.Stop()
hbCheckCh = hbCheck.C
}

ctl.lastPong = time.Now()
for {
select {
case <-hbSend.C:
case <-hbSendCh:
// send heartbeat to server
xl.Debug("send heartbeat to server")
pingMsg := &msg.Ping{}
Expand All @@ -326,7 +362,7 @@ func (ctl *Control) msgHandler() {
return
}
ctl.sendCh <- pingMsg
case <-hbCheck.C:
case <-hbCheckCh:
if time.Since(ctl.lastPong) > time.Duration(ctl.clientCfg.HeartbeatTimeout)*time.Second {
xl.Warn("heartbeat timeout")
// let reader() stop
Expand Down
3 changes: 2 additions & 1 deletion client/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (

"github.com/fatedier/golib/errors"
frpIo "github.com/fatedier/golib/io"
libdial "github.com/fatedier/golib/net/dial"
"github.com/fatedier/golib/pool"
fmux "github.com/hashicorp/yamux"
pp "github.com/pires/go-proxyproto"
Expand Down Expand Up @@ -790,7 +791,7 @@ func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf
return
}

localConn, err := frpNet.ConnectServer("tcp", fmt.Sprintf("%s:%d", localInfo.LocalIP, localInfo.LocalPort))
localConn, err := libdial.Dial(net.JoinHostPort(localInfo.LocalIP, strconv.Itoa(localInfo.LocalPort)))
if err != nil {
workConn.Close()
xl.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIP, localInfo.LocalPort, err)
Expand Down
32 changes: 29 additions & 3 deletions client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
frpNet "github.com/fatedier/frp/pkg/util/net"
"github.com/fatedier/frp/pkg/util/version"
"github.com/fatedier/frp/pkg/util/xlog"
libdial "github.com/fatedier/golib/net/dial"

fmux "github.com/hashicorp/yamux"
)
Expand Down Expand Up @@ -228,8 +229,33 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
}
}

address := net.JoinHostPort(svr.cfg.ServerAddr, strconv.Itoa(svr.cfg.ServerPort))
conn, err = frpNet.ConnectServerByProxyWithTLS(svr.cfg.HTTPProxy, svr.cfg.Protocol, address, tlsConfig, svr.cfg.DisableCustomTLSFirstByte)
proxyType, addr, auth, err := libdial.ParseProxyURL(svr.cfg.HTTPProxy)
if err != nil {
xl.Error("fail to parse proxy url")
return
}
dialOptions := []libdial.DialOption{}
protocol := svr.cfg.Protocol
if protocol == "websocket" {
protocol = "tcp"
dialOptions = append(dialOptions, libdial.WithAfterHook(libdial.AfterHook{Hook: frpNet.DialHookWebsocket()}))
}
if svr.cfg.ConnectServerLocalIP != "" {
dialOptions = append(dialOptions, libdial.WithLocalAddr(svr.cfg.ConnectServerLocalIP))
}
dialOptions = append(dialOptions,
libdial.WithProtocol(protocol),
libdial.WithProxy(proxyType, addr),
libdial.WithProxyAuth(auth),
libdial.WithTLSConfig(tlsConfig),
libdial.WithAfterHook(libdial.AfterHook{
Hook: frpNet.DialHookCustomTLSHeadByte(tlsConfig != nil, svr.cfg.DisableCustomTLSFirstByte),
}),
)
conn, err = libdial.Dial(
net.JoinHostPort(svr.cfg.ServerAddr, strconv.Itoa(svr.cfg.ServerPort)),
dialOptions...,
)
if err != nil {
return
}
Expand All @@ -245,7 +271,7 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {

if svr.cfg.TCPMux {
fmuxCfg := fmux.DefaultConfig()
fmuxCfg.KeepAliveInterval = 20 * time.Second
fmuxCfg.KeepAliveInterval = time.Duration(svr.cfg.TCPMuxKeepaliveInterval) * time.Second
fmuxCfg.LogOutput = io.Discard
session, err = fmux.Client(conn, fmuxCfg)
if err != nil {
Expand Down
10 changes: 9 additions & 1 deletion conf/frpc_full.ini
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pool_count = 5

# if tcp stream multiplexing is used, default is true, it must be same with frps
tcp_mux = true
# specify keep alive interval for tcp mux.
# only valid if tcp_mux is true.
# tcp_mux_keepalive_interval = 60

# your proxy name will be changed to {user}.{proxy}
user = your_name
Expand All @@ -73,6 +76,10 @@ login_fail_exit = true
# now it supports tcp, kcp and websocket, default is tcp
protocol = tcp

# set client binding ip when connect server, default is empty.
# only when protocol = tcp or websocket, the value will be used.
connect_server_local_ip = 0.0.0.0

# if tls_enable is true, frpc will connect frps by tls
tls_enable = true

Expand All @@ -89,7 +96,8 @@ tls_enable = true
# start = ssh,dns

# heartbeat configure, it's not recommended to modify the default value
# the default value of heartbeat_interval is 10 and heartbeat_timeout is 90
# The default value of heartbeat_interval is 10 and heartbeat_timeout is 90. Set negative value
# to disable it.
# heartbeat_interval = 30
# heartbeat_timeout = 90

Expand Down
5 changes: 4 additions & 1 deletion conf/frps_full.ini
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ oidc_skip_expiry_check = false
oidc_skip_issuer_check = false

# heartbeat configure, it's not recommended to modify the default value
# the default value of heartbeat_timeout is 90
# the default value of heartbeat_timeout is 90. Set negative value to disable it.
# heartbeat_timeout = 90

# user_conn_timeout configure, it's not recommended to modify the default value
Expand Down Expand Up @@ -121,6 +121,9 @@ subdomain_host = frps.com

# if tcp stream multiplexing is used, default is true
tcp_mux = true
# specify keep alive interval for tcp mux.
# only valid if tcp_mux is true.
# tcp_mux_keepalive_interval = 60

# custom 404 page for HTTP requests
# custom_404_page = /path/to/404.html
Expand Down
Binary file added doc/pic/sponsor_doppler.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion doc/server_plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ Client login operation
"privilege_key": <string>,
"run_id": <string>,
"pool_count": <int>,
"metas": map<string>string
"metas": map<string>string,
"client_address": <string>
}
}
```
Expand Down
Loading

0 comments on commit 2dab5d0

Please sign in to comment.