Merge branch '18947-githttpd'
[arvados.git] / lib / boot / cert.go
index 560579b77716bcbcd252d981c5da4cc396ab9ef4..916f9f53b2af7b9109474c3e662b395174f982b9 100644 (file)
@@ -6,29 +6,38 @@ package boot
 
 import (
        "context"
+       "fmt"
        "io/ioutil"
+       "net"
+       "os"
        "path/filepath"
 )
 
+// Create a root CA key and use it to make a new server
+// certificate+key pair.
+//
+// In future we'll make one root CA key per host instead of one per
+// cluster, so it only needs to be imported to a browser once for
+// ongoing dev/test usage.
 type createCertificates struct{}
 
 func (createCertificates) String() string {
        return "certificates"
 }
 
-func (createCertificates) Run(ctx context.Context, fail func(error), boot *Booter) error {
+func (createCertificates) Run(ctx context.Context, fail func(error), super *Supervisor) error {
        // Generate root key
-       err := boot.RunProgram(ctx, boot.tempdir, nil, nil, "openssl", "genrsa", "-out", "rootCA.key", "4096")
+       err := super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "genrsa", "-out", "rootCA.key", "4096")
        if err != nil {
                return err
        }
        // Generate a self-signed root certificate
-       err = boot.RunProgram(ctx, boot.tempdir, nil, nil, "openssl", "req", "-x509", "-new", "-nodes", "-key", "rootCA.key", "-sha256", "-days", "3650", "-out", "rootCA.crt", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost")
+       err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "req", "-x509", "-new", "-nodes", "-key", "rootCA.key", "-sha256", "-days", "3650", "-out", "rootCA.crt", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost")
        if err != nil {
                return err
        }
        // Generate server key
-       err = boot.RunProgram(ctx, boot.tempdir, nil, nil, "openssl", "genrsa", "-out", "server.key", "2048")
+       err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "genrsa", "-out", "server.key", "2048")
        if err != nil {
                return err
        }
@@ -37,20 +46,30 @@ func (createCertificates) Run(ctx context.Context, fail func(error), boot *Boote
        if err != nil {
                return err
        }
-       err = ioutil.WriteFile(filepath.Join(boot.tempdir, "server.cfg"), append(defaultconf, []byte(`
-[SAN]
-subjectAltName=DNS:localhost,DNS:localhost.localdomain
-`)...), 0777)
+       hostname, err := os.Hostname()
+       if err != nil {
+               return fmt.Errorf("hostname: %w", err)
+       }
+       san := "DNS:localhost,DNS:localhost.localdomain,DNS:" + hostname
+       if super.ListenHost == hostname || super.ListenHost == "localhost" {
+               // already have it
+       } else if net.ParseIP(super.ListenHost) != nil {
+               san += fmt.Sprintf(",IP:%s", super.ListenHost)
+       } else {
+               san += fmt.Sprintf(",DNS:%s", super.ListenHost)
+       }
+       conf := append(defaultconf, []byte(fmt.Sprintf("\n[SAN]\nsubjectAltName=%s\n", san))...)
+       err = ioutil.WriteFile(filepath.Join(super.tempdir, "server.cfg"), conf, 0644)
        if err != nil {
                return err
        }
        // Generate signing request
-       err = boot.RunProgram(ctx, boot.tempdir, nil, nil, "openssl", "req", "-new", "-sha256", "-key", "server.key", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost", "-reqexts", "SAN", "-config", "server.cfg", "-out", "server.csr")
+       err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "req", "-new", "-sha256", "-key", "server.key", "-subj", "/C=US/ST=MA/O=Example Org/CN=localhost", "-reqexts", "SAN", "-config", "server.cfg", "-out", "server.csr")
        if err != nil {
                return err
        }
        // Sign certificate
-       err = boot.RunProgram(ctx, boot.tempdir, nil, nil, "openssl", "x509", "-req", "-in", "server.csr", "-CA", "rootCA.crt", "-CAkey", "rootCA.key", "-CAcreateserial", "-out", "server.crt", "-days", "3650", "-sha256")
+       err = super.RunProgram(ctx, super.tempdir, runOptions{}, "openssl", "x509", "-req", "-in", "server.csr", "-CA", "rootCA.crt", "-CAkey", "rootCA.key", "-CAcreateserial", "-out", "server.crt", "-extfile", "server.cfg", "-extensions", "SAN", "-days", "3650", "-sha256")
        if err != nil {
                return err
        }