feat(backend): add config option to listen on HTTPS

This commit is contained in:
Łukasz Mierzwa
2020-11-20 19:26:41 +00:00
committed by Łukasz Mierzwa
parent 4bc4e7f539
commit feaad60007
19 changed files with 336 additions and 8 deletions
+21 -4
View File
@@ -439,17 +439,34 @@ func serve(errorHandling pflag.ErrorHandling) error {
if err != nil {
return err
}
log.Info().Str("address", listener.Addr().String()).Msg("Starting HTTP server")
httpServer := &http.Server{
Addr: listen,
Handler: router,
}
go func() {
_ = httpServer.Serve(listener)
}()
quit := make(chan os.Signal, 1)
if config.Config.Listen.TLS.Cert != "" {
log.Info().Str("address", listener.Addr().String()).Msg("Starting HTTPS server")
go func() {
err := httpServer.ServeTLS(listener, config.Config.Listen.TLS.Cert, config.Config.Listen.TLS.Key)
if err != nil && err != http.ErrServerClosed {
log.Error().Err(err).Msg("HTTPS server startup error")
quit <- syscall.SIGTERM
}
}()
} else {
log.Info().Str("address", listener.Addr().String()).Msg("Starting HTTP server")
go func() {
err := httpServer.Serve(listener)
if err != nil && err != http.ErrServerClosed {
log.Error().Err(err).Msg("HTTP server startup error")
quit <- syscall.SIGTERM
}
}()
}
signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Info().Msg("Shutting down HTTP server")
@@ -158,6 +158,9 @@ level=info msg=" - instance"
level=info msg=" - cluster"
level=info msg="listen:"
level=info msg=" address: 127.0.0.1"
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 1234"
level=info msg=" prefix: /prefix/"
level=info msg="log:"
@@ -162,6 +162,9 @@ level=info msg=" - instance"
level=info msg=" - '@receiver'"
level=info msg="listen:"
level=info msg=" address: \"\""
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg="log:"
@@ -72,6 +72,9 @@ level=info msg=" static: []"
level=info msg=" unique: []"
level=info msg="listen:"
level=info msg=" address: \"\""
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg="log:"
+3
View File
@@ -72,6 +72,9 @@ level=info msg=" static: []"
level=info msg=" unique: []"
level=info msg="listen:"
level=info msg=" address: \"\""
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg="log:"
@@ -72,6 +72,9 @@ level=info msg=" static: []"
level=info msg=" unique: []"
level=info msg="listen:"
level=info msg=" address: \"\""
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg="log:"
@@ -74,6 +74,9 @@ level=info msg=" static: []"
level=info msg=" unique: []"
level=info msg="listen:"
level=info msg=" address: 127.0.0.1"
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8068"
level=info msg=" prefix: /"
level=info msg="log:"
@@ -82,6 +82,9 @@ level=info msg=" static: []"
level=info msg=" unique: []"
level=info msg="listen:"
level=info msg=" address: \"\""
level=info msg=" tls:"
level=info msg=" cert: \"\""
level=info msg=" key: \"\""
level=info msg=" port: 8080"
level=info msg=" prefix: /"
level=info msg="log:"
@@ -0,0 +1,57 @@
# Listens on HTTPS when enabled
exec sh -x ./tls.sh
exec sh -x ./test.sh &
karma.bin-should-work --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8087
! stdout .
wait
cmp http1.txt pong.txt
cmp http2.txt pong.txt
-- pong.txt --
Pong
-- stderr.txt --
level=info msg="Reading configuration file" path=karma.yaml
level=info msg="Version: dev"
level=info msg="Configured Alertmanager source" name=local proxy=false readonly=false uri=https://127.0.0.1:9093
level=info msg="Writing PID file" path=karma.pid
level=info msg="Initial Alertmanager collection"
level=info msg="Pulling latest alerts and silences from Alertmanager"
level=info msg="Collecting alerts and silences" alertmanager=local
level=info msg="GET request" timeout=10 uri=https://127.0.0.1:9093/metrics
level=error msg="Request failed" error="Get \"https://127.0.0.1:9093/metrics\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local uri=https://127.0.0.1:9093
level=error msg="Collection failed" error="Get \"https://127.0.0.1:9093/api/v2/status\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local
level=info msg="Collection completed"
level=info msg="Done, starting HTTP server"
level=info msg="Starting HTTPS server" address=127.0.0.1:8087
level=info msg="Shutting down HTTP server"
level=error msg="HTTPS server startup error" error="http: Server closed"
level=info msg="HTTP server shut down"
level=info msg="Removing PID file" path=karma.pid
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.pem
key: server.key
-- tls.sh --
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 7 -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=karma.example.com"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 7
-- test.sh --
#!/bin/sh
while [ ! -f karma.pid ]; do sleep 1 ; done
sleep 1
curl -s --resolve karma.example.com:8087:127.0.0.1 --cacert ca.pem -o http1.txt --http1.1 https://karma.example.com:8087/health
curl -s --resolve karma.example.com:8087:127.0.0.1 --cacert ca.pem -o http2.txt --http2 https://karma.example.com:8087/health
cat karma.pid | xargs kill
@@ -0,0 +1,45 @@
# Fails on invalid TLS key
exec sh -x ./tls.sh
karma.bin-should-work --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8088
! stdout .
cmp stderr stderr.txt
-- server.bad --
BAD KEY
-- stderr.txt --
level=info msg="Reading configuration file" path=karma.yaml
level=info msg="Version: dev"
level=info msg="Configured Alertmanager source" name=local proxy=false readonly=false uri=https://127.0.0.1:9093
level=info msg="Writing PID file" path=karma.pid
level=info msg="Initial Alertmanager collection"
level=info msg="Pulling latest alerts and silences from Alertmanager"
level=info msg="Collecting alerts and silences" alertmanager=local
level=info msg="GET request" timeout=10 uri=https://127.0.0.1:9093/metrics
level=error msg="Request failed" error="Get \"https://127.0.0.1:9093/metrics\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local uri=https://127.0.0.1:9093
level=error msg="Collection failed" error="Get \"https://127.0.0.1:9093/api/v2/status\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local
level=info msg="Collection completed"
level=info msg="Done, starting HTTP server"
level=info msg="Starting HTTPS server" address=127.0.0.1:8088
level=error msg="HTTPS server startup error" error="tls: failed to find any PEM data in key input"
level=info msg="Shutting down HTTP server"
level=info msg="HTTP server shut down"
level=info msg="Removing PID file" path=karma.pid
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.pem
key: server.bad
-- tls.sh --
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 7 -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=karma.example.com"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 7
@@ -0,0 +1,45 @@
# Fails on invalid TLS cert
exec sh -x ./tls.sh
karma.bin-should-work --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8089
! stdout .
cmp stderr stderr.txt
-- server.bad --
BAD CERT
-- stderr.txt --
level=info msg="Reading configuration file" path=karma.yaml
level=info msg="Version: dev"
level=info msg="Configured Alertmanager source" name=local proxy=false readonly=false uri=https://127.0.0.1:9093
level=info msg="Writing PID file" path=karma.pid
level=info msg="Initial Alertmanager collection"
level=info msg="Pulling latest alerts and silences from Alertmanager"
level=info msg="Collecting alerts and silences" alertmanager=local
level=info msg="GET request" timeout=10 uri=https://127.0.0.1:9093/metrics
level=error msg="Request failed" error="Get \"https://127.0.0.1:9093/metrics\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local uri=https://127.0.0.1:9093
level=error msg="Collection failed" error="Get \"https://127.0.0.1:9093/api/v2/status\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local
level=info msg="Collection completed"
level=info msg="Done, starting HTTP server"
level=info msg="Starting HTTPS server" address=127.0.0.1:8089
level=error msg="HTTPS server startup error" error="tls: failed to find any PEM data in certificate input"
level=info msg="Shutting down HTTP server"
level=info msg="HTTP server shut down"
level=info msg="Removing PID file" path=karma.pid
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.bad
key: server.key
-- tls.sh --
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 7 -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=karma.example.com"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 7
@@ -0,0 +1,45 @@
# Fails on missing TLS key
exec sh -x ./tls.sh
karma.bin-should-work --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8090
! stdout .
cmp stderr stderr.txt
-- server.bad --
BAD CERT
-- stderr.txt --
level=info msg="Reading configuration file" path=karma.yaml
level=info msg="Version: dev"
level=info msg="Configured Alertmanager source" name=local proxy=false readonly=false uri=https://127.0.0.1:9093
level=info msg="Writing PID file" path=karma.pid
level=info msg="Initial Alertmanager collection"
level=info msg="Pulling latest alerts and silences from Alertmanager"
level=info msg="Collecting alerts and silences" alertmanager=local
level=info msg="GET request" timeout=10 uri=https://127.0.0.1:9093/metrics
level=error msg="Request failed" error="Get \"https://127.0.0.1:9093/metrics\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local uri=https://127.0.0.1:9093
level=error msg="Collection failed" error="Get \"https://127.0.0.1:9093/api/v2/status\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local
level=info msg="Collection completed"
level=info msg="Done, starting HTTP server"
level=info msg="Starting HTTPS server" address=127.0.0.1:8090
level=error msg="HTTPS server startup error" error="open server.nofound: no such file or directory"
level=info msg="Shutting down HTTP server"
level=info msg="HTTP server shut down"
level=info msg="Removing PID file" path=karma.pid
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.pem
key: server.nofound
-- tls.sh --
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 7 -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=karma.example.com"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 7
@@ -0,0 +1,45 @@
# Fails on missing TLS cert
exec sh -x ./tls.sh
karma.bin-should-work --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8091
! stdout .
cmp stderr stderr.txt
-- server.bad --
BAD CERT
-- stderr.txt --
level=info msg="Reading configuration file" path=karma.yaml
level=info msg="Version: dev"
level=info msg="Configured Alertmanager source" name=local proxy=false readonly=false uri=https://127.0.0.1:9093
level=info msg="Writing PID file" path=karma.pid
level=info msg="Initial Alertmanager collection"
level=info msg="Pulling latest alerts and silences from Alertmanager"
level=info msg="Collecting alerts and silences" alertmanager=local
level=info msg="GET request" timeout=10 uri=https://127.0.0.1:9093/metrics
level=error msg="Request failed" error="Get \"https://127.0.0.1:9093/metrics\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local uri=https://127.0.0.1:9093
level=error msg="Collection failed" error="Get \"https://127.0.0.1:9093/api/v2/status\": dial tcp 127.0.0.1:9093: connect: connection refused" alertmanager=local
level=info msg="Collection completed"
level=info msg="Done, starting HTTP server"
level=info msg="Starting HTTPS server" address=127.0.0.1:8091
level=error msg="HTTPS server startup error" error="open server.notfound: no such file or directory"
level=info msg="Shutting down HTTP server"
level=info msg="HTTP server shut down"
level=info msg="Removing PID file" path=karma.pid
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.notfound
key: server.key
-- tls.sh --
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -days 7 -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=karma.example.com"
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -days 7
@@ -0,0 +1,18 @@
# Fails on empty TLS key
karma.bin-should-fail --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8092
! stdout .
cmp stderr stderr.txt
-- stderr.txt --
level=error msg="Execution failed" error="listen.tls.key must be set when listen.tls.cert is set"
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
cert: server.pem
@@ -0,0 +1,18 @@
# Fails on empty TLS cert
karma.bin-should-fail --pid-file=karma.pid --config.file=karma.yaml --listen.address=127.0.0.1 --listen.port=8092
! stdout .
cmp stderr stderr.txt
-- stderr.txt --
level=error msg="Execution failed" error="listen.tls.cert must be set when listen.tls.key is set"
-- karma.yaml --
alertmanager:
servers:
- name: local
uri: https://127.0.0.1:9093
timeout: 10s
listen:
tls:
key: server.key
+2 -2
View File
@@ -38,7 +38,7 @@ func badRequestJSON(w http.ResponseWriter, error string) {
}
func pong(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("Pong"))
_, _ = w.Write([]byte("Pong\n"))
}
func compressResponse(data []byte) ([]byte, error) {
@@ -82,7 +82,7 @@ func decompressCachedResponse(data []byte) ([]byte, error) {
func pushPath(w http.ResponseWriter, path string) {
if pusher, ok := w.(http.Pusher); ok {
if err := pusher.Push(path, nil); err != nil {
log.Warn().Str("path", path).Msg("Failed to push server path via HTTP/2")
log.Debug().Err(err).Str("path", path).Msg("Failed to push server path via HTTP/2")
}
}
}
+10
View File
@@ -112,6 +112,8 @@ func SetupFlags(f *pflag.FlagSet) {
f.String("listen.address", "", "IP/Hostname to listen on")
f.Int("listen.port", 8080, "HTTP port to listen on")
f.String("listen.prefix", "/", "URL prefix")
f.String("listen.tls.cert", "", "TLS certificate path (enables HTTPS)")
f.String("listen.tls.key", "", "TLS key path (enables HTTPS)")
f.String("sentry.public", "", "Sentry DSN for Go exceptions")
f.String("sentry.private", "", "Sentry DSN for JavaScript exceptions")
@@ -349,6 +351,14 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
return "", fmt.Errorf("listen.prefix must start with '/', got %q", config.Listen.Prefix)
}
if config.Listen.TLS.Cert != "" && config.Listen.TLS.Key == "" {
return "", fmt.Errorf("listen.tls.key must be set when listen.tls.cert is set")
}
if config.Listen.TLS.Key != "" && config.Listen.TLS.Cert == "" {
return "", fmt.Errorf("listen.tls.cert must be set when listen.tls.key is set")
}
// accept single Alertmanager server from flag/env if nothing is set yet
if len(config.Alertmanager.Servers) == 0 && config.Alertmanager.URI != "" {
config.Alertmanager.Servers = []AlertmanagerConfig{
+3
View File
@@ -97,6 +97,9 @@ labels:
- gg
listen:
address: 0.0.0.0
tls:
cert: ""
key: ""
port: 80
prefix: /
log:
+6 -2
View File
@@ -128,8 +128,12 @@ type configSchema struct {
}
Listen struct {
Address string
Port int
Prefix string
TLS struct {
Cert string
Key string
}
Port int
Prefix string
}
Log struct {
Config bool