Skip to content

Commit

Permalink
Expand surface of hsic for better TLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
juanfont committed Apr 24, 2023
1 parent bb07aec commit 549f5a1
Showing 1 changed file with 46 additions and 6 deletions.
52 changes: 46 additions & 6 deletions integration/hsic/hsic.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"math/big"
"net"
"net/http"
"net/url"
"time"

"github.com/davecgh/go-spew/spew"
Expand All @@ -23,6 +24,7 @@ import (
"github.com/juanfont/headscale/integration/dockertestutil"
"github.com/juanfont/headscale/integration/integrationutil"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)

const (
Expand Down Expand Up @@ -52,6 +54,8 @@ type HeadscaleInContainer struct {

// optional config
port int
extraPorts []string
hostPortBindings map[string][]string
aclPolicy *headscale.ACLPolicy
env map[string]string
tlsCert []byte
Expand All @@ -77,7 +81,7 @@ func WithACLPolicy(acl *headscale.ACLPolicy) Option {
// WithTLS creates certificates and enables HTTPS.
func WithTLS() Option {
return func(hsic *HeadscaleInContainer) {
cert, key, err := createCertificate()
cert, key, err := createCertificate(hsic.hostname)
if err != nil {
log.Fatalf("failed to create certificates for headscale test: %s", err)
}
Expand Down Expand Up @@ -108,6 +112,19 @@ func WithPort(port int) Option {
}
}

// WithExtraPorts exposes additional ports on the container (e.g. 3478/udp for STUN)
func WithExtraPorts(ports []string) Option {
return func(hsic *HeadscaleInContainer) {
hsic.extraPorts = ports
}
}

func WithHostPortBindings(bindings map[string][]string) Option {
return func(hsic *HeadscaleInContainer) {
hsic.hostPortBindings = bindings
}
}

// WithTestName sets a name for the test, this will be reflected
// in the Docker container name.
func WithTestName(testName string) Option {
Expand Down Expand Up @@ -173,6 +190,16 @@ func New(

portProto := fmt.Sprintf("%d/tcp", hsic.port)

serverUrl, err := url.Parse(hsic.env["HEADSCALE_SERVER_URL"])
if err != nil {
return nil, err
}

if len(hsic.tlsCert) != 0 && len(hsic.tlsKey) != 0 {
serverUrl.Scheme = "https"
hsic.env["HEADSCALE_SERVER_URL"] = serverUrl.String()
}

headscaleBuildOptions := &dockertest.BuildOptions{
Dockerfile: "Dockerfile.debug",
ContextDir: dockerContextPath,
Expand All @@ -187,7 +214,7 @@ func New(

runOptions := &dockertest.RunOptions{
Name: hsic.hostname,
ExposedPorts: []string{portProto},
ExposedPorts: append([]string{portProto}, hsic.extraPorts...),
Networks: []*dockertest.Network{network},
// Cmd: []string{"headscale", "serve"},
// TODO(kradalby): Get rid of this hack, we currently need to give us some
Expand All @@ -196,6 +223,18 @@ func New(
Env: env,
}

if len(hsic.hostPortBindings) > 0 {
runOptions.PortBindings = map[docker.Port][]docker.PortBinding{}
for port, hostPorts := range hsic.hostPortBindings {
runOptions.PortBindings[docker.Port(port)] = []docker.PortBinding{}
for _, hostPort := range hostPorts {
runOptions.PortBindings[docker.Port(port)] = append(
runOptions.PortBindings[docker.Port(port)],
docker.PortBinding{HostPort: hostPort})
}
}
}

// dockertest isnt very good at handling containers that has already
// been created, this is an attempt to make sure this container isnt
// present.
Expand Down Expand Up @@ -456,7 +495,7 @@ func (t *HeadscaleInContainer) WriteFile(path string, data []byte) error {
}

// nolint
func createCertificate() ([]byte, []byte, error) {
func createCertificate(hostname string) ([]byte, []byte, error) {
// From:
// https://shaneutt.com/blog/golang-ca-and-signed-cert-go/

Expand All @@ -468,7 +507,7 @@ func createCertificate() ([]byte, []byte, error) {
Locality: []string{"Leiden"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(30 * time.Minute),
NotAfter: time.Now().Add(60 * time.Minute),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
Expand All @@ -486,16 +525,17 @@ func createCertificate() ([]byte, []byte, error) {
cert := &x509.Certificate{
SerialNumber: big.NewInt(1658),
Subject: pkix.Name{
CommonName: hostname,
Organization: []string{"Headscale testing INC"},
Country: []string{"NL"},
Locality: []string{"Leiden"},
},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
NotBefore: time.Now(),
NotAfter: time.Now().Add(30 * time.Minute),
NotAfter: time.Now().Add(60 * time.Minute),
SubjectKeyId: []byte{1, 2, 3, 4, 6},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
DNSNames: []string{hostname},
}

certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
Expand Down

0 comments on commit 549f5a1

Please sign in to comment.