Add support for private Tailscale HTTPS

This commit is contained in:
Jan-Lukas Else 2021-09-22 23:55:07 +02:00
parent b4b36d1441
commit 2080058dfe
4 changed files with 593 additions and 48 deletions

View File

@ -35,6 +35,7 @@ type configServer struct {
ShortPublicAddress string `mapstructure:"shortPublicAddress"`
MediaAddress string `mapstructure:"mediaAddress"`
PublicHTTPS bool `mapstructure:"publicHttps"`
TailscaleHTTPS bool `mapstructure:"tailscaleHttps"`
Tor bool `mapstructure:"tor"`
SecurityHeaders bool `mapstructure:"securityHeaders"`
CSPDomains []string `mapstructure:"cspDomains"`

20
go.mod
View File

@ -34,7 +34,7 @@ require (
github.com/schollz/sqlite3dump v1.3.0
github.com/snabb/sitemap v1.0.0
github.com/spf13/cast v1.4.1
github.com/spf13/viper v1.8.1
github.com/spf13/viper v1.9.0
github.com/stretchr/testify v1.7.0
github.com/tdewolff/minify/v2 v2.9.22
github.com/thoas/go-funk v0.9.1
@ -43,15 +43,16 @@ require (
github.com/yuin/goldmark v1.4.1
// master
github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/net v0.0.0-20210913180222-943fd674d43e
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
tailscale.com v1.14.3
willnorris.com/go/microformats v1.1.1
)
require (
github.com/andybalholm/cascadia v1.2.0 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
@ -65,7 +66,8 @@ require (
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/lestrrat-go/strftime v1.0.5 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
@ -75,8 +77,12 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/tdewolff/parse/v2 v2.5.21 // indirect
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 // indirect
go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 // indirect
golang.org/x/sys v0.0.0-20210921065528-437939a70204 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.63.0 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e // indirect
)

571
go.sum

File diff suppressed because it is too large Load Diff

49
http.go
View File

@ -2,6 +2,7 @@ package main
import (
"compress/flate"
"crypto/tls"
"database/sql"
"errors"
"fmt"
@ -19,6 +20,7 @@ import (
"golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/net/context"
"tailscale.com/client/tailscale"
)
const (
@ -62,7 +64,7 @@ func (a *goBlog) startServer() (err error) {
WriteTimeout: 5 * time.Minute,
}
a.shutdown.Add(shutdownServer(s, "main server"))
if a.cfg.Server.PublicHTTPS {
if a.cfg.Server.PublicHTTPS || a.cfg.Server.TailscaleHTTPS {
// Start HTTP server for redirects
httpServer := &http.Server{
Addr: ":http",
@ -78,23 +80,34 @@ func (a *goBlog) startServer() (err error) {
}()
// Start HTTPS
s.Addr = ":https"
hosts := []string{a.cfg.Server.publicHostname}
if shn := a.cfg.Server.shortPublicHostname; shn != "" {
hosts = append(hosts, shn)
}
if mhn := a.cfg.Server.mediaHostname; mhn != "" {
hosts = append(hosts, mhn)
}
acmeDir := acme.LetsEncryptURL
// acmeDir := "https://acme-staging-v02.api.letsencrypt.org/directory"
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(hosts...),
Cache: &httpsCache{db: a.db},
Client: &acme.Client{DirectoryURL: acmeDir},
}
if err = s.Serve(m.Listener()); err != nil && err != http.ErrServerClosed {
return err
if a.cfg.Server.TailscaleHTTPS {
// HTTPS via Tailscale
s.TLSConfig = &tls.Config{
GetCertificate: tailscale.GetCertificate,
}
if err = s.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed {
return err
}
} else {
// Public HTTPS via Let's Encrypt
hosts := []string{a.cfg.Server.publicHostname}
if shn := a.cfg.Server.shortPublicHostname; shn != "" {
hosts = append(hosts, shn)
}
if mhn := a.cfg.Server.mediaHostname; mhn != "" {
hosts = append(hosts, mhn)
}
acmeDir := acme.LetsEncryptURL
// acmeDir := "https://acme-staging-v02.api.letsencrypt.org/directory"
m := &autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist(hosts...),
Cache: &httpsCache{db: a.db},
Client: &acme.Client{DirectoryURL: acmeDir},
}
if err = s.Serve(m.Listener()); err != nil && err != http.ErrServerClosed {
return err
}
}
} else {
s.Addr = ":" + strconv.Itoa(a.cfg.Server.Port)