mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-26 17:03:06 +00:00
Expand surface of hsic for better TLS support
This commit is contained in:
parent
17b597ed77
commit
b8bf0a3b9f
1 changed files with 46 additions and 6 deletions
|
@ -15,6 +15,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
@ -23,6 +24,7 @@ import (
|
||||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||||
"github.com/juanfont/headscale/integration/integrationutil"
|
"github.com/juanfont/headscale/integration/integrationutil"
|
||||||
"github.com/ory/dockertest/v3"
|
"github.com/ory/dockertest/v3"
|
||||||
|
"github.com/ory/dockertest/v3/docker"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -52,6 +54,8 @@ type HeadscaleInContainer struct {
|
||||||
|
|
||||||
// optional config
|
// optional config
|
||||||
port int
|
port int
|
||||||
|
extraPorts []string
|
||||||
|
hostPortBindings map[string][]string
|
||||||
aclPolicy *headscale.ACLPolicy
|
aclPolicy *headscale.ACLPolicy
|
||||||
env map[string]string
|
env map[string]string
|
||||||
tlsCert []byte
|
tlsCert []byte
|
||||||
|
@ -77,7 +81,7 @@ func WithACLPolicy(acl *headscale.ACLPolicy) Option {
|
||||||
// WithTLS creates certificates and enables HTTPS.
|
// WithTLS creates certificates and enables HTTPS.
|
||||||
func WithTLS() Option {
|
func WithTLS() Option {
|
||||||
return func(hsic *HeadscaleInContainer) {
|
return func(hsic *HeadscaleInContainer) {
|
||||||
cert, key, err := createCertificate()
|
cert, key, err := createCertificate(hsic.hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to create certificates for headscale test: %s", err)
|
log.Fatalf("failed to create certificates for headscale test: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -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
|
// WithTestName sets a name for the test, this will be reflected
|
||||||
// in the Docker container name.
|
// in the Docker container name.
|
||||||
func WithTestName(testName string) Option {
|
func WithTestName(testName string) Option {
|
||||||
|
@ -173,6 +190,16 @@ func New(
|
||||||
|
|
||||||
portProto := fmt.Sprintf("%d/tcp", hsic.port)
|
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{
|
headscaleBuildOptions := &dockertest.BuildOptions{
|
||||||
Dockerfile: "Dockerfile.debug",
|
Dockerfile: "Dockerfile.debug",
|
||||||
ContextDir: dockerContextPath,
|
ContextDir: dockerContextPath,
|
||||||
|
@ -187,7 +214,7 @@ func New(
|
||||||
|
|
||||||
runOptions := &dockertest.RunOptions{
|
runOptions := &dockertest.RunOptions{
|
||||||
Name: hsic.hostname,
|
Name: hsic.hostname,
|
||||||
ExposedPorts: []string{portProto},
|
ExposedPorts: append([]string{portProto}, hsic.extraPorts...),
|
||||||
Networks: []*dockertest.Network{network},
|
Networks: []*dockertest.Network{network},
|
||||||
// Cmd: []string{"headscale", "serve"},
|
// Cmd: []string{"headscale", "serve"},
|
||||||
// TODO(kradalby): Get rid of this hack, we currently need to give us some
|
// TODO(kradalby): Get rid of this hack, we currently need to give us some
|
||||||
|
@ -196,6 +223,18 @@ func New(
|
||||||
Env: env,
|
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
|
// dockertest isnt very good at handling containers that has already
|
||||||
// been created, this is an attempt to make sure this container isnt
|
// been created, this is an attempt to make sure this container isnt
|
||||||
// present.
|
// present.
|
||||||
|
@ -456,7 +495,7 @@ func (t *HeadscaleInContainer) WriteFile(path string, data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func createCertificate() ([]byte, []byte, error) {
|
func createCertificate(hostname string) ([]byte, []byte, error) {
|
||||||
// From:
|
// From:
|
||||||
// https://shaneutt.com/blog/golang-ca-and-signed-cert-go/
|
// https://shaneutt.com/blog/golang-ca-and-signed-cert-go/
|
||||||
|
|
||||||
|
@ -468,7 +507,7 @@ func createCertificate() ([]byte, []byte, error) {
|
||||||
Locality: []string{"Leiden"},
|
Locality: []string{"Leiden"},
|
||||||
},
|
},
|
||||||
NotBefore: time.Now(),
|
NotBefore: time.Now(),
|
||||||
NotAfter: time.Now().Add(30 * time.Minute),
|
NotAfter: time.Now().Add(60 * time.Minute),
|
||||||
IsCA: true,
|
IsCA: true,
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
ExtKeyUsage: []x509.ExtKeyUsage{
|
||||||
x509.ExtKeyUsageClientAuth,
|
x509.ExtKeyUsageClientAuth,
|
||||||
|
@ -486,16 +525,17 @@ func createCertificate() ([]byte, []byte, error) {
|
||||||
cert := &x509.Certificate{
|
cert := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(1658),
|
SerialNumber: big.NewInt(1658),
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
|
CommonName: hostname,
|
||||||
Organization: []string{"Headscale testing INC"},
|
Organization: []string{"Headscale testing INC"},
|
||||||
Country: []string{"NL"},
|
Country: []string{"NL"},
|
||||||
Locality: []string{"Leiden"},
|
Locality: []string{"Leiden"},
|
||||||
},
|
},
|
||||||
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
|
|
||||||
NotBefore: time.Now(),
|
NotBefore: time.Now(),
|
||||||
NotAfter: time.Now().Add(30 * time.Minute),
|
NotAfter: time.Now().Add(60 * time.Minute),
|
||||||
SubjectKeyId: []byte{1, 2, 3, 4, 6},
|
SubjectKeyId: []byte{1, 2, 3, 4, 6},
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||||
|
DNSNames: []string{hostname},
|
||||||
}
|
}
|
||||||
|
|
||||||
certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||||
|
|
Loading…
Reference in a new issue