|
@@ -16,8 +16,14 @@ package server
|
|
|
|
|
|
import (
|
|
import (
|
|
"bytes"
|
|
"bytes"
|
|
|
|
+ "crypto/rand"
|
|
|
|
+ "crypto/rsa"
|
|
|
|
+ "crypto/tls"
|
|
|
|
+ "crypto/x509"
|
|
|
|
+ "encoding/pem"
|
|
"fmt"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
|
+ "math/big"
|
|
"net"
|
|
"net"
|
|
"net/http"
|
|
"net/http"
|
|
"time"
|
|
"time"
|
|
@@ -61,6 +67,9 @@ type Service struct {
|
|
// Accept connections using websocket
|
|
// Accept connections using websocket
|
|
websocketListener frpNet.Listener
|
|
websocketListener frpNet.Listener
|
|
|
|
|
|
|
|
+ // Accept frp tls connections
|
|
|
|
+ tlsListener frpNet.Listener
|
|
|
|
+
|
|
// Manage all controllers
|
|
// Manage all controllers
|
|
ctlManager *ControlManager
|
|
ctlManager *ControlManager
|
|
|
|
|
|
@@ -72,6 +81,8 @@ type Service struct {
|
|
|
|
|
|
// stats collector to store server and proxies stats info
|
|
// stats collector to store server and proxies stats info
|
|
statsCollector stats.Collector
|
|
statsCollector stats.Collector
|
|
|
|
+
|
|
|
|
+ tlsConfig *tls.Config
|
|
}
|
|
}
|
|
|
|
|
|
func NewService() (svr *Service, err error) {
|
|
func NewService() (svr *Service, err error) {
|
|
@@ -84,6 +95,7 @@ func NewService() (svr *Service, err error) {
|
|
TcpPortManager: ports.NewPortManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts),
|
|
TcpPortManager: ports.NewPortManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts),
|
|
UdpPortManager: ports.NewPortManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts),
|
|
UdpPortManager: ports.NewPortManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts),
|
|
},
|
|
},
|
|
|
|
+ tlsConfig: generateTLSConfig(),
|
|
}
|
|
}
|
|
|
|
|
|
// Init group controller
|
|
// Init group controller
|
|
@@ -187,6 +199,12 @@ func NewService() (svr *Service, err error) {
|
|
log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
|
|
log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // frp tls listener
|
|
|
|
+ tlsListener := svr.muxer.Listen(1, 1, func(data []byte) bool {
|
|
|
|
+ return int(data[0]) == frpNet.FRP_TLS_HEAD_BYTE
|
|
|
|
+ })
|
|
|
|
+ svr.tlsListener = frpNet.WrapLogListener(tlsListener)
|
|
|
|
+
|
|
// Create nat hole controller.
|
|
// Create nat hole controller.
|
|
if cfg.BindUdpPort > 0 {
|
|
if cfg.BindUdpPort > 0 {
|
|
var nc *nathole.NatHoleController
|
|
var nc *nathole.NatHoleController
|
|
@@ -225,6 +243,7 @@ func (svr *Service) Run() {
|
|
}
|
|
}
|
|
|
|
|
|
go svr.HandleListener(svr.websocketListener)
|
|
go svr.HandleListener(svr.websocketListener)
|
|
|
|
+ go svr.HandleListener(svr.tlsListener)
|
|
|
|
|
|
svr.HandleListener(svr.listener)
|
|
svr.HandleListener(svr.listener)
|
|
}
|
|
}
|
|
@@ -237,6 +256,7 @@ func (svr *Service) HandleListener(l frpNet.Listener) {
|
|
log.Warn("Listener for incoming connections from client closed")
|
|
log.Warn("Listener for incoming connections from client closed")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+ c = frpNet.CheckAndEnableTLSServerConn(c, svr.tlsConfig)
|
|
|
|
|
|
// Start a new goroutine for dealing connections.
|
|
// Start a new goroutine for dealing connections.
|
|
go func(frpConn frpNet.Conn) {
|
|
go func(frpConn frpNet.Conn) {
|
|
@@ -373,3 +393,24 @@ func (svr *Service) RegisterVisitorConn(visitorConn frpNet.Conn, newMsg *msg.New
|
|
return svr.rc.VisitorManager.NewConn(newMsg.ProxyName, visitorConn, newMsg.Timestamp, newMsg.SignKey,
|
|
return svr.rc.VisitorManager.NewConn(newMsg.ProxyName, visitorConn, newMsg.Timestamp, newMsg.SignKey,
|
|
newMsg.UseEncryption, newMsg.UseCompression)
|
|
newMsg.UseEncryption, newMsg.UseCompression)
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// Setup a bare-bones TLS config for the server
|
|
|
|
+func generateTLSConfig() *tls.Config {
|
|
|
|
+ key, err := rsa.GenerateKey(rand.Reader, 1024)
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ template := x509.Certificate{SerialNumber: big.NewInt(1)}
|
|
|
|
+ certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
|
|
|
+ certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
|
|
|
+
|
|
|
|
+ tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ return &tls.Config{Certificates: []tls.Certificate{tlsCert}}
|
|
|
|
+}
|