mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2024-11-18 10:29:43 +00:00
Implement HTTP-01 challenge
This commit is contained in:
parent
73c21d0195
commit
c99dbb34ce
3 changed files with 40 additions and 2 deletions
|
@ -11,5 +11,6 @@
|
||||||
- `ACME_EMAIL` (default: `noreply@example.email`): Set this to "true" to accept the Terms of Service of your ACME provider.
|
- `ACME_EMAIL` (default: `noreply@example.email`): Set this to "true" to accept the Terms of Service of your ACME provider.
|
||||||
- `ACME_EAB_KID` & `ACME_EAB_HMAC` (default: don't use EAB): EAB credentials, for example for ZeroSSL.
|
- `ACME_EAB_KID` & `ACME_EAB_HMAC` (default: don't use EAB): EAB credentials, for example for ZeroSSL.
|
||||||
- `ACME_ACCEPT_TERMS` (default: use self-signed certificate): Set this to "true" to accept the Terms of Service of your ACME provider.
|
- `ACME_ACCEPT_TERMS` (default: use self-signed certificate): Set this to "true" to accept the Terms of Service of your ACME provider.
|
||||||
|
- `ENABLE_HTTP_SERVER` (default: false): Set this to true to enable the HTTP-01 challenge and redirect all other HTTP requests to HTTPS. Currently only works with port 80.
|
||||||
- `DNS_PROVIDER` (default: use self-signed certificate): Code of the ACME DNS provider for the main domain wildcard.
|
- `DNS_PROVIDER` (default: use self-signed certificate): Code of the ACME DNS provider for the main domain wildcard.
|
||||||
See https://go-acme.github.io/lego/dns/ for available values & additional environment variables.
|
See https://go-acme.github.io/lego/dns/ for available values & additional environment variables.
|
||||||
|
|
|
@ -131,7 +131,6 @@ var tlsConfig = &tls.Config{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var challengeCache = mcache.New()
|
|
||||||
var keyCache = mcache.New()
|
var keyCache = mcache.New()
|
||||||
var keyDatabase *pogreb.DB
|
var keyDatabase *pogreb.DB
|
||||||
|
|
||||||
|
@ -189,6 +188,7 @@ var acmeClientOrderLimit = equalizer.NewTokenBucket(25, 15 * time.Minute)
|
||||||
// rate limit is 20 / second, we want 10 / second
|
// rate limit is 20 / second, we want 10 / second
|
||||||
var acmeClientRequestLimit = equalizer.NewTokenBucket(10, 1 * time.Second)
|
var acmeClientRequestLimit = equalizer.NewTokenBucket(10, 1 * time.Second)
|
||||||
|
|
||||||
|
var challengeCache = mcache.New()
|
||||||
type AcmeTLSChallengeProvider struct{}
|
type AcmeTLSChallengeProvider struct{}
|
||||||
var _ challenge.Provider = AcmeTLSChallengeProvider{}
|
var _ challenge.Provider = AcmeTLSChallengeProvider{}
|
||||||
func (a AcmeTLSChallengeProvider) Present(domain, _, keyAuth string) error {
|
func (a AcmeTLSChallengeProvider) Present(domain, _, keyAuth string) error {
|
||||||
|
@ -198,6 +198,15 @@ func (a AcmeTLSChallengeProvider) CleanUp(domain, _, _ string) error {
|
||||||
challengeCache.Remove(domain)
|
challengeCache.Remove(domain)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
type AcmeHTTPChallengeProvider struct{}
|
||||||
|
var _ challenge.Provider = AcmeHTTPChallengeProvider{}
|
||||||
|
func (a AcmeHTTPChallengeProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
return challengeCache.Set(domain + "/" + token, keyAuth, 1*time.Hour)
|
||||||
|
}
|
||||||
|
func (a AcmeHTTPChallengeProvider) CleanUp(domain, token, _ string) error {
|
||||||
|
challengeCache.Remove(domain + "/" + token)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func retrieveCertFromDB(sni []byte) (tls.Certificate, bool) {
|
func retrieveCertFromDB(sni []byte) (tls.Certificate, bool) {
|
||||||
// parse certificate from database
|
// parse certificate from database
|
||||||
|
@ -383,7 +392,14 @@ func setupCertificates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
acmeClient = newAcmeClient(func(challenge *resolver.SolverManager) error {
|
acmeClient = newAcmeClient(func(challenge *resolver.SolverManager) error {
|
||||||
return challenge.SetTLSALPN01Provider(AcmeTLSChallengeProvider{})
|
err = challenge.SetTLSALPN01Provider(AcmeTLSChallengeProvider{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if os.Getenv("ENABLE_HTTP_SERVER") == "true" {
|
||||||
|
return challenge.SetHTTP01Provider(AcmeHTTPChallengeProvider{})
|
||||||
|
}
|
||||||
|
return err
|
||||||
})
|
})
|
||||||
mainDomainAcmeClient = newAcmeClient(func(challenge *resolver.SolverManager) error {
|
mainDomainAcmeClient = newAcmeClient(func(challenge *resolver.SolverManager) error {
|
||||||
if os.Getenv("DNS_PROVIDER") == "" {
|
if os.Getenv("DNS_PROVIDER") == "" {
|
||||||
|
|
21
main.go
21
main.go
|
@ -22,6 +22,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -103,6 +104,26 @@ func main() {
|
||||||
listener = tls.NewListener(listener, tlsConfig)
|
listener = tls.NewListener(listener, tlsConfig)
|
||||||
|
|
||||||
setupCertificates()
|
setupCertificates()
|
||||||
|
if os.Getenv("ENABLE_HTTP_SERVER") == "true" {
|
||||||
|
go (func() {
|
||||||
|
challengePath := []byte("/.well-known/acme-challenge/")
|
||||||
|
err := fasthttp.ListenAndServe("[::]:80", func(ctx *fasthttp.RequestCtx) {
|
||||||
|
if bytes.HasPrefix(ctx.Path(), challengePath) {
|
||||||
|
challenge, ok := challengeCache.Get(string(TrimHostPort(ctx.Host())) + "/" + string(bytes.TrimPrefix(ctx.Path(), challengePath)))
|
||||||
|
if !ok {
|
||||||
|
ctx.SetStatusCode(http.StatusNotFound)
|
||||||
|
ctx.SetBodyString("no challenge for this token")
|
||||||
|
}
|
||||||
|
ctx.SetBodyString(challenge.(string))
|
||||||
|
} else {
|
||||||
|
ctx.Redirect("https://" + string(ctx.Host()) + string(ctx.RequestURI()), http.StatusMovedPermanently)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Couldn't start HTTP server: %s", err)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
|
||||||
// Start the web server
|
// Start the web server
|
||||||
err = server.Serve(listener)
|
err = server.Serve(listener)
|
||||||
|
|
Loading…
Reference in a new issue