service.go 14.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright 2017 fatedier, fatedier@gmail.com
//
// 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.

F
fatedier 已提交
15 16 17
package server

import (
F
fatedier 已提交
18
	"bytes"
F
fatedier 已提交
19
	"context"
F
fatedier 已提交
20 21 22 23 24
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
F
fatedier 已提交
25
	"fmt"
F
fatedier 已提交
26
	"io/ioutil"
F
fatedier 已提交
27
	"math/big"
F
fatedier 已提交
28 29
	"net"
	"net/http"
F
fatedier 已提交
30 31 32
	"time"

	"github.com/fatedier/frp/assets"
33
	"github.com/fatedier/frp/models/auth"
34
	"github.com/fatedier/frp/models/config"
35
	modelmetrics "github.com/fatedier/frp/models/metrics"
F
fatedier 已提交
36
	"github.com/fatedier/frp/models/msg"
F
fatedier 已提交
37
	"github.com/fatedier/frp/models/nathole"
F
fatedier 已提交
38
	plugin "github.com/fatedier/frp/models/plugin/server"
F
fatedier 已提交
39
	"github.com/fatedier/frp/server/controller"
F
fatedier 已提交
40
	"github.com/fatedier/frp/server/group"
41
	"github.com/fatedier/frp/server/metrics"
F
fatedier 已提交
42
	"github.com/fatedier/frp/server/ports"
F
fatedier 已提交
43
	"github.com/fatedier/frp/server/proxy"
F
fatedier 已提交
44
	"github.com/fatedier/frp/utils/log"
45
	frpNet "github.com/fatedier/frp/utils/net"
46
	"github.com/fatedier/frp/utils/tcpmux"
F
fatedier 已提交
47 48 49
	"github.com/fatedier/frp/utils/util"
	"github.com/fatedier/frp/utils/version"
	"github.com/fatedier/frp/utils/vhost"
F
fatedier 已提交
50
	"github.com/fatedier/frp/utils/xlog"
51

F
fatedier 已提交
52
	"github.com/fatedier/golib/net/mux"
F
fatedier 已提交
53
	fmux "github.com/hashicorp/yamux"
F
fatedier 已提交
54 55
)

F
fatedier 已提交
56
const (
57 58
	connReadTimeout       time.Duration = 10 * time.Second
	vhostReadWriteTimeout time.Duration = 30 * time.Second
F
fatedier 已提交
59 60
)

61
// Server service
F
fatedier 已提交
62
type Service struct {
63
	// Dispatch connections to different handlers listen on same port
64 65
	muxer *mux.Mux

66
	// Accept connections from client
F
fatedier 已提交
67
	listener net.Listener
F
fatedier 已提交
68

69
	// Accept connections using kcp
F
fatedier 已提交
70
	kcpListener net.Listener
F
fatedier 已提交
71

F
FishFish 已提交
72
	// Accept connections using websocket
F
fatedier 已提交
73
	websocketListener net.Listener
F
FishFish 已提交
74

F
fatedier 已提交
75
	// Accept frp tls connections
F
fatedier 已提交
76
	tlsListener net.Listener
F
fatedier 已提交
77

F
fatedier 已提交
78 79 80 81 82 83
	// Manage all controllers
	ctlManager *ControlManager

	// Manage all proxies
	pxyManager *proxy.ProxyManager

F
fatedier 已提交
84 85 86
	// Manage all plugins
	pluginManager *plugin.Manager

F
fatedier 已提交
87 88 89
	// HTTP vhost router
	httpVhostRouter *vhost.VhostRouters

F
fatedier 已提交
90
	// All resource managers and controllers
F
fatedier 已提交
91 92
	rc *controller.ResourceController

93 94 95
	// Verifies authentication based on selected method
	authVerifier auth.Verifier

F
fatedier 已提交
96
	tlsConfig *tls.Config
97 98

	cfg config.ServerCommonConf
F
fatedier 已提交
99 100
}

101
func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
F
fatedier 已提交
102
	svr = &Service{
F
fatedier 已提交
103 104 105
		ctlManager:    NewControlManager(),
		pxyManager:    proxy.NewProxyManager(),
		pluginManager: plugin.NewManager(),
F
fatedier 已提交
106 107
		rc: &controller.ResourceController{
			VisitorManager: controller.NewVisitorManager(),
F
fatedier 已提交
108 109 110
			TcpPortManager: ports.NewPortManager("tcp", cfg.ProxyBindAddr, cfg.AllowPorts),
			UdpPortManager: ports.NewPortManager("udp", cfg.ProxyBindAddr, cfg.AllowPorts),
		},
F
fatedier 已提交
111
		httpVhostRouter: vhost.NewVhostRouters(),
112
		authVerifier:    auth.NewAuthVerifier(cfg.AuthServerConfig),
F
fatedier 已提交
113
		tlsConfig:       generateTLSConfig(),
114
		cfg:             cfg,
F
fatedier 已提交
115
	}
F
fatedier 已提交
116

G
Guy Lewin 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	// Create tcpmux httpconnect multiplexer.
	if cfg.TcpMuxHttpConnectPort > 0 {
		var l net.Listener
		l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.TcpMuxHttpConnectPort))
		if err != nil {
			err = fmt.Errorf("Create server listener error, %v", err)
			return
		}

		svr.rc.TcpMuxHttpConnectMuxer, err = tcpmux.NewHttpConnectTcpMuxer(l, vhostReadWriteTimeout)
		if err != nil {
			err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
			return
		}
		log.Info("tcpmux httpconnect multiplexer listen on %s:%d", cfg.ProxyBindAddr, cfg.TcpMuxHttpConnectPort)
	}

F
fatedier 已提交
134 135 136 137 138
	// Init all plugins
	for name, options := range cfg.HTTPPlugins {
		svr.pluginManager.Register(plugin.NewHTTPPluginOptions(options))
		log.Info("plugin [%s] has been registered", name)
	}
139
	svr.rc.PluginManager = svr.pluginManager
F
fatedier 已提交
140

F
fatedier 已提交
141
	// Init group controller
F
fatedier 已提交
142
	svr.rc.TcpGroupCtl = group.NewTcpGroupCtl(svr.rc.TcpPortManager)
F
fatedier 已提交
143

F
fatedier 已提交
144 145 146
	// Init HTTP group controller
	svr.rc.HTTPGroupCtl = group.NewHTTPGroupController(svr.httpVhostRouter)

G
Guy Lewin 已提交
147 148 149
	// Init TCP mux group controller
	svr.rc.TcpMuxGroupCtl = group.NewTcpMuxGroupCtl(svr.rc.TcpMuxHttpConnectMuxer)

F
fatedier 已提交
150 151 152
	// Init 404 not found page
	vhost.NotFoundPagePath = cfg.Custom404Page

153 154 155 156 157 158 159 160 161 162 163 164 165
	var (
		httpMuxOn  bool
		httpsMuxOn bool
	)
	if cfg.BindAddr == cfg.ProxyBindAddr {
		if cfg.BindPort == cfg.VhostHttpPort {
			httpMuxOn = true
		}
		if cfg.BindPort == cfg.VhostHttpsPort {
			httpsMuxOn = true
		}
	}

F
fatedier 已提交
166
	// Listen for accepting connections from client.
167
	ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindPort))
F
fatedier 已提交
168 169 170 171
	if err != nil {
		err = fmt.Errorf("Create server listener error, %v", err)
		return
	}
F
FishFish 已提交
172

F
fix ci  
fatedier 已提交
173 174
	svr.muxer = mux.NewMux(ln)
	go svr.muxer.Serve()
F
FishFish 已提交
175 176
	ln = svr.muxer.DefaultListener()

F
fatedier 已提交
177
	svr.listener = ln
F
fatedier 已提交
178
	log.Info("frps tcp listen on %s:%d", cfg.BindAddr, cfg.BindPort)
F
fatedier 已提交
179 180

	// Listen for accepting connections from client using kcp protocol.
F
fatedier 已提交
181 182
	if cfg.KcpBindPort > 0 {
		svr.kcpListener, err = frpNet.ListenKcp(cfg.BindAddr, cfg.KcpBindPort)
F
fatedier 已提交
183
		if err != nil {
F
fatedier 已提交
184
			err = fmt.Errorf("Listen on kcp address udp [%s:%d] error: %v", cfg.BindAddr, cfg.KcpBindPort, err)
F
fatedier 已提交
185 186
			return
		}
F
fatedier 已提交
187
		log.Info("frps kcp listen on udp %s:%d", cfg.BindAddr, cfg.KcpBindPort)
F
fatedier 已提交
188
	}
F
fatedier 已提交
189

F
fatedier 已提交
190
	// Listen for accepting connections from client using websocket protocol.
F
fatedier 已提交
191
	websocketPrefix := []byte("GET " + frpNet.FrpWebsocketPath)
F
fatedier 已提交
192 193 194 195 196
	websocketLn := svr.muxer.Listen(0, uint32(len(websocketPrefix)), func(data []byte) bool {
		return bytes.Equal(data, websocketPrefix)
	})
	svr.websocketListener = frpNet.NewWebsocketListener(websocketLn)

F
fatedier 已提交
197
	// Create http vhost muxer.
F
fatedier 已提交
198
	if cfg.VhostHttpPort > 0 {
F
fatedier 已提交
199 200
		rp := vhost.NewHttpReverseProxy(vhost.HttpReverseProxyOptions{
			ResponseHeaderTimeoutS: cfg.VhostHttpTimeout,
F
fatedier 已提交
201
		}, svr.httpVhostRouter)
F
fatedier 已提交
202
		svr.rc.HttpReverseProxy = rp
F
fatedier 已提交
203 204 205 206 207

		address := fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort)
		server := &http.Server{
			Addr:    address,
			Handler: rp,
F
fatedier 已提交
208
		}
F
fatedier 已提交
209
		var l net.Listener
210
		if httpMuxOn {
F
fatedier 已提交
211
			l = svr.muxer.ListenHttp(1)
212 213 214 215 216 217
		} else {
			l, err = net.Listen("tcp", address)
			if err != nil {
				err = fmt.Errorf("Create vhost http listener error, %v", err)
				return
			}
F
fatedier 已提交
218
		}
F
fatedier 已提交
219
		go server.Serve(l)
F
fatedier 已提交
220
		log.Info("http service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort)
F
fatedier 已提交
221 222 223
	}

	// Create https vhost muxer.
F
fatedier 已提交
224
	if cfg.VhostHttpsPort > 0 {
225 226
		var l net.Listener
		if httpsMuxOn {
F
fatedier 已提交
227
			l = svr.muxer.ListenHttps(1)
228 229 230 231 232 233
		} else {
			l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort))
			if err != nil {
				err = fmt.Errorf("Create server listener error, %v", err)
				return
			}
F
fatedier 已提交
234
		}
235

236
		svr.rc.VhostHttpsMuxer, err = vhost.NewHttpsMuxer(l, vhostReadWriteTimeout)
F
fatedier 已提交
237 238 239 240
		if err != nil {
			err = fmt.Errorf("Create vhost httpsMuxer error, %v", err)
			return
		}
F
fatedier 已提交
241 242 243
		log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
	}

F
fatedier 已提交
244
	// frp tls listener
F
fatedier 已提交
245
	svr.tlsListener = svr.muxer.Listen(1, 1, func(data []byte) bool {
F
fatedier 已提交
246 247 248
		return int(data[0]) == frpNet.FRP_TLS_HEAD_BYTE
	})

F
fatedier 已提交
249 250
	// Create nat hole controller.
	if cfg.BindUdpPort > 0 {
F
fatedier 已提交
251
		var nc *nathole.NatHoleController
F
fatedier 已提交
252
		addr := fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindUdpPort)
F
fatedier 已提交
253
		nc, err = nathole.NewNatHoleController(addr)
F
fatedier 已提交
254 255 256 257
		if err != nil {
			err = fmt.Errorf("Create nat hole controller error, %v", err)
			return
		}
F
fatedier 已提交
258
		svr.rc.NatHoleController = nc
F
fatedier 已提交
259
		log.Info("nat hole udp service listen on %s:%d", cfg.BindAddr, cfg.BindUdpPort)
F
fatedier 已提交
260 261
	}

F
fatedier 已提交
262
	var statsEnable bool
F
fatedier 已提交
263
	// Create dashboard web server.
F
fatedier 已提交
264
	if cfg.DashboardPort > 0 {
265 266 267 268 269 270 271
		// Init dashboard assets
		err = assets.Load(cfg.AssetsDir)
		if err != nil {
			err = fmt.Errorf("Load assets error: %v", err)
			return
		}

F
fatedier 已提交
272
		err = svr.RunDashboardServer(cfg.DashboardAddr, cfg.DashboardPort)
F
fatedier 已提交
273 274 275 276
		if err != nil {
			err = fmt.Errorf("Create dashboard web server error, %v", err)
			return
		}
T
timerever 已提交
277
		log.Info("Dashboard listen on %s:%d", cfg.DashboardAddr, cfg.DashboardPort)
F
fatedier 已提交
278
		statsEnable = true
F
fatedier 已提交
279
	}
280 281 282 283 284 285
	if statsEnable {
		modelmetrics.EnableMem()
		if cfg.EnablePrometheus {
			modelmetrics.EnablePrometheus()
		}
	}
F
fatedier 已提交
286 287 288 289
	return
}

func (svr *Service) Run() {
F
fatedier 已提交
290 291
	if svr.rc.NatHoleController != nil {
		go svr.rc.NatHoleController.Run()
F
fatedier 已提交
292
	}
293
	if svr.cfg.KcpBindPort > 0 {
F
fatedier 已提交
294 295 296
		go svr.HandleListener(svr.kcpListener)
	}

F
fatedier 已提交
297
	go svr.HandleListener(svr.websocketListener)
F
fatedier 已提交
298
	go svr.HandleListener(svr.tlsListener)
F
fatedier 已提交
299

F
fatedier 已提交
300 301 302
	svr.HandleListener(svr.listener)
}

303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
func (svr *Service) handleConnection(ctx context.Context, conn net.Conn) {
	xl := xlog.FromContextSafe(ctx)

	var (
		rawMsg msg.Message
		err    error
	)

	conn.SetReadDeadline(time.Now().Add(connReadTimeout))
	if rawMsg, err = msg.ReadMsg(conn); err != nil {
		log.Trace("Failed to read message: %v", err)
		conn.Close()
		return
	}
	conn.SetReadDeadline(time.Time{})

	switch m := rawMsg.(type) {
	case *msg.Login:
		// server plugin hook
		content := &plugin.LoginContent{
			Login: *m,
		}
		retContent, err := svr.pluginManager.Login(content)
		if err == nil {
			m = &retContent.Login
			err = svr.RegisterControl(conn, m)
		}

		// If login failed, send error message there.
		// Otherwise send success message in control's work goroutine.
		if err != nil {
			xl.Warn("register control error: %v", err)
			msg.WriteMsg(conn, &msg.LoginResp{
				Version: version.Full(),
				Error:   util.GenerateResponseErrorString("register control error", err, svr.cfg.DetailedErrorsToClient),
			})
			conn.Close()
		}
	case *msg.NewWorkConn:
		if err := svr.RegisterWorkConn(conn, m); err != nil {
			conn.Close()
		}
	case *msg.NewVisitorConn:
		if err = svr.RegisterVisitorConn(conn, m); err != nil {
			xl.Warn("register visitor conn error: %v", err)
			msg.WriteMsg(conn, &msg.NewVisitorConnResp{
				ProxyName: m.ProxyName,
				Error:     util.GenerateResponseErrorString("register visitor conn error", err, svr.cfg.DetailedErrorsToClient),
			})
			conn.Close()
		} else {
			msg.WriteMsg(conn, &msg.NewVisitorConnResp{
				ProxyName: m.ProxyName,
				Error:     "",
			})
		}
	default:
		log.Warn("Error message type for the new connection [%s]", conn.RemoteAddr().String())
		conn.Close()
	}
}

F
fatedier 已提交
365
func (svr *Service) HandleListener(l net.Listener) {
F
fatedier 已提交
366 367
	// Listen for incoming connections from client.
	for {
F
fatedier 已提交
368
		c, err := l.Accept()
F
fatedier 已提交
369 370 371 372
		if err != nil {
			log.Warn("Listener for incoming connections from client closed")
			return
		}
F
fatedier 已提交
373 374
		// inject xlog object into net.Conn context
		xl := xlog.New()
375 376 377
		ctx := context.Background()

		c = frpNet.NewContextConn(c, xlog.NewContext(ctx, xl))
378 379 380

		log.Trace("start check TLS connection...")
		originConn := c
381
		c, err = frpNet.CheckAndEnableTLSServerConnWithTimeout(c, svr.tlsConfig, svr.cfg.TlsOnly, connReadTimeout)
382 383 384 385 386 387
		if err != nil {
			log.Warn("CheckAndEnableTLSServerConnWithTimeout error: %v", err)
			originConn.Close()
			continue
		}
		log.Trace("success check TLS connection")
F
fatedier 已提交
388 389

		// Start a new goroutine for dealing connections.
390
		go func(ctx context.Context, frpConn net.Conn) {
391
			if svr.cfg.TcpMux {
F
fatedier 已提交
392
				fmuxCfg := fmux.DefaultConfig()
F
fatedier 已提交
393
				fmuxCfg.KeepAliveInterval = 20 * time.Second
F
fatedier 已提交
394 395
				fmuxCfg.LogOutput = ioutil.Discard
				session, err := fmux.Server(frpConn, fmuxCfg)
F
fatedier 已提交
396
				if err != nil {
397
					log.Warn("Failed to create mux connection: %v", err)
F
fatedier 已提交
398
					frpConn.Close()
399 400 401 402 403 404
					return
				}

				for {
					stream, err := session.AcceptStream()
					if err != nil {
405
						log.Debug("Accept new mux stream error: %v", err)
F
fatedier 已提交
406
						session.Close()
407 408
						return
					}
409
					go svr.handleConnection(ctx, stream)
F
fatedier 已提交
410
				}
411
			} else {
412
				svr.handleConnection(ctx, frpConn)
F
fatedier 已提交
413
			}
414
		}(ctx, c)
F
fatedier 已提交
415 416 417
	}
}

F
fatedier 已提交
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login) (err error) {
	// If client's RunId is empty, it's a new client, we just create a new controller.
	// Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one.
	if loginMsg.RunId == "" {
		loginMsg.RunId, err = util.RandId()
		if err != nil {
			return
		}
	}

	ctx := frpNet.NewContextFromConn(ctlConn)
	xl := xlog.FromContextSafe(ctx)
	xl.AppendPrefix(loginMsg.RunId)
	ctx = xlog.NewContext(ctx, xl)
	xl.Info("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
F
fatedier 已提交
433 434 435 436 437 438 439 440 441
		ctlConn.RemoteAddr().String(), loginMsg.Version, loginMsg.Hostname, loginMsg.Os, loginMsg.Arch)

	// Check client version.
	if ok, msg := version.Compat(loginMsg.Version); !ok {
		err = fmt.Errorf("%s", msg)
		return
	}

	// Check auth.
442
	if err = svr.authVerifier.VerifyLogin(loginMsg); err != nil {
F
fatedier 已提交
443 444 445
		return
	}

446
	ctl := NewControl(ctx, svr.rc, svr.pxyManager, svr.pluginManager, svr.authVerifier, ctlConn, loginMsg, svr.cfg)
F
fatedier 已提交
447
	if oldCtl := svr.ctlManager.Add(loginMsg.RunId, ctl); oldCtl != nil {
F
fatedier 已提交
448
		oldCtl.allShutdown.WaitDone()
F
fatedier 已提交
449 450 451
	}

	ctl.Start()
452 453

	// for statistics
454
	metrics.Server.NewClient()
F
fatedier 已提交
455 456 457 458

	go func() {
		// block until control closed
		ctl.WaitClosed()
F
fatedier 已提交
459
		svr.ctlManager.Del(loginMsg.RunId, ctl)
F
fatedier 已提交
460
	}()
F
fatedier 已提交
461 462 463 464
	return
}

// RegisterWorkConn register a new work connection to control and proxies need it.
465
func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn) error {
F
fatedier 已提交
466
	xl := frpNet.NewLogFromConn(workConn)
F
fatedier 已提交
467
	ctl, exist := svr.ctlManager.GetById(newMsg.RunId)
F
fatedier 已提交
468
	if !exist {
F
fatedier 已提交
469
		xl.Warn("No client control found for run id [%s]", newMsg.RunId)
470
		return fmt.Errorf("no client control found for run id [%s]", newMsg.RunId)
F
fatedier 已提交
471
	}
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
	// server plugin hook
	content := &plugin.NewWorkConnContent{
		User: plugin.UserInfo{
			User:  ctl.loginMsg.User,
			Metas: ctl.loginMsg.Metas,
			RunId: ctl.loginMsg.RunId,
		},
		NewWorkConn: *newMsg,
	}
	retContent, err := svr.pluginManager.NewWorkConn(content)
	if err == nil {
		newMsg = &retContent.NewWorkConn
		// Check auth.
		err = svr.authVerifier.VerifyNewWorkConn(newMsg)
	}
	if err != nil {
		xl.Warn("invalid NewWorkConn with run id [%s]", newMsg.RunId)
489
		msg.WriteMsg(workConn, &msg.StartWorkConn{
490
			Error: util.GenerateResponseErrorString("invalid NewWorkConn", err, ctl.serverCfg.DetailedErrorsToClient),
491
		})
492
		return fmt.Errorf("invalid NewWorkConn with run id [%s]", newMsg.RunId)
493 494
	}
	return ctl.RegisterWorkConn(workConn)
F
fatedier 已提交
495 496
}

F
fatedier 已提交
497
func (svr *Service) RegisterVisitorConn(visitorConn net.Conn, newMsg *msg.NewVisitorConn) error {
F
fatedier 已提交
498
	return svr.rc.VisitorManager.NewConn(newMsg.ProxyName, visitorConn, newMsg.Timestamp, newMsg.SignKey,
F
fatedier 已提交
499 500
		newMsg.UseEncryption, newMsg.UseCompression)
}
F
fatedier 已提交
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521

// 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}}
}