mirror of
https://gitee.com/IrisVega/frp.git
synced 2024-11-01 22:31:29 +08:00
Merge branch 'dev' into feature/detailed-errors-to-client
# Conflicts: # models/config/server_common.go
This commit is contained in:
commit
9440bc5d72
@ -461,6 +461,8 @@ Config `tls_enable = true` in the `[common]` section to `frpc.ini` to enable thi
|
|||||||
|
|
||||||
For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection.
|
For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection.
|
||||||
|
|
||||||
|
To enforce `frps` to only accept TLS connections - configure `tls_only = true` in the `[common]` section in `frps.ini`.
|
||||||
|
|
||||||
### Hot-Reloading frpc configuration
|
### Hot-Reloading frpc configuration
|
||||||
|
|
||||||
The `admin_addr` and `admin_port` fields are required for enabling HTTP API:
|
The `admin_addr` and `admin_port` fields are required for enabling HTTP API:
|
||||||
|
@ -131,6 +131,9 @@ type ServerCommonConf struct {
|
|||||||
// may proxy to. If this value is 0, no limit will be applied. By default,
|
// may proxy to. If this value is 0, no limit will be applied. By default,
|
||||||
// this value is 0.
|
// this value is 0.
|
||||||
MaxPortsPerClient int64 `json:"max_ports_per_client"`
|
MaxPortsPerClient int64 `json:"max_ports_per_client"`
|
||||||
|
// TlsOnly specifies whether to only accept TLS-encrypted connections. By
|
||||||
|
// default, the value is false.
|
||||||
|
TlsOnly bool `json:"tls_only"`
|
||||||
// HeartBeatTimeout specifies the maximum time to wait for a heartbeat
|
// HeartBeatTimeout specifies the maximum time to wait for a heartbeat
|
||||||
// before terminating the connection. It is not recommended to change this
|
// before terminating the connection. It is not recommended to change this
|
||||||
// value. By default, this value is 90.
|
// value. By default, this value is 90.
|
||||||
@ -171,6 +174,7 @@ func GetDefaultServerConf() ServerCommonConf {
|
|||||||
AllowPorts: make(map[int]struct{}),
|
AllowPorts: make(map[int]struct{}),
|
||||||
MaxPoolCount: 5,
|
MaxPoolCount: 5,
|
||||||
MaxPortsPerClient: 0,
|
MaxPortsPerClient: 0,
|
||||||
|
TlsOnly: false,
|
||||||
HeartBeatTimeout: 90,
|
HeartBeatTimeout: 90,
|
||||||
UserConnTimeout: 10,
|
UserConnTimeout: 10,
|
||||||
Custom404Page: "",
|
Custom404Page: "",
|
||||||
@ -388,6 +392,12 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
|||||||
cfg.HeartBeatTimeout = v
|
cfg.HeartBeatTimeout = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tmpStr, ok = conf.Get("common", "tls_only"); ok && tmpStr == "true" {
|
||||||
|
cfg.TlsOnly = true
|
||||||
|
} else {
|
||||||
|
cfg.TlsOnly = false
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ func (svr *Service) HandleListener(l net.Listener) {
|
|||||||
|
|
||||||
log.Trace("start check TLS connection...")
|
log.Trace("start check TLS connection...")
|
||||||
originConn := c
|
originConn := c
|
||||||
c, err = frpNet.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, connReadTimeout)
|
c, err = frpNet.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, svr.cfg.TlsOnly, connReadTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err)
|
log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err)
|
||||||
originConn.Close()
|
originConn.Close()
|
||||||
|
@ -186,3 +186,95 @@ func TestTLSOverWebsocket(t *testing.T) {
|
|||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(consts.TEST_TCP_ECHO_STR, res)
|
assert.Equal(consts.TEST_TCP_ECHO_STR, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FRPS_TLS_ONLY_TCP_CONF = `
|
||||||
|
[common]
|
||||||
|
bind_addr = 0.0.0.0
|
||||||
|
bind_port = 20000
|
||||||
|
log_file = console
|
||||||
|
log_level = debug
|
||||||
|
token = 123456
|
||||||
|
tls_only = true
|
||||||
|
`
|
||||||
|
|
||||||
|
const FRPC_TLS_ONLY_TCP_CONF = `
|
||||||
|
[common]
|
||||||
|
server_addr = 127.0.0.1
|
||||||
|
server_port = 20000
|
||||||
|
log_file = console
|
||||||
|
log_level = debug
|
||||||
|
token = 123456
|
||||||
|
protocol = tcp
|
||||||
|
tls_enable = true
|
||||||
|
|
||||||
|
[tcp]
|
||||||
|
type = tcp
|
||||||
|
local_port = 10701
|
||||||
|
remote_port = 20801
|
||||||
|
`
|
||||||
|
|
||||||
|
const FRPC_TLS_ONLY_NO_TLS_TCP_CONF = `
|
||||||
|
[common]
|
||||||
|
server_addr = 127.0.0.1
|
||||||
|
server_port = 20000
|
||||||
|
log_file = console
|
||||||
|
log_level = debug
|
||||||
|
token = 123456
|
||||||
|
protocol = tcp
|
||||||
|
tls_enable = false
|
||||||
|
|
||||||
|
[tcp]
|
||||||
|
type = tcp
|
||||||
|
local_port = 10701
|
||||||
|
remote_port = 20802
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestTlsOnlyOverTCP(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
frpsCfgPath, err := config.GenerateConfigFile(consts.FRPS_NORMAL_CONFIG, FRPS_TLS_ONLY_TCP_CONF)
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer os.Remove(frpsCfgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
frpcWithTlsCfgPath, err := config.GenerateConfigFile(consts.FRPC_NORMAL_CONFIG, FRPC_TLS_ONLY_TCP_CONF)
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer os.Remove(frpcWithTlsCfgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
frpsProcess := util.NewProcess(consts.FRPS_BIN_PATH, []string{"-c", frpsCfgPath})
|
||||||
|
err = frpsProcess.Start()
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer frpsProcess.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
|
frpcProcessWithTls := util.NewProcess(consts.FRPC_BIN_PATH, []string{"-c", frpcWithTlsCfgPath})
|
||||||
|
err = frpcProcessWithTls.Start()
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer frpcProcessWithTls.Stop()
|
||||||
|
}
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
|
// test tcp over tls
|
||||||
|
res, err := util.SendTcpMsg("127.0.0.1:20801", consts.TEST_TCP_ECHO_STR)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(consts.TEST_TCP_ECHO_STR, res)
|
||||||
|
frpcProcessWithTls.Stop()
|
||||||
|
|
||||||
|
frpcWithoutTlsCfgPath, err := config.GenerateConfigFile(consts.FRPC_NORMAL_CONFIG, FRPC_TLS_ONLY_NO_TLS_TCP_CONF)
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer os.Remove(frpcWithTlsCfgPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
frpcProcessWithoutTls := util.NewProcess(consts.FRPC_BIN_PATH, []string{"-c", frpcWithoutTlsCfgPath})
|
||||||
|
err = frpcProcessWithoutTls.Start()
|
||||||
|
if assert.NoError(err) {
|
||||||
|
defer frpcProcessWithoutTls.Stop()
|
||||||
|
}
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
|
// test tcp without tls
|
||||||
|
_, err = util.SendTcpMsg("127.0.0.1:20802", consts.TEST_TCP_ECHO_STR)
|
||||||
|
assert.Error(err)
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@ package net
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ func WrapTLSClientConn(c net.Conn, tlsConfig *tls.Config) (out net.Conn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, timeout time.Duration) (out net.Conn, err error) {
|
func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, tlsOnly bool, timeout time.Duration) (out net.Conn, err error) {
|
||||||
sc, r := gnet.NewSharedConnSize(c, 2)
|
sc, r := gnet.NewSharedConnSize(c, 2)
|
||||||
buf := make([]byte, 1)
|
buf := make([]byte, 1)
|
||||||
var n int
|
var n int
|
||||||
@ -46,6 +47,10 @@ func CheckAndEnableTLSServerConnWithTimeout(c net.Conn, tlsConfig *tls.Config, t
|
|||||||
if n == 1 && int(buf[0]) == FRP_TLS_HEAD_BYTE {
|
if n == 1 && int(buf[0]) == FRP_TLS_HEAD_BYTE {
|
||||||
out = tls.Server(c, tlsConfig)
|
out = tls.Server(c, tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
|
if tlsOnly {
|
||||||
|
err = fmt.Errorf("non-TLS connection received on a TlsOnly server")
|
||||||
|
return
|
||||||
|
}
|
||||||
out = sc
|
out = sc
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user