about summary refs log tree commit diff stats
path: root/internal/server
diff options
context:
space:
mode:
Diffstat (limited to 'internal/server')
-rw-r--r--internal/server/server.go17
-rw-r--r--internal/server/tls.go39
2 files changed, 47 insertions, 9 deletions
diff --git a/internal/server/server.go b/internal/server/server.go
index b174c0c..0bbfba4 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -8,6 +8,7 @@ import (
 	"net/url"
 	"os"
 	"path/filepath"
+	"regexp"
 	"slices"
 	"strconv"
 	"strings"
@@ -184,11 +185,21 @@ func New(runtimeConfig *Config, log *log.Logger) (*Server, error) {
 	}
 
 	if runtimeConfig.Redirect {
+		re := regexp.MustCompile(
+			"^(.*)\\." + strings.ReplaceAll(config.WildcardDomain, ".", `\.`) + "$",
+		)
+		replace := "${1}." + config.Domains[0]
 		loggingMux.Handle(config.BaseURL.Hostname()+"/", mux)
 		loggingMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-			path, _ := website.CanonicalisePath(r.URL.Path)
-			newURL := config.BaseURL.JoinPath(path)
-			http.Redirect(w, r, newURL.String(), http.StatusMovedPermanently)
+			if slices.Contains(config.Domains, r.Host) {
+				path, _ := website.CanonicalisePath(r.URL.Path)
+				newURL := config.BaseURL.JoinPath(path)
+				http.Redirect(w, r, newURL.String(), http.StatusMovedPermanently)
+			} else {
+				url := config.BaseURL
+				url.Host = re.ReplaceAllString(r.Host, replace)
+				http.Redirect(w, r, url.String(), http.StatusTemporaryRedirect)
+			}
 		})
 	} else {
 		loggingMux.Handle("/", mux)
diff --git a/internal/server/tls.go b/internal/server/tls.go
index 85eaac9..4d52b8d 100644
--- a/internal/server/tls.go
+++ b/internal/server/tls.go
@@ -12,6 +12,7 @@ import (
 	"github.com/ardanlabs/conf/v3"
 	"github.com/caddyserver/caddy/v2"
 	"github.com/caddyserver/certmagic"
+	"github.com/libdns/acmedns"
 	certmagic_redis "github.com/pberkel/caddy-storage-redis"
 	"gitlab.com/tozd/go/errors"
 )
@@ -24,8 +25,14 @@ type redisConfig struct {
 	KeyPrefix     string `conf:"default:certmagic"`
 }
 
+type acmeConfig struct {
+	Username  string `conf:"required"`
+	Password  string `conf:"required"`
+	Subdomain string `conf:"required"`
+	ServerURL string `conf:"env:SERVER_URL,default:https://acme.alanpearce.eu"`
+}
+
 func (s *Server) serveTLS() (err error) {
-	var issuer *certmagic.ACMEIssuer
 	log := s.log.Named("tls")
 
 	// setting cfg.Logger is too late somehow
@@ -33,9 +40,7 @@ func (s *Server) serveTLS() (err error) {
 	cfg := certmagic.NewDefault()
 	cfg.DefaultServerName = s.config.Domains[0]
 
-	issuer = &certmagic.DefaultACME
-	certmagic.DefaultACME.Agreed = true
-	certmagic.DefaultACME.Email = s.config.Email
+	var issuer *certmagic.ACMEIssuer
 
 	if s.runtimeConfig.Development {
 		ca := s.runtimeConfig.ACMECA
@@ -63,8 +68,8 @@ func (s *Server) serveTLS() (err error) {
 			ListenHost:              s.runtimeConfig.ListenAddress,
 			AltHTTPPort:             s.runtimeConfig.Port,
 			AltTLSALPNPort:          s.runtimeConfig.TLSPort,
+			Logger:                  certmagic.Default.Logger,
 		})
-		cfg.Issuers[0] = issuer
 	} else {
 		rc := &redisConfig{}
 		_, err = conf.Parse("REDIS", rc)
@@ -72,6 +77,27 @@ func (s *Server) serveTLS() (err error) {
 			return errors.Wrap(err, "could not parse redis config")
 		}
 
+		acme := &acmedns.Provider{}
+		_, err = conf.Parse("ACME", acme)
+		if err != nil {
+			return errors.Wrap(err, "could not parse ACME config")
+		}
+
+		issuer = certmagic.NewACMEIssuer(cfg, certmagic.ACMEIssuer{
+			CA:     certmagic.LetsEncryptProductionCA,
+			Email:  s.config.Email,
+			Agreed: true,
+			Logger: certmagic.Default.Logger,
+			DNS01Solver: &certmagic.DNS01Solver{
+				DNSManager: certmagic.DNSManager{
+					DNSProvider: acme,
+					Logger:      certmagic.Default.Logger,
+				},
+			},
+		})
+
+		log.Info("acme", "username", acme.Username, "subdomain", acme.Subdomain, "server_url", acme.ServerURL)
+
 		rs := certmagic_redis.New()
 		rs.Address = []string{rc.Address}
 		rs.Username = rc.Username
@@ -87,6 +113,7 @@ func (s *Server) serveTLS() (err error) {
 			return errors.Wrap(err, "could not provision redis storage")
 		}
 	}
+	cfg.Issuers[0] = issuer
 
 	ln, err := listenfd.GetListener(
 		1,
@@ -137,7 +164,7 @@ func (s *Server) serveTLS() (err error) {
 		"https_port",
 		s.runtimeConfig.TLSPort,
 	)
-	err = cfg.ManageSync(context.TODO(), s.config.Domains)
+	err = cfg.ManageAsync(context.TODO(), s.config.Domains)
 	if err != nil {
 		return errors.Wrap(err, "could not enable TLS")
 	}