Skip to content

Commit

Permalink
Merge pull request #1122 from fatedier/dev
Browse files Browse the repository at this point in the history
bump version to v0.25.0
  • Loading branch information
fatedier authored Mar 11, 2019
2 parents cbf9c73 + d1f1c72 commit 90b7f20
Show file tree
Hide file tree
Showing 28 changed files with 604 additions and 132 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ sudo: false
language: go

go:
- 1.10.x
- 1.11.x
- 1.12.x

install:
- make
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ Now it also try to support p2p connect.
* [Configuration File](#configuration-file)
* [Configuration file template](#configuration-file-template)
* [Dashboard](#dashboard)
* [Admin UI](#admin-ui)
* [Authentication](#authentication)
* [Encryption and Compression](#encryption-and-compression)
* [TLS](#tls)
* [Hot-Reload frpc configuration](#hot-reload-frpc-configuration)
* [Get proxy status from client](#get-proxy-status-from-client)
* [Port White List](#port-white-list)
Expand Down Expand Up @@ -389,6 +391,22 @@ Then visit `http://[server_addr]:7500` to see dashboard, default username and pa

![dashboard](/doc/pic/dashboard.png)

### Admin UI

Admin UI help you check and manage frpc's configure.

Configure a address for admin UI to enable this feature:

```ini
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
```

Then visit `http://127.0.0.1:7400` to see admin UI, default username and password are both `admin`.

### Authentication

`token` in frps.ini and frpc.ini should be same.
Expand All @@ -407,6 +425,14 @@ use_encryption = true
use_compression = true
```

#### TLS

frp support TLS protocol between frpc and frps since v0.25.0.

Config `tls_enable = true` in `common` section to frpc.ini to enable this feature.

For port multiplexing, frp send a first byte 0x17 to dial a TLS connection.

### Hot-Reload frpc configuration

First you need to set admin port in frpc's configure file to let it provide HTTP API for more features.
Expand Down Expand Up @@ -592,7 +618,7 @@ custom_domains = test.yourdomain.com
host_header_rewrite = dev.yourdomain.com
```

If `host_header_rewrite` is specified, the host header will be rewritten to match the hostname portion of the forwarding address.
The `Host` request header will be rewritten to `Host: dev.yourdomain.com` before it reach your local http server.

### Set Headers In HTTP Request

Expand Down Expand Up @@ -736,8 +762,6 @@ plugin_http_passwd = abc
## Development Plan

* Log http request information in frps.
* Direct reverse proxy, like haproxy.
* kubernetes ingress support.

## Contributing

Expand Down
29 changes: 29 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp
* [配置文件](#配置文件)
* [配置文件模版渲染](#配置文件模版渲染)
* [Dashboard](#dashboard)
* [Admin UI](#admin-ui)
* [身份验证](#身份验证)
* [加密与压缩](#加密与压缩)
* [TLS](#tls)
* [客户端热加载配置文件](#客户端热加载配置文件)
* [客户端查看代理状态](#客户端查看代理状态)
* [端口白名单](#端口白名单)
Expand All @@ -47,6 +49,7 @@ frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp
* [开发计划](#开发计划)
* [为 frp 做贡献](#为-frp-做贡献)
* [捐助](#捐助)
* [知识星球](#知识星球)
* [支付宝扫码捐赠](#支付宝扫码捐赠)
* [微信支付捐赠](#微信支付捐赠)
* [Paypal 捐赠](#paypal-捐赠)
Expand Down Expand Up @@ -404,6 +407,24 @@ dashboard_pwd = admin

![dashboard](/doc/pic/dashboard.png)

### Admin UI

Admin UI 可以帮助用户通过浏览器来查询和管理客户端的 proxy 状态和配置。

需要在 frpc.ini 中指定 admin 服务使用的端口,即可开启此功能:

```ini
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
```

打开浏览器通过 `http://127.0.0.1:7400` 访问 Admin UI,用户名密码默认为 `admin`

如果想要在外网环境访问 Admin UI,将 7400 端口映射出去即可,但需要重视安全风险。

### 身份验证

服务端和客户端的 common 配置中的 `token` 参数一致则身份验证通过。
Expand All @@ -426,6 +447,14 @@ use_compression = true

如果传输的报文长度较长,通过设置 `use_compression = true` 对传输内容进行压缩,可以有效减小 frpc 与 frps 之间的网络流量,加快流量转发速度,但是会额外消耗一些 cpu 资源。

#### TLS

从 v0.25.0 版本开始 frpc 和 frps 之间支持通过 TLS 协议加密传输。通过在 `frpc.ini``common` 中配置 `tls_enable = true` 来启用此功能,安全性更高。

为了端口复用,frp 建立 TLS 连接的第一个字节为 0x17。

**注意: 启用此功能后除 xtcp 外,不需要再设置 use_encryption。**

### 客户端热加载配置文件

当修改了 frpc 中的代理配置,可以通过 `frpc reload` 命令来动态加载配置文件,通常会在 10 秒内完成代理的更新。
Expand Down
11 changes: 9 additions & 2 deletions client/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package client

import (
"crypto/tls"
"fmt"
"io"
"runtime/debug"
Expand Down Expand Up @@ -166,8 +167,14 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
}
conn = frpNet.WrapConn(stream)
} else {
conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
var tlsConfig *tls.Config
if g.GlbClientCfg.TLSEnable {
tlsConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig)
if err != nil {
ctl.Warn("start new connection to server error: %v", err)
return
Expand Down
89 changes: 79 additions & 10 deletions client/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
"strconv"
"strings"
"sync"
"time"

Expand All @@ -33,6 +36,7 @@ import (
"github.com/fatedier/golib/errors"
frpIo "github.com/fatedier/golib/io"
"github.com/fatedier/golib/pool"
fmux "github.com/hashicorp/yamux"
)

// Proxy defines how to handle work connections for different proxy type.
Expand Down Expand Up @@ -278,32 +282,97 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) {
return
}

pxy.Trace("get natHoleRespMsg, sid [%s], client address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr)
pxy.Trace("get natHoleRespMsg, sid [%s], client address [%s] visitor address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr, natHoleRespMsg.VisitorAddr)

// Send sid to visitor udp address.
time.Sleep(time.Second)
// Send detect message
array := strings.Split(natHoleRespMsg.VisitorAddr, ":")
if len(array) <= 1 {
pxy.Error("get NatHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
}
laddr, _ := net.ResolveUDPAddr("udp", clientConn.LocalAddr().String())
daddr, err := net.ResolveUDPAddr("udp", natHoleRespMsg.VisitorAddr)
/*
for i := 1000; i < 65000; i++ {
pxy.sendDetectMsg(array[0], int64(i), laddr, "a")
}
*/
port, err := strconv.ParseInt(array[1], 10, 64)
if err != nil {
pxy.Error("resolve visitor udp address error: %v", err)
pxy.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
return
}
pxy.sendDetectMsg(array[0], int(port), laddr, []byte(natHoleRespMsg.Sid))
pxy.Trace("send all detect msg done")

lConn, err := net.DialUDP("udp", laddr, daddr)
msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{})

// Listen for clientConn's address and wait for visitor connection
lConn, err := net.ListenUDP("udp", laddr)
if err != nil {
pxy.Error("dial visitor udp address error: %v", err)
pxy.Error("listen on visitorConn's local adress error: %v", err)
return
}
lConn.Write([]byte(natHoleRespMsg.Sid))
defer lConn.Close()

kcpConn, err := frpNet.NewKcpConnFromUdp(lConn, true, natHoleRespMsg.VisitorAddr)
lConn.SetReadDeadline(time.Now().Add(8 * time.Second))
sidBuf := pool.GetBuf(1024)
var uAddr *net.UDPAddr
n, uAddr, err = lConn.ReadFromUDP(sidBuf)
if err != nil {
pxy.Warn("get sid from visitor error: %v", err)
return
}
lConn.SetReadDeadline(time.Time{})
if string(sidBuf[:n]) != natHoleRespMsg.Sid {
pxy.Warn("incorrect sid from visitor")
return
}
pool.PutBuf(sidBuf)
pxy.Info("nat hole connection make success, sid [%s]", natHoleRespMsg.Sid)

lConn.WriteToUDP(sidBuf[:n], uAddr)

kcpConn, err := frpNet.NewKcpConnFromUdp(lConn, false, natHoleRespMsg.VisitorAddr)
if err != nil {
pxy.Error("create kcp connection from udp connection error: %v", err)
return
}

fmuxCfg := fmux.DefaultConfig()
fmuxCfg.KeepAliveInterval = 5 * time.Second
fmuxCfg.LogOutput = ioutil.Discard
sess, err := fmux.Server(kcpConn, fmuxCfg)
if err != nil {
pxy.Error("create yamux server from kcp connection error: %v", err)
return
}
defer sess.Close()
muxConn, err := sess.Accept()
if err != nil {
pxy.Error("accept for yamux connection error: %v", err)
return
}

HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf,
frpNet.WrapConn(kcpConn), []byte(pxy.cfg.Sk))
frpNet.WrapConn(muxConn), []byte(pxy.cfg.Sk))
}

func (pxy *XtcpProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) {
daddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", addr, port))
if err != nil {
return err
}

tConn, err := net.DialUDP("udp", laddr, daddr)
if err != nil {
return err
}

//uConn := ipv4.NewConn(tConn)
//uConn.SetTTL(3)

tConn.Write(content)
tConn.Close()
return nil
}

// UDP
Expand Down
11 changes: 9 additions & 2 deletions client/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package client

import (
"crypto/tls"
"fmt"
"io/ioutil"
"runtime"
Expand Down Expand Up @@ -151,8 +152,14 @@ func (svr *Service) keepControllerWorking() {
// conn: control connection
// session: if it's not nil, using tcp mux
func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) {
conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
var tlsConfig *tls.Config
if g.GlbClientCfg.TLSEnable {
tlsConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig)
if err != nil {
return
}
Expand Down
Loading

0 comments on commit 90b7f20

Please sign in to comment.