Implement HTTP-only mode

This is very useful for reserve proxies
in cases when TLS passthrough is not desired.
This commit is contained in:
JCM 2024-05-23 12:07:32 +02:00
parent 69361c69c1
commit ec3af84174
No known key found for this signature in database
GPG Key ID: 2F536DE3E9EC3AD8
6 changed files with 63 additions and 40 deletions

View File

@ -150,6 +150,12 @@ var (
EnvVars: []string{"PROFILING_ADDRESS"},
Value: "localhost:9999",
},
&cli.BoolFlag{
Name: "http-only-mode",
Usage: "serve content directly via HTTP using the Host header to identify the repository",
EnvVars: []string{"HTTP_ONLY_MODE"},
Value: false,
},
// ############################
// ### ACME Client Settings ###

View File

@ -9,6 +9,7 @@ mainDomain = 'codeberg.page'
rawDomain = 'raw.codeberg.page'
allowedCorsDomains = ['fonts.codeberg.org', 'design.codeberg.org']
blacklistedPaths = ['do/not/use']
httpOnlyMode = false
[gitea]
root = 'codeberg.org'

View File

@ -18,6 +18,7 @@ type ServerConfig struct {
PagesBranches []string
AllowedCorsDomains []string
BlacklistedPaths []string
HttpOnlyMode bool `default:"false"`
}
type GiteaConfig struct {

View File

@ -84,6 +84,9 @@ func mergeServerConfig(ctx *cli.Context, config *ServerConfig) {
if ctx.IsSet("blacklisted-paths") {
config.BlacklistedPaths = ctx.StringSlice("blacklisted-paths")
}
if ctx.IsSet("http-only-mode") {
config.HttpOnlyMode = ctx.Bool("http-only-mode")
}
// add the paths that should always be blacklisted
config.BlacklistedPaths = append(config.BlacklistedPaths, ALWAYS_BLACKLISTED_PATHS...)

View File

@ -10,6 +10,7 @@ rawDomain = 'raw.codeberg.page'
pagesBranches = ["pages"]
allowedCorsDomains = []
blacklistedPaths = []
httpOnlyMode = false
[gitea]
root = 'https://codeberg.org'

View File

@ -82,51 +82,62 @@ func Serve(ctx *cli.Context) error {
return fmt.Errorf("could not create new gitea client: %v", err)
}
acmeClient, err := acme.CreateAcmeClient(cfg.ACME, cfg.Server.HttpServerEnabled, challengeCache)
if err != nil {
return err
}
var listener net.Listener
if cfg.Server.HttpOnlyMode {
log.Info().Msgf("Create TCP listener on %s", listeningHTTPAddress)
listener_, err := net.Listen("tcp", listeningHTTPAddress)
if err != nil {
return fmt.Errorf("couldn't create listener: %v", err)
}
listener = listener_
} else {
acmeClient, err := acme.CreateAcmeClient(cfg.ACME, cfg.Server.HttpServerEnabled, challengeCache)
if err != nil {
return err
}
if err := certificates.SetupMainDomainCertificates(cfg.Server.MainDomain, acmeClient, certDB); err != nil {
return err
}
if err := certificates.SetupMainDomainCertificates(cfg.Server.MainDomain, acmeClient, certDB); err != nil {
return err
}
// Create listener for SSL connections
log.Info().Msgf("Create TCP listener for SSL on %s", listeningSSLAddress)
listener, err := net.Listen("tcp", listeningSSLAddress)
if err != nil {
return fmt.Errorf("couldn't create listener: %v", err)
}
// Create listener for SSL connections
log.Info().Msgf("Create TCP listener for SSL on %s", listeningSSLAddress)
listener_, err := net.Listen("tcp", listeningSSLAddress)
if err != nil {
return fmt.Errorf("couldn't create listener: %v", err)
}
listener = listener_
// Setup listener for SSL connections
listener = tls.NewListener(listener, certificates.TLSConfig(
cfg.Server.MainDomain,
giteaClient,
acmeClient,
cfg.Server.PagesBranches[0],
keyCache, challengeCache, dnsLookupCache, canonicalDomainCache,
certDB,
cfg.ACME.NoDNS01,
cfg.Server.RawDomain,
))
// Setup listener for SSL connections
listener = tls.NewListener(listener, certificates.TLSConfig(
cfg.Server.MainDomain,
giteaClient,
acmeClient,
cfg.Server.PagesBranches[0],
keyCache, challengeCache, dnsLookupCache, canonicalDomainCache,
certDB,
cfg.ACME.NoDNS01,
cfg.Server.RawDomain,
))
interval := 12 * time.Hour
certMaintainCtx, cancelCertMaintain := context.WithCancel(context.Background())
defer cancelCertMaintain()
go certificates.MaintainCertDB(certMaintainCtx, interval, acmeClient, cfg.Server.MainDomain, certDB)
interval := 12 * time.Hour
certMaintainCtx, cancelCertMaintain := context.WithCancel(context.Background())
defer cancelCertMaintain()
go certificates.MaintainCertDB(certMaintainCtx, interval, acmeClient, cfg.Server.MainDomain, certDB)
if cfg.Server.HttpServerEnabled {
// Create handler for http->https redirect and http acme challenges
httpHandler := certificates.SetupHTTPACMEChallengeServer(challengeCache, uint(cfg.Server.Port))
if cfg.Server.HttpServerEnabled {
// Create handler for http->https redirect and http acme challenges
httpHandler := certificates.SetupHTTPACMEChallengeServer(challengeCache, uint(cfg.Server.Port))
// Create listener for http and start listening
go func() {
log.Info().Msgf("Start HTTP server listening on %s", listeningHTTPAddress)
err := http.ListenAndServe(listeningHTTPAddress, httpHandler)
if err != nil {
log.Error().Err(err).Msg("Couldn't start HTTP server")
}
}()
// Create listener for http and start listening
go func() {
log.Info().Msgf("Start HTTP server listening on %s", listeningHTTPAddress)
err := http.ListenAndServe(listeningHTTPAddress, httpHandler)
if err != nil {
log.Error().Err(err).Msg("Couldn't start HTTP server")
}
}()
}
}
if ctx.IsSet("enable-profiling") {
@ -137,7 +148,7 @@ func Serve(ctx *cli.Context) error {
sslHandler := handler.Handler(cfg.Server, giteaClient, dnsLookupCache, canonicalDomainCache, redirectsCache)
// Start the ssl listener
log.Info().Msgf("Start SSL server using TCP listener on %s", listener.Addr())
log.Info().Msgf("Start main server using TCP listener on %s", listener.Addr())
return http.Serve(listener, sslHandler)
}