mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
chore: run tests with tls using self-signed certificate
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
||||
.git
|
||||
.idea
|
||||
tests
|
||||
tests
|
||||
!tests/config/ca.pem
|
||||
@@ -0,0 +1,140 @@
|
||||
// partially taken from https://github.com/FiloSottile/mkcert
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
path := "./tests/config"
|
||||
caCert, caKey := newCA(path)
|
||||
makeCert(path, caCert, caKey, []string{"ionscale"})
|
||||
}
|
||||
|
||||
func generateKey(rootCA bool) (crypto.PrivateKey, error) {
|
||||
if rootCA {
|
||||
return rsa.GenerateKey(rand.Reader, 3072)
|
||||
}
|
||||
return rsa.GenerateKey(rand.Reader, 2048)
|
||||
}
|
||||
|
||||
func makeCert(path string, caCert *x509.Certificate, caKey any, hosts []string) {
|
||||
priv, err := generateKey(false)
|
||||
fatalIfErr(err)
|
||||
pub := priv.(crypto.Signer).Public()
|
||||
|
||||
expiration := time.Now().AddDate(2, 3, 0)
|
||||
|
||||
tpl := &x509.Certificate{
|
||||
SerialNumber: randomSerialNumber(),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"ionscale tests cert"},
|
||||
OrganizationalUnit: []string{"ionscale"},
|
||||
},
|
||||
|
||||
NotBefore: time.Now(), NotAfter: expiration,
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
tpl.IPAddresses = append(tpl.IPAddresses, ip)
|
||||
} else if email, err := mail.ParseAddress(h); err == nil && email.Address == h {
|
||||
tpl.EmailAddresses = append(tpl.EmailAddresses, h)
|
||||
} else if uriName, err := url.Parse(h); err == nil && uriName.Scheme != "" && uriName.Host != "" {
|
||||
tpl.URIs = append(tpl.URIs, uriName)
|
||||
} else {
|
||||
tpl.DNSNames = append(tpl.DNSNames, h)
|
||||
}
|
||||
}
|
||||
|
||||
if len(tpl.IPAddresses) > 0 || len(tpl.DNSNames) > 0 || len(tpl.URIs) > 0 {
|
||||
tpl.ExtKeyUsage = append(tpl.ExtKeyUsage, x509.ExtKeyUsageServerAuth)
|
||||
}
|
||||
if len(tpl.EmailAddresses) > 0 {
|
||||
tpl.ExtKeyUsage = append(tpl.ExtKeyUsage, x509.ExtKeyUsageEmailProtection)
|
||||
}
|
||||
|
||||
cert, err := x509.CreateCertificate(rand.Reader, tpl, caCert, pub, caKey)
|
||||
fatalIfErr(err)
|
||||
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||||
privDER, err := x509.MarshalPKCS8PrivateKey(priv)
|
||||
fatalIfErr(err)
|
||||
privPEM := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER})
|
||||
|
||||
fatalIfErr(os.WriteFile(filepath.Join(path, "ionscale.pem"), certPEM, 0644))
|
||||
fatalIfErr(os.WriteFile(filepath.Join(path, "ionscale.key"), privPEM, 0600))
|
||||
}
|
||||
|
||||
func newCA(path string) (*x509.Certificate, any) {
|
||||
priv, err := generateKey(true)
|
||||
fatalIfErr(err)
|
||||
pub := priv.(crypto.Signer).Public()
|
||||
|
||||
spkiASN1, err := x509.MarshalPKIXPublicKey(pub)
|
||||
fatalIfErr(err)
|
||||
|
||||
var spki struct {
|
||||
Algorithm pkix.AlgorithmIdentifier
|
||||
SubjectPublicKey asn1.BitString
|
||||
}
|
||||
_, err = asn1.Unmarshal(spkiASN1, &spki)
|
||||
fatalIfErr(err)
|
||||
|
||||
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
|
||||
|
||||
tpl := &x509.Certificate{
|
||||
SerialNumber: randomSerialNumber(),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"ionscale tests CA"},
|
||||
OrganizationalUnit: []string{"ionscale"},
|
||||
CommonName: "ionscale",
|
||||
},
|
||||
SubjectKeyId: skid[:],
|
||||
|
||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
||||
NotBefore: time.Now(),
|
||||
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
MaxPathLenZero: true,
|
||||
}
|
||||
|
||||
cert, err := x509.CreateCertificate(rand.Reader, tpl, tpl, pub, priv)
|
||||
fatalIfErr(err)
|
||||
fatalIfErr(os.WriteFile(filepath.Join(path, "ca.pem"), pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert}), 0644))
|
||||
|
||||
return tpl, priv
|
||||
}
|
||||
|
||||
func randomSerialNumber() *big.Int {
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
fatalIfErr(err)
|
||||
return serialNumber
|
||||
}
|
||||
|
||||
func fatalIfErr(err error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEVDCCArygAwIBAgIRAMIAYisvcyOuv3qmGjMmJqAwDQYJKoZIhvcNAQELBQAw
|
||||
QjEaMBgGA1UEChMRaW9uc2NhbGUgdGVzdHMgQ0ExETAPBgNVBAsTCGlvbnNjYWxl
|
||||
MREwDwYDVQQDEwhpb25zY2FsZTAeFw0yNDAyMjgxMDU1MjJaFw0zNDAyMjgxMDU1
|
||||
MjJaMEIxGjAYBgNVBAoTEWlvbnNjYWxlIHRlc3RzIENBMREwDwYDVQQLEwhpb25z
|
||||
Y2FsZTERMA8GA1UEAxMIaW9uc2NhbGUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
|
||||
ggGKAoIBgQDE2OSk75B3+2t/A/YxnCg0Ppz4Gzbw2oEZ2nw6bjDuIzjCOg+/CwoM
|
||||
prFQcgEBmACKAnQ6gBvXhxVFQ4ROhqWlmGtQ7LzNG/ByKGI7h1hHz4jMJTDmCWH1
|
||||
rfvIRvApUer+Pmp4+39/++WPhkdy4UWu1puVOWdaOIbPigzd5hpqihyWy5FdEKyA
|
||||
d0V5ElnTNjUHOjJ2MM9f33VxGe3U21u785w4jXndLgG5IxMYfpeMZ0HtOu5JTrsB
|
||||
ec8taLqM3SxClpOFOJWDgieb3eacpl5GARh+a5/lVEJtM1CJE4CEPwghjGtjow4E
|
||||
7nze5pckPEetHtWEax9hz/dC7J/mcMa1MFgpKcxlaHotT0I9goCEdvEuHI0r0Nt5
|
||||
TRfGjRTV2LGbHBnOY4Pn6N6OlfmesG4oTHErCkS9X1CZrB+Nxxywtvy1M2hEtbLY
|
||||
bZMnWRhEoH8E9plWVS/HmyMza1rq4MEBv1BQhywoBChy+W+hqY1CQcdSgPeRj20F
|
||||
JR9LvmD3W98CAwEAAaNFMEMwDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYB
|
||||
Af8CAQAwHQYDVR0OBBYEFLNqb6/tfxMEdf8F13/mOausIT9hMA0GCSqGSIb3DQEB
|
||||
CwUAA4IBgQCH0fc9cCYV5G7Oy0QVY5L0iYYz4aWXy1dsHxPtSvzbai0ZvNGupesp
|
||||
fpsAb426mGp9vEJ+xQYnnTBhmvPJRZAbKbD2PV2vh/SpbD86gJS2azYneLSM0QXe
|
||||
jgKb0aK/OSQYA5wzp/An1Yggg8SvT7SxS+fD4D7uD1UXPSqPjSO4IHT+8GPnm+rg
|
||||
P3uierAyO5bAdE831yswTj33E4gm9HVKLqDW8YdIw9xI48T0ylj5F2DEQkSZWhFA
|
||||
BqLN58e3zfo+3uh8KeVikd/k1KTQgrJeknDy12NMY1SzblBCEO8jF8LdraHn0RMy
|
||||
QlJcRG315JNM0OIEbc22LeTUmeyJT7qrkERmoK1A7iRTQVpjJe4ZdocUtjKc03Pa
|
||||
sAPs2xRXr58g9fVsN1ZevKSfvAvZWbXECdKRnw6z/LeqnjEpskbtcAoDoPV5cQ3L
|
||||
1r9WpZYPq3D0Y9weX/XI0cGUnjIXqhY/mcBy/KwlVOfeen6eV0N6KYwDdd19zn8D
|
||||
PRxxinJCKkg=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,9 +1,11 @@
|
||||
web_listen_addr: ":80"
|
||||
web_public_addr: "http://ionscale:80"
|
||||
web_listen_addr: ":443"
|
||||
web_public_addr: "ionscale:443"
|
||||
|
||||
tls:
|
||||
disable: true
|
||||
disable: false
|
||||
force_https: false
|
||||
key_file: /etc/ionscale/ionscale.key
|
||||
cert_file: /etc/ionscale/ionscale.pem
|
||||
|
||||
keys:
|
||||
system_admin_key: "804ecd57365342254ce6647da5c249e85c10a0e51e74856bfdf292a2136b4249"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDOcaJGhEiAO/Tu
|
||||
usxtQWbuxIqotV7bDdyQRBlLhPb2UORo6U+KNNP26xPWv8eSg4P1hYroyRGPGRtQ
|
||||
e6if49cYTRxh26lzO/umLfjFbiY4nyVpXVtOEwpz9A6okRgno7k/TVw4cCriXnIg
|
||||
bqqwhK+FBGWVT/yTxVYE8OXJ5oIzD8XJ9ZVekSCNr/Pn5HmklViyMuGdH49yEIRt
|
||||
LOPLW3dU5Rt8vPyWec1w/KJQyScBUMS/yk1r1Tc/FT90RpHqiJRcVIZQG1RZEOg0
|
||||
+rgoaEW8XsoLIPUHqBqkAuM2pPvAtTzPwKjA6ktel+FdRRwNCe5NEy95BBBBDyF0
|
||||
QsqhGRV5AgMBAAECggEAPjXGBeP1CReIPqxxz/amcwstEZveIrqxnZO336cI2L8V
|
||||
pXuxKV+0BDNgvhT6qe8Rw9njOzTkIrAZKA6riMsa1UrfY6nTDVOlCLXPwobn46Yp
|
||||
mu+0BPn962U/SZK3qbJPr4C7apJ6ic6WK6nNq/XAAqCJkA4TeeA8hK6nQElDMOlk
|
||||
JrSbpRpqUs9H+LYGUPku+Ti33UMcz/DWtHM2XpaXM7MWkkNQfu2Z89lQbeGoLLVP
|
||||
FA90ufwh9o6z2kTkscDuCT+iYQvf5W4Yu3MYugdHt9am7JbDWx1FGJf0vosg7Ckb
|
||||
A5ccEK5791bjn+41oTUKcjJnRfDenFUyxs2JMaV/RQKBgQDbRk2shTk00DRAeQhl
|
||||
sEzv7kyjKVEdo52Xd4Z0MKwcTwBGuEF91fvC1saSxFii5MVu8uFnCzZby63yxbqp
|
||||
PKyncGSI8uHSDNN2nKlcrWa8ecFPWloU2qNFka7Pj8tcAt7fXN/x0BOeyPl2ZgKI
|
||||
JjGJ5zEY1ZRjUVajaFPCLb9wPwKBgQDxBTHx0qq4j4J7tOJWrFVfY1GFoXYXBzDs
|
||||
mxgLEXm7Tln7/O+1bOUOsViaSR+JlwkMzYMYAX0+5Dwq2X7D5UeICzHboF44VCxb
|
||||
WA0RUcI3fXX/fXYvB4kgcDq697MyUd7uXMz9aJtL8y9x3UWkg7YBtcLa8Nj22NS/
|
||||
5aNOGMIMRwKBgF4SJzigXw59VC1kv2mA3UEB5vcIvrgMfYuBx7kJOI1chy3P1qj5
|
||||
qGzKX56Phcc8hkc3A+SFNuji1NmWYqJAWYHsAfWO3bqTrhTw2OfdrHmncntss8DG
|
||||
m8041tpNQl1TDfKdkaXYMtKoPf3BfcyTNiWHfdS9rE9/kb/A/k4L+llZAoGAUDV8
|
||||
Y4/KRNVthSGzWUjMuIvi62fKVuuLupH6tGRCcLUoeRW56FSu/e7DH8VJ+44J8vrJ
|
||||
r8l/Ftj5tQDgkOzSm1Gua/q4oGJSyKtK3gKpcbIM/NOR6yDE38i5otMgDZT1bbnw
|
||||
djzDwcjSd0A+FvvGLFeC2z3f1nZehuYzLKBMo60CgYAPjANh0rVnCbbnsQYwLJa7
|
||||
83vatZWtb4Qy1VJcsGT6TFqf3gUTKel8KttM2RN0rs9nZ/Slso9q778Fv16aTnlI
|
||||
48P8x8Qw+Zen7042NvrsjnXcOi4sj0b2SLWvOBDBO7eY7GXSqa7O0PpPUSD7vTLu
|
||||
EDO0H/OF6MRC8YSaz8WrkQ==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID2jCCAkKgAwIBAgIQSH/qIg/vOs/ZPoTlMlg2GDANBgkqhkiG9w0BAQsFADBC
|
||||
MRowGAYDVQQKExFpb25zY2FsZSB0ZXN0cyBDQTERMA8GA1UECxMIaW9uc2NhbGUx
|
||||
ETAPBgNVBAMTCGlvbnNjYWxlMB4XDTI0MDIyODEwNTUyMloXDTI2MDUyODA5NTUy
|
||||
MlowMTEcMBoGA1UEChMTaW9uc2NhbGUgdGVzdHMgY2VydDERMA8GA1UECxMIaW9u
|
||||
c2NhbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOcaJGhEiAO/Tu
|
||||
usxtQWbuxIqotV7bDdyQRBlLhPb2UORo6U+KNNP26xPWv8eSg4P1hYroyRGPGRtQ
|
||||
e6if49cYTRxh26lzO/umLfjFbiY4nyVpXVtOEwpz9A6okRgno7k/TVw4cCriXnIg
|
||||
bqqwhK+FBGWVT/yTxVYE8OXJ5oIzD8XJ9ZVekSCNr/Pn5HmklViyMuGdH49yEIRt
|
||||
LOPLW3dU5Rt8vPyWec1w/KJQyScBUMS/yk1r1Tc/FT90RpHqiJRcVIZQG1RZEOg0
|
||||
+rgoaEW8XsoLIPUHqBqkAuM2pPvAtTzPwKjA6ktel+FdRRwNCe5NEy95BBBBDyF0
|
||||
QsqhGRV5AgMBAAGjXTBbMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEF
|
||||
BQcDATAfBgNVHSMEGDAWgBSzam+v7X8TBHX/Bdd/5jmrrCE/YTATBgNVHREEDDAK
|
||||
gghpb25zY2FsZTANBgkqhkiG9w0BAQsFAAOCAYEALUO2i7zsClFSTdBzMEsPupAd
|
||||
TYMxFG0ms8jBma9VixQycudiLS5ICgoGErXtYqsfHOOi3OxwZ8SUVF3JnqaWStFD
|
||||
Hi3ckdjBprBJEVXaZUGSeaKJHYIuBrFZBf5uhtd7o9qC3uPYLp8yzdDM/JsyRCl9
|
||||
V7NUq69fKkYi1vokHwL0xTU+hbTygVAsok1j4E2dBmtLpRsfokjAExdx5QykIlh2
|
||||
mAf2owD1e2JY9bW1zHZpgkfapV6bv95jrKSerG0PM/fUpZ3/QxjB0OenQXHz2dcK
|
||||
hIS+lWj+Sns6m5iyTsLVQyw4giLTGLDPAztWotA+zaHUcS6iR9nrChZ5J4tklRD4
|
||||
+OAmL+iiR4z0aIED/CLRiw27W/m8+K5XfisTfNk6IhgsE/cILAhxnHJy6asa/0pT
|
||||
KanbA1ilcr3nAYuETW39f2NIrjvm8ELvrOrzC5LB75FxoJyp799QO939XqSKwoxL
|
||||
T4JDjOOprtH1cPwag5MJF6NZj0fb2ej77RR3R5cI
|
||||
-----END CERTIFICATE-----
|
||||
@@ -4,6 +4,8 @@ FROM tailscale/tailscale:${TAILSCALE_VERSION} as src
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk update && apk add ca-certificates openssh curl && rm -rf /var/cache/apk/*
|
||||
COPY ./tests/config/ca.pem /usr/local/share/ca-certificates/
|
||||
RUN update-ca-certificates
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=src /usr/local/bin/tailscale .
|
||||
|
||||
+12
-8
@@ -169,7 +169,7 @@ func (s *Scenario) NewTailscaleNode(opts ...TailscaleNodeOpt) *tsn.TailscaleNode
|
||||
|
||||
s.resources = append(s.resources, resource)
|
||||
|
||||
return tsn.New(s.t, config.Hostname, "http://ionscale", resource, s.pool.Retry)
|
||||
return tsn.New(s.t, config.Hostname, "https://ionscale", resource, s.pool.Retry)
|
||||
}
|
||||
|
||||
func Run(t *testing.T, f func(s *Scenario)) {
|
||||
@@ -247,25 +247,28 @@ func Run(t *testing.T, f func(s *Scenario)) {
|
||||
fmt.Sprintf("%s/config:/etc/ionscale", currentPath),
|
||||
},
|
||||
Networks: []*dockertest.Network{s.network},
|
||||
ExposedPorts: []string{"80"},
|
||||
ExposedPorts: []string{"443"},
|
||||
Cmd: []string{"server", "--config", "/etc/ionscale/config.yaml"},
|
||||
}
|
||||
|
||||
s.ionscale, err = pool.RunWithOptions(ionscale, restartPolicy)
|
||||
require.NoError(s.t, err)
|
||||
|
||||
port := s.ionscale.GetPort("80/tcp")
|
||||
port := s.ionscale.GetPort("443/tcp")
|
||||
|
||||
err = pool.Retry(httpCheck(port, "/key"))
|
||||
require.NoError(s.t, err)
|
||||
|
||||
addr := fmt.Sprintf("http://localhost:%s", port)
|
||||
addr := fmt.Sprintf("https://localhost:%s", port)
|
||||
auth, err := ionscaleclt.LoadClientAuth(addr, "804ecd57365342254ce6647da5c249e85c10a0e51e74856bfdf292a2136b4249")
|
||||
require.NoError(s.t, err)
|
||||
|
||||
s.ionscaleClient, err = ionscaleclt.NewClient(auth, addr, true)
|
||||
require.NoError(s.t, err)
|
||||
|
||||
err = pool.Retry(func() error {
|
||||
_, err := s.ionscaleClient.GetVersion(context.Background(), connect.NewRequest(&api.GetVersionRequest{}))
|
||||
return err
|
||||
})
|
||||
require.NoError(s.t, err)
|
||||
|
||||
f(s)
|
||||
}
|
||||
|
||||
@@ -313,7 +316,8 @@ func prepareDockerPoolAndImages() {
|
||||
pool, _ = dockertest.NewPool("")
|
||||
|
||||
buildOpts := &dockertest.BuildOptions{
|
||||
ContextDir: "./docker/tailscale",
|
||||
ContextDir: "../",
|
||||
Dockerfile: "tests/docker/tailscale/Dockerfile",
|
||||
BuildArgs: []docker.BuildArg{
|
||||
{
|
||||
Name: "TAILSCALE_VERSION",
|
||||
|
||||
Reference in New Issue
Block a user