From 7655db6ce29c1eee16231199fb059b451c3eb5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Thu, 1 Sep 2022 10:09:04 +0100 Subject: [PATCH] fix(ci): move tls tests into go --- cmd/karma/script_test.go | 107 ++++++++++++++++++ cmd/karma/tests/testscript/087_listen_tls.txt | 18 +-- .../testscript/088_listen_tls_key_invalid.txt | 12 +- .../089_listen_tls_cert_invalid.txt | 12 +- .../testscript/090_listen_tls_key_missing.txt | 14 +-- .../091_listen_tls_cert_missing.txt | 14 +-- .../testscript/098_proxy_url_request.txt | 2 +- .../testscript/103_alert_history_tls.txt | 27 +---- 8 files changed, 123 insertions(+), 83 deletions(-) diff --git a/cmd/karma/script_test.go b/cmd/karma/script_test.go index 55f0e4489..8e1f784a3 100644 --- a/cmd/karma/script_test.go +++ b/cmd/karma/script_test.go @@ -2,11 +2,18 @@ package main import ( "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" "errors" "fmt" + "math/big" "net" "net/http" "os" + "path" "strconv" "strings" "testing" @@ -58,6 +65,7 @@ func TestScripts(t *testing.T) { UpdateScripts: os.Getenv("UPDATE_SNAPSHOTS") == "1", Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){ "http": httpServer, + "cert": tlsCert, }, Setup: func(env *testscript.Env) error { env.Values["mocks"] = &httpMocks{responses: map[string][]httpMock{}} @@ -186,3 +194,102 @@ func (m *httpMocks) add(name string, mock httpMock) { } m.responses[name] = append(m.responses[name], mock) } + +func tlsCert(ts *testscript.TestScript, neg bool, args []string) { + if len(args) < 2 { + ts.Fatalf("! cert command requires '$DIRNAME $NAME' args, got [%s]", strings.Join(args, " ")) + } + dirname := args[0] + name := args[1] + + ca := &x509.Certificate{ + SerialNumber: big.NewInt(2019), + Subject: pkix.Name{ + Organization: []string{"Company, INC."}, + Country: []string{"US"}, + Province: []string{""}, + Locality: []string{"San Francisco"}, + StreetAddress: []string{""}, + PostalCode: []string{""}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(10, 0, 0), + IsCA: true, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + BasicConstraintsValid: true, + } + + caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + ts.Fatalf("failed to generate CA private key: %s", err) + } + + caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey) + if err != nil { + ts.Fatalf("failed to generate CA cert: %s", err) + } + + writeCert(ts, dirname, name+"-ca.pem", &pem.Block{ + Type: "CERTIFICATE", + Bytes: caBytes, + }) + writeCert(ts, dirname, name+"-ca.key", &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey), + }) + + cert := &x509.Certificate{ + SerialNumber: big.NewInt(1658), + Subject: pkix.Name{ + Organization: []string{""}, + Country: []string{""}, + Province: []string{""}, + Locality: []string{""}, + StreetAddress: []string{""}, + PostalCode: []string{""}, + }, + IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback}, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(0, 0, 1), + SubjectKeyId: []byte{1, 2, 3, 4, 6}, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: x509.KeyUsageDigitalSignature, + } + + certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + ts.Fatalf("failed to generate cert private key: %s", err) + } + + certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey) + if err != nil { + ts.Fatalf("failed to generate cert: %s", err) + } + + writeCert(ts, dirname, name+".pem", &pem.Block{ + Type: "CERTIFICATE", + Bytes: certBytes, + }) + writeCert(ts, dirname, name+".key", &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey), + }) +} + +func writeCert(ts *testscript.TestScript, dirname, filename string, block *pem.Block) { + fullpath := path.Join(dirname, filename) + + f, err := os.Create(fullpath) + if err != nil { + ts.Fatalf("failed to write %s: %s", fullpath, err) + } + + if err = pem.Encode(f, block); err != nil { + ts.Fatalf("failed to encode %s: %s", fullpath, err) + } + + if err = f.Close(); err != nil { + ts.Fatalf("failed to close %s: %s", fullpath, err) + } +} diff --git a/cmd/karma/tests/testscript/087_listen_tls.txt b/cmd/karma/tests/testscript/087_listen_tls.txt index e2e1afad6..8dcdcc96b 100644 --- a/cmd/karma/tests/testscript/087_listen_tls.txt +++ b/cmd/karma/tests/testscript/087_listen_tls.txt @@ -1,6 +1,6 @@ # Listens on HTTPS when enabled -exec bash -x ./tls.sh +cert $WORK karma exec bash -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 . @@ -36,20 +36,12 @@ alertmanager: 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 -sha256 -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 + cert: karma.pem + key: karma.key -- test.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 +curl -s --cacert karma-ca.pem -o http1.txt --http1.1 https://127.0.0.1:8087/health +curl -s --cacert karma-ca.pem -o http2.txt --http2 https://127.0.0.1:8087/health cat karma.pid | xargs kill diff --git a/cmd/karma/tests/testscript/088_listen_tls_key_invalid.txt b/cmd/karma/tests/testscript/088_listen_tls_key_invalid.txt index 042328c1a..c25686648 100644 --- a/cmd/karma/tests/testscript/088_listen_tls_key_invalid.txt +++ b/cmd/karma/tests/testscript/088_listen_tls_key_invalid.txt @@ -1,6 +1,6 @@ # Fails on invalid TLS key -exec sh -x ./tls.sh +cert $WORK karma 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 @@ -36,13 +36,5 @@ alertmanager: timeout: 10s listen: tls: - cert: server.pem + cert: karma.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 -sha256 -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 diff --git a/cmd/karma/tests/testscript/089_listen_tls_cert_invalid.txt b/cmd/karma/tests/testscript/089_listen_tls_cert_invalid.txt index 49f75b882..562ed23c6 100644 --- a/cmd/karma/tests/testscript/089_listen_tls_cert_invalid.txt +++ b/cmd/karma/tests/testscript/089_listen_tls_cert_invalid.txt @@ -1,6 +1,6 @@ # Fails on invalid TLS cert -exec sh -x ./tls.sh +cert $WORK karma 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 @@ -37,12 +37,4 @@ alertmanager: 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 -sha256 -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 + key: karma.key diff --git a/cmd/karma/tests/testscript/090_listen_tls_key_missing.txt b/cmd/karma/tests/testscript/090_listen_tls_key_missing.txt index 123bfddb6..d6f618e38 100644 --- a/cmd/karma/tests/testscript/090_listen_tls_key_missing.txt +++ b/cmd/karma/tests/testscript/090_listen_tls_key_missing.txt @@ -1,12 +1,10 @@ # Fails on missing TLS key -exec sh -x ./tls.sh +cert $WORK karma 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" @@ -36,13 +34,5 @@ alertmanager: timeout: 10s listen: tls: - cert: server.pem + cert: karma.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 -sha256 -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 diff --git a/cmd/karma/tests/testscript/091_listen_tls_cert_missing.txt b/cmd/karma/tests/testscript/091_listen_tls_cert_missing.txt index 4abfa56cf..82ac21340 100644 --- a/cmd/karma/tests/testscript/091_listen_tls_cert_missing.txt +++ b/cmd/karma/tests/testscript/091_listen_tls_cert_missing.txt @@ -1,12 +1,10 @@ # Fails on missing TLS cert -exec sh -x ./tls.sh +cert $WORK karma 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" @@ -37,12 +35,4 @@ alertmanager: 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 -sha256 -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 + key: karma.key diff --git a/cmd/karma/tests/testscript/098_proxy_url_request.txt b/cmd/karma/tests/testscript/098_proxy_url_request.txt index a2f076220..e99059770 100644 --- a/cmd/karma/tests/testscript/098_proxy_url_request.txt +++ b/cmd/karma/tests/testscript/098_proxy_url_request.txt @@ -122,7 +122,7 @@ func main() { go func() { err := server.Serve(listener) - if err != nil { + if err != nil && err != http.ErrServerClosed { log.Printf("Serve returned error: %v", err) } }() diff --git a/cmd/karma/tests/testscript/103_alert_history_tls.txt b/cmd/karma/tests/testscript/103_alert_history_tls.txt index b9df5476d..9ac8f3f2d 100644 --- a/cmd/karma/tests/testscript/103_alert_history_tls.txt +++ b/cmd/karma/tests/testscript/103_alert_history_tls.txt @@ -1,4 +1,4 @@ -exec bash -x ./tls.sh +cert $WORK prometheus http response prometheus /api/v1/labels 200 {"status":"success","data":["alertname"]} http response prometheus /api/v1/query_range 200 {"status":"success","data":{"resultType":"matrix","result":[{"metric":{},"values":[]}]}} @@ -44,7 +44,7 @@ history: - source: '(.*)' uri: '$1' tls: - ca: ./ca.pem + ca: ./prometheus-ca.pem insecureSkipVerify: false -- query.json -- { @@ -56,21 +56,6 @@ history: "alertname": "Fake Alert" } } --- prometheus.conf -- -[req] -distinguished_name = DN -x509_extensions = SAN -[DN] -CN = 127.0.0.1 -[SAN] -basicConstraints = CA:FALSE -subjectKeyIdentifier = hash -keyUsage = digitalSignature, keyEncipherment -extendedKeyUsage = clientAuth, serverAuth -subjectAltName = @alt_names -[alt_names] -DNS.1 = localhost -IP.1 = 127.0.0.1 -- test.sh -- I=0 while [ ! -f karma.pid ] && [ $I -lt 30 ]; do sleep 1; I=$((I+1)); done @@ -79,11 +64,3 @@ sleep 5 curl -s -f -o /dev/null -XPOST -d @query.json http://127.0.0.1:8103/history.json cat karma.pid | xargs kill --- tls.sh -- -openssl ecparam -genkey -name secp256r1 | openssl ec -out ca.key -openssl req -new -x509 -sha256 -days 7 -key ca.key -out ca.pem -subj "/C=CI/ST=CI/L=CI/O=CI/CN=FakeCA" - -openssl ecparam -genkey -name secp256r1 | openssl ec -out prometheus.key -openssl req -new -sha256 -key prometheus.key -out prometheus.csr -subj "/C=CI/ST=CI/L=CI/O=CI/CN=127.0.0.1" -config prometheus.conf -extensions SAN -openssl x509 -req -sha256 -days 7 -extfile prometheus.conf -extensions SAN -in prometheus.csr -CA ca.pem -CAkey ca.key -set_serial 01 -out prometheus.pem -openssl x509 -in prometheus.pem -text