all repos — homestead @ 9187a5d1ad9b22009c8e3a7ae999f912e0cf4ea7

Code for my website

add wildcard domain redirect support

Alan Pearce
commit

9187a5d1ad9b22009c8e3a7ae999f912e0cf4ea7

parent

b3bf19dceced6114b2287ea3c57cd00e67ea1211

M fly.tomlfly.toml
@@ -18,6 +18,7 @@ ROOT = "/data"
PRODUCTION = "true" VCS_LOCAL_PATH = "/data/website" VCS_REMOTE_URL = "https://git.alanpearce.eu/website.git" + ACME_SERVER_URL = "https://acme.alanpearce.eu" [[services]] internal_port = 8080
M go.modgo.mod
@@ -20,6 +20,7 @@ github.com/fatih/structtag v1.2.0
github.com/fsnotify/fsnotify v1.7.0 github.com/go-git/go-git/v5 v5.12.0 github.com/kevinpollet/nego v0.0.0-20211010160919-a65cd48cee43 + github.com/libdns/acmedns v0.2.0 github.com/osdevisnot/sorvor v0.4.4 github.com/pberkel/caddy-storage-redis v1.2.0 github.com/snabb/sitemap v1.0.4
M go.sumgo.sum
@@ -137,6 +137,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/libdns/acmedns v0.2.0 h1:zTXdHZwe3r2issdVRyqt5/4X2yHpiBVmFnTrwBA29ik= +github.com/libdns/acmedns v0.2.0/go.mod h1:XlKHilQQK/IGHYY//vCb903PdG4Wc/XnDQzcMp2hV3g= github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
M internal/config/config.gointernal/config/config.go
@@ -42,6 +42,7 @@ DomainStartDate string `toml:"domain_start_date"`
OriginalDomain string `toml:"original_domain"` GoatCounter URL `toml:"goatcounter"` Domains []string + WildcardDomain string OIDCHost URL `toml:"oidc_host"` Taxonomies []Taxonomy CSP *CSP `toml:"content-security-policy"`
M internal/server/server.gointernal/server/server.go
@@ -8,6 +8,7 @@ "net/http"
"net/url" "os" "path/filepath" + "regexp" "slices" "strconv" "strings"
@@ -184,11 +185,26 @@ return nil, errors.Wrap(err, "could not create website mux")
} if runtimeConfig.Redirect { + re := regexp.MustCompile( + "^(.*)\\." + strings.ReplaceAll(config.WildcardDomain, ".", `\.`) + "$", + ) + replace := "${0}." + 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 { + matches := re.FindSubmatchIndex([]byte(r.Host)) + if matches == nil { + http.Redirect(w, r, config.BaseURL.String(), http.StatusTemporaryRedirect) + + return + } + newHost := re.ExpandString([]byte{}, replace, r.Host, matches) + http.Redirect(w, r, string(newHost), http.StatusTemporaryRedirect) + } }) } else { loggingMux.Handle("/", mux)
M internal/server/tls.gointernal/server/tls.go
@@ -12,6 +12,7 @@
"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" )
@@ -22,6 +23,13 @@ Username string `conf:"default:default"`
Password string `conf:"required"` EncryptionKey string `conf:"required"` 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) {
@@ -71,6 +79,21 @@ _, err = conf.Parse("REDIS", rc)
if err != nil { 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.DNS01Solver = &certmagic.DNS01Solver{ + DNSManager: certmagic.DNSManager{ + DNSProvider: acme, + Logger: certmagic.Default.Logger, + }, + } + + log.Debug("acme", "username", acme.Username, "subdomain", acme.Subdomain, "server_url", acme.ServerURL) rs := certmagic_redis.New() rs.Address = []string{rc.Address}