main
 1package cfg
 2
 3import (
 4	"context"
 5	"crypto/tls"
 6	"crypto/x509"
 7	"encoding/pem"
 8	"io/ioutil"
 9	"net/http"
10	"os"
11	"path/filepath"
12
13	"github.com/caddyserver/certmagic"
14	"github.com/xlgmokha/x/pkg/x"
15	"go.uber.org/zap"
16)
17
18func WithSelfSigned(cert, key string) Option {
19	certificate := x.Must(tls.LoadX509KeyPair(cert, key))
20
21	return func(config *Config) {
22		config.TLS = &tls.Config{
23			MinVersion:   tls.VersionTLS13,
24			Certificates: []tls.Certificate{certificate},
25		}
26	}
27}
28
29func WithTLS(domainNames []string) Option {
30	directoryURL := "https://localhost:8081/acme/acme/directory"
31	storage := &certmagic.FileStorage{
32		Path: filepath.Join(x.Must(os.Getwd()), "/tmp/cache"),
33	}
34	var cache *certmagic.Cache
35	cache = certmagic.NewCache(certmagic.CacheOptions{
36		GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
37			return certmagic.New(cache, certmagic.Config{
38				Logger:   x.Must(zap.NewProduction()),
39				OnDemand: new(certmagic.OnDemandConfig),
40				Storage:  storage,
41			}), nil
42		},
43	})
44	roots := x.Must(x509.SystemCertPool())
45	roots.AddCert(func() *x509.Certificate {
46		block, _ := pem.Decode(x.Must(ioutil.ReadFile(
47			filepath.Join(x.Must(os.Getwd()), "/tmp/step/certs/root_ca.crt"),
48		)))
49		return x.Must(x509.ParseCertificate(block.Bytes))
50	}())
51	magic := certmagic.New(cache, certmagic.Config{
52		Logger:   x.Must(zap.NewProduction()),
53		OnDemand: new(certmagic.OnDemandConfig),
54		Storage:  storage,
55	})
56	issuer := certmagic.NewACMEIssuer(magic, certmagic.ACMEIssuer{
57		Agreed:       true,
58		Email:        "email@example.com",
59		CA:           directoryURL,
60		TestCA:       directoryURL,
61		TrustedRoots: roots,
62	})
63	magic.Issuers = []certmagic.Issuer{issuer}
64
65	if err := http.ListenAndServe(":80", issuer.HTTPChallengeHandler(http.DefaultServeMux)); err != nil {
66		return func(*Config) {}
67	}
68
69	x.Check(magic.ManageSync(context.Background(), domainNames))
70
71	return func(config *Config) {
72		config.TLS = magic.TLSConfig()
73		config.TLS.NextProtos = append([]string{"h2", "http/1.1"}, config.TLS.NextProtos...)
74	}
75}