add tls
This commit is contained in:
@@ -25,6 +25,9 @@ jobs:
|
||||
node-version: 18
|
||||
cache-dependency-path: static
|
||||
cache: npm
|
||||
- run: |
|
||||
apt-get update
|
||||
apt-get install --yes --no-install-recommends make
|
||||
- run: make build-static
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -26,14 +26,17 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
http := server.NewHttpServer(lg.With(zap.String("context", "server")), &cfg)
|
||||
http := server.NewHttpServer(lg.With(zap.String("context", "server")), &cfg.Http)
|
||||
|
||||
err = webrtc.NewWebrtcHandler(ctx, lg.With(zap.String("context", "webrtc")), cfg.Stream(), http.Hndl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
http.ListenAndServe(ctx, cfg.Http.Address())
|
||||
err = http.ListenAndServe(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Listen for the interrupt signal.
|
||||
<-ctx.Done()
|
||||
|
||||
@@ -28,6 +28,10 @@ type ConfigLogging struct {
|
||||
type ConfigHTTP struct {
|
||||
Host string `arg:"--http-host,env:HTTP_HOST" default:"0.0.0.0"`
|
||||
Port uint `arg:"--http-port,env:HTTP_PORT" default:"8080"`
|
||||
PortTls uint `arg:"--http-port,env:HTTP_PORT" default:"8443"`
|
||||
Tls bool `arg:"--http-tls,env:HTTP_TLS" default:"true"`
|
||||
TlsKey *string `arg:"--http-tls-key,env:HTTP_TLS_KEY"`
|
||||
TlsCert *string `arg:"--http-tls-cert,env:HTTP_TLS_CERT"`
|
||||
PathGetLiveness string `arg:"env:HTTP_PATH_LIVENESS" default:"/healthz"`
|
||||
PathGetReadiness string `arg:"env:HTTP_PATH_READINESS" default:"/readyz"`
|
||||
StaticPath *string `arg:"--http-static,env:HTTP_STATIC"`
|
||||
@@ -69,6 +73,10 @@ func (c *ConfigHTTP) Address() string {
|
||||
return net.JoinHostPort(c.Host, fmt.Sprint(c.Port))
|
||||
}
|
||||
|
||||
func (c *ConfigHTTP) AddressTls() string {
|
||||
return net.JoinHostPort(c.Host, fmt.Sprint(c.PortTls))
|
||||
}
|
||||
|
||||
func (c *Config) MustParse() {
|
||||
arg.MustParse(c)
|
||||
}
|
||||
|
||||
+117
-9
@@ -2,7 +2,15 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -24,6 +32,8 @@ type SignalingHandle struct {
|
||||
type HttpServer struct {
|
||||
http.Server
|
||||
lg *zap.Logger
|
||||
cfg *common.ConfigHTTP
|
||||
rs *http.Server
|
||||
Hndl chan *SignalingHandle
|
||||
}
|
||||
|
||||
@@ -35,9 +45,10 @@ func NewSignalingHandle(id string) SignalingHandle {
|
||||
}
|
||||
}
|
||||
|
||||
func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
|
||||
func NewHttpServer(lg *zap.Logger, cfg *common.ConfigHTTP) *HttpServer {
|
||||
h := HttpServer{
|
||||
Hndl: make(chan *SignalingHandle, 10),
|
||||
cfg: cfg,
|
||||
lg: lg,
|
||||
}
|
||||
|
||||
@@ -45,7 +56,7 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
|
||||
engine.GET("/signaling/:id", h.signalingHandler)
|
||||
|
||||
// static handler
|
||||
static.SetupHandler(engine, cfg.Http)
|
||||
static.SetupHandler(engine, cfg)
|
||||
|
||||
// set out handler
|
||||
h.Handler = engine
|
||||
@@ -53,24 +64,121 @@ func NewHttpServer(lg *zap.Logger, cfg *common.Config) *HttpServer {
|
||||
return &h
|
||||
}
|
||||
|
||||
func (h *HttpServer) ListenAndServe(ctx context.Context, addr string) {
|
||||
go func() {
|
||||
|
||||
func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
||||
if h.cfg.Tls {
|
||||
// set the configured address
|
||||
h.Addr = addr
|
||||
h.Addr = h.cfg.AddressTls()
|
||||
|
||||
// and listen
|
||||
if err := h.Server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
h.lg.Fatal("listen failed", zap.Error(err))
|
||||
if h.cfg.TlsCert != nil && h.cfg.TlsKey != nil {
|
||||
cert, err := tls.LoadX509KeyPair(*h.cfg.TlsCert, *h.cfg.TlsKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.Server.TLSConfig = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
} else {
|
||||
h.lg.Info("creating self signed certificate")
|
||||
cert, err := generateSelfSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.Server.TLSConfig = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
// and listen
|
||||
if err := h.Server.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
|
||||
h.lg.Fatal("listen failed", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
|
||||
h.rs = runRedirect(h.cfg)
|
||||
} else {
|
||||
// set the configured address
|
||||
h.Addr = h.cfg.Address()
|
||||
|
||||
go func() {
|
||||
// and listen
|
||||
if err := h.Server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
h.lg.Fatal("listen failed", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runRedirect(cfg *common.ConfigHTTP) *http.Server {
|
||||
engine := gin.Default()
|
||||
|
||||
engine.NoRoute(func(c *gin.Context) {
|
||||
u := c.Request.URL
|
||||
|
||||
host, _, _ := net.SplitHostPort(c.Request.Host)
|
||||
u.Host = net.JoinHostPort(host, fmt.Sprint(cfg.PortTls))
|
||||
u.Scheme = "https"
|
||||
|
||||
c.Redirect(302, u.String())
|
||||
})
|
||||
|
||||
go func() {
|
||||
engine.Run(net.JoinHostPort(cfg.Host, fmt.Sprint(cfg.Port)))
|
||||
}()
|
||||
|
||||
return &http.Server{
|
||||
Addr: cfg.Address(),
|
||||
Handler: engine,
|
||||
}
|
||||
}
|
||||
|
||||
func generateSelfSigned() (tls.Certificate, error) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, fmt.Errorf("failed to generate serial number: %v", err)
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{Organization: []string{"PHI"}},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 180),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
|
||||
return tls.Certificate{
|
||||
PrivateKey: priv,
|
||||
Certificate: [][]byte{cert},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *HttpServer) TearDown() error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if h.rs != nil {
|
||||
if err := h.rs.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("redirect server forced to shutdown: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.Server.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("server forced to shutdown: %s", err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ func (s staticDiskSource) Open(p string) (common.StaticSourceFile, error) {
|
||||
return &staticSourceFile{t}, nil
|
||||
}
|
||||
|
||||
func SetupHandler(e *gin.Engine, cfg common.ConfigHTTP) {
|
||||
func SetupHandler(e *gin.Engine, cfg *common.ConfigHTTP) {
|
||||
if cfg.StaticPath != nil {
|
||||
handler := common.NewStaticHandler(staticDiskSource{*cfg.StaticPath}, "index.html")
|
||||
e.NoRoute(func(c *gin.Context) {
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ func (s staticSource) Open(p string) (common.StaticSourceFile, error) {
|
||||
return &staticSourceFile{t}, nil
|
||||
}
|
||||
|
||||
func SetupHandler(e *gin.Engine, _ common.ConfigHTTP) {
|
||||
func SetupHandler(e *gin.Engine, _ *common.ConfigHTTP) {
|
||||
handler := common.NewStaticHandler(staticSource{"dist"}, "index.html")
|
||||
e.NoRoute(func(c *gin.Context) {
|
||||
encoding := c.Request.Header.Get("Accept-Encoding")
|
||||
|
||||
Reference in New Issue
Block a user