finalize tls
This commit is contained in:
1 parent
4c2371417b
commit
28987a2952
4 files changed
+61
-80
No files matched your search
@@ -0,0 +1,45 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateSelfSigned() (*tls.Certificate, error) {
|
||||||
|
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||||
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 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 nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tls.Certificate{
|
||||||
|
PrivateKey: priv,
|
||||||
|
Certificate: [][]byte{cert},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ type ConfigLogging struct {
|
|||||||
type ConfigHTTP struct {
|
type ConfigHTTP struct {
|
||||||
Host string `arg:"--http-host,env:HTTP_HOST" default:"0.0.0.0"`
|
Host string `arg:"--http-host,env:HTTP_HOST" default:"0.0.0.0"`
|
||||||
Port uint `arg:"--http-port,env:HTTP_PORT" default:"8080"`
|
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"`
|
Tls bool `arg:"--http-tls,env:HTTP_TLS" default:"true"`
|
||||||
TlsKey *string `arg:"--http-tls-key,env:HTTP_TLS_KEY"`
|
TlsKey *string `arg:"--http-tls-key,env:HTTP_TLS_KEY"`
|
||||||
TlsCert *string `arg:"--http-tls-cert,env:HTTP_TLS_CERT"`
|
TlsCert *string `arg:"--http-tls-cert,env:HTTP_TLS_CERT"`
|
||||||
@@ -73,10 +72,6 @@ func (c *ConfigHTTP) Address() string {
|
|||||||
return net.JoinHostPort(c.Host, fmt.Sprint(c.Port))
|
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() {
|
func (c *Config) MustParse() {
|
||||||
arg.MustParse(c)
|
arg.MustParse(c)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func Time[T any](runnable func() (T, error)) (time.Duration, T, error) {
|
||||||
|
t := time.Now()
|
||||||
|
res, err := runnable()
|
||||||
|
return time.Since(t), res, err
|
||||||
|
}
|
||||||
+7
-75
@@ -2,15 +2,8 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math/big"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -33,7 +26,6 @@ type HttpServer struct {
|
|||||||
http.Server
|
http.Server
|
||||||
lg *zap.Logger
|
lg *zap.Logger
|
||||||
cfg *common.ConfigHTTP
|
cfg *common.ConfigHTTP
|
||||||
rs *http.Server
|
|
||||||
Hndl chan *SignalingHandle
|
Hndl chan *SignalingHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +59,7 @@ func NewHttpServer(lg *zap.Logger, cfg *common.ConfigHTTP) *HttpServer {
|
|||||||
func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
||||||
if h.cfg.Tls {
|
if h.cfg.Tls {
|
||||||
// set the configured address
|
// set the configured address
|
||||||
h.Addr = h.cfg.AddressTls()
|
h.Addr = h.cfg.Address()
|
||||||
|
|
||||||
if h.cfg.TlsCert != nil && h.cfg.TlsKey != nil {
|
if h.cfg.TlsCert != nil && h.cfg.TlsKey != nil {
|
||||||
cert, err := tls.LoadX509KeyPair(*h.cfg.TlsCert, *h.cfg.TlsKey)
|
cert, err := tls.LoadX509KeyPair(*h.cfg.TlsCert, *h.cfg.TlsKey)
|
||||||
@@ -80,13 +72,17 @@ func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
h.lg.Info("creating self signed certificate")
|
h.lg.Info("creating self signed certificate")
|
||||||
cert, err := generateSelfSigned()
|
var cert *tls.Certificate
|
||||||
|
duration, cert, err := common.Time(func() (*tls.Certificate, error) {
|
||||||
|
return common.GenerateSelfSigned()
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
h.lg.Info("certificate created", zap.Duration("elapsed", duration))
|
||||||
|
|
||||||
h.Server.TLSConfig = &tls.Config{
|
h.Server.TLSConfig = &tls.Config{
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{*cert},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,8 +92,6 @@ func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
|||||||
h.lg.Fatal("listen failed", zap.Error(err))
|
h.lg.Fatal("listen failed", zap.Error(err))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
h.rs = runRedirect(h.cfg)
|
|
||||||
} else {
|
} else {
|
||||||
// set the configured address
|
// set the configured address
|
||||||
h.Addr = h.cfg.Address()
|
h.Addr = h.cfg.Address()
|
||||||
@@ -113,72 +107,10 @@ func (h *HttpServer) ListenAndServe(ctx context.Context) error {
|
|||||||
return nil
|
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 {
|
func (h *HttpServer) TearDown() error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
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 {
|
if err := h.Server.Shutdown(ctx); err != nil {
|
||||||
return fmt.Errorf("server forced to shutdown: %s", err)
|
return fmt.Errorf("server forced to shutdown: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user