Skip to content

Commit

Permalink
Merge pull request fatedier#795 from fatedier/lb
Browse files Browse the repository at this point in the history
support lb
  • Loading branch information
fatedier authored May 26, 2018
2 parents cb1bf71 + 102408d commit 85dd41c
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 54 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ frp is a fast reverse proxy to help you expose a local server behind a NAT or fi
* [TCP Stream Multiplexing](#tcp-stream-multiplexing)
* [Support KCP Protocol](#support-kcp-protocol)
* [Connection Pool](#connection-pool)
* [Load balancing](#load-balancing)
* [Rewriting the Host Header](#rewriting-the-host-header)
* [Set Headers In HTTP Request](#set-headers-in-http-request)
* [Get Real IP](#get-real-ip)
Expand Down Expand Up @@ -484,6 +485,32 @@ This feature is fit for a large number of short connections.
pool_count = 1
```

### Load balancing

Load balancing is supported by `group`.
This feature is available only for type `tcp` now.

```ini
# frpc.ini
[test1]
type = tcp
local_port = 8080
remote_port = 80
group = web
group_key = 123

[test2]
type = tcp
local_port = 8081
remote_port = 80
group = web
group_key = 123
```

`group_key` is used for authentication.

Proxies in same group will accept connections from port 80 randomly.

### Rewriting the Host Header

When forwarding to a local port, frp does not modify the tunneled HTTP requests at all, they are copied to your server byte-for-byte as they are received. Some application servers use the Host header for determining which development site to display. For this reason, frp can rewrite your requests with a modified host header. Use the `host_header_rewrite` switch to rewrite incoming HTTP requests.
Expand Down Expand Up @@ -644,7 +671,6 @@ plugin_http_passwd = abc

* Log http request information in frps.
* Direct reverse proxy, like haproxy.
* Load balance to different service in frpc.
* kubernetes ingress support.

## Contributing
Expand Down
32 changes: 29 additions & 3 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp
* [TCP 多路复用](#tcp-多路复用)
* [底层通信可选 kcp 协议](#底层通信可选-kcp-协议)
* [连接池](#连接池)
* [负载均衡](#负载均衡)
* [修改 Host Header](#修改-host-header)
* [设置 http 请求的 header](#设置-http-请求的-header)
* [设置 HTTP 请求的 header](#设置-http-请求的-header)
* [获取用户真实 IP](#获取用户真实-ip)
* [通过密码保护你的 web 服务](#通过密码保护你的-web-服务)
* [自定义二级域名](#自定义二级域名)
Expand Down Expand Up @@ -511,6 +512,32 @@ tcp_mux = false
pool_count = 1
```

### 负载均衡

可以将多个相同类型的 proxy 加入到同一个 group 中,从而实现负载均衡的功能。
目前只支持 tcp 类型的 proxy。

```ini
# fprc.ini
[test1]
type = tcp
local_port = 8080
remote_port = 80
group = web
group_key = 123

[test2]
type = tcp
local_port = 8081
remote_port = 80
group = web
group_key = 123
```

用户连接 frps 服务器的 80 端口,frps 会将接收到的用户连接随机分发给其中一个存活的 proxy。这样可以在一台 frpc 机器挂掉后仍然有其他节点能够提供服务。

要求 `group_key` 相同,做权限验证,且 `remote_port` 相同。

### 修改 Host Header

通常情况下 frp 不会修改转发的任何数据。但有一些后端服务会根据 http 请求 header 中的 host 字段来展现不同的网站,例如 nginx 的虚拟主机服务,启用 host-header 的修改功能可以动态修改 http 请求中的 host 字段。该功能仅限于 http 类型的代理。
Expand All @@ -526,7 +553,7 @@ host_header_rewrite = dev.yourdomain.com

原来 http 请求中的 host 字段 `test.yourdomain.com` 转发到后端服务时会被替换为 `dev.yourdomain.com`

### 设置 http 请求的 header
### 设置 HTTP 请求的 header

对于 `type = http` 的代理,可以设置在转发中动态添加的 header 参数。

Expand Down Expand Up @@ -684,7 +711,6 @@ plugin_http_passwd = abc

* frps 记录 http 请求日志。
* frps 支持直接反向代理,类似 haproxy。
* frpc 支持负载均衡到后端不同服务。
* 集成对 k8s 等平台的支持。

## 为 frp 做贡献
Expand Down
6 changes: 5 additions & 1 deletion conf/frpc_full.ini
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ login_fail_exit = true
protocol = tcp

# specify a dns server, so frpc will use this instead of default one
dns_server = 8.8.8.8
# dns_server = 8.8.8.8

# proxy names you want to start divided by ','
# default is empty, means all proxies
Expand All @@ -69,6 +69,10 @@ use_encryption = false
use_compression = false
# remote port listen by frps
remote_port = 6001
# frps will load balancing connections for proxies in same group
group = test_group
# group should have same group key
group_key = 123456

[ssh_random]
type = tcp
Expand Down
17 changes: 14 additions & 3 deletions models/config/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ type BaseProxyConf struct {
ProxyName string `json:"proxy_name"`
ProxyType string `json:"proxy_type"`

UseEncryption bool `json:"use_encryption"`
UseCompression bool `json:"use_compression"`
UseEncryption bool `json:"use_encryption"`
UseCompression bool `json:"use_compression"`
Group string `json:"group"`
GroupKey string `json:"group_key"`
}

func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf {
Expand All @@ -112,7 +114,9 @@ func (cfg *BaseProxyConf) compare(cmp *BaseProxyConf) bool {
if cfg.ProxyName != cmp.ProxyName ||
cfg.ProxyType != cmp.ProxyType ||
cfg.UseEncryption != cmp.UseEncryption ||
cfg.UseCompression != cmp.UseCompression {
cfg.UseCompression != cmp.UseCompression ||
cfg.Group != cmp.Group ||
cfg.GroupKey != cmp.GroupKey {
return false
}
return true
Expand All @@ -123,6 +127,8 @@ func (cfg *BaseProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
cfg.ProxyType = pMsg.ProxyType
cfg.UseEncryption = pMsg.UseEncryption
cfg.UseCompression = pMsg.UseCompression
cfg.Group = pMsg.Group
cfg.GroupKey = pMsg.GroupKey
}

func (cfg *BaseProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) error {
Expand All @@ -142,6 +148,9 @@ func (cfg *BaseProxyConf) UnmarshalFromIni(prefix string, name string, section i
if ok && tmpStr == "true" {
cfg.UseCompression = true
}

cfg.Group = section["group"]
cfg.GroupKey = section["group_key"]
return nil
}

Expand All @@ -150,6 +159,8 @@ func (cfg *BaseProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
pMsg.ProxyType = cfg.ProxyType
pMsg.UseEncryption = cfg.UseEncryption
pMsg.UseCompression = cfg.UseCompression
pMsg.Group = cfg.Group
pMsg.GroupKey = cfg.GroupKey
}

// Bind info
Expand Down
2 changes: 2 additions & 0 deletions models/msg/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type NewProxy struct {
ProxyType string `json:"proxy_type"`
UseEncryption bool `json:"use_encryption"`
UseCompression bool `json:"use_compression"`
Group string `json:"group"`
GroupKey string `json:"group_key"`

// tcp and udp only
RemotePort int `json:"remote_port"`
Expand Down
25 changes: 25 additions & 0 deletions server/group/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2018 fatedier, [email protected]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package group

import (
"errors"
)

var (
ErrGroupAuthFailed = errors.New("group auth failed")
ErrGroupParamsInvalid = errors.New("group params invalid")
ErrListenerClosed = errors.New("group listener closed")
)
Loading

0 comments on commit 85dd41c

Please sign in to comment.