mirror of
https://github.com/acme-dns/acme-dns.git
synced 2026-02-21 09:15:30 -07:00
* Refactor core * Re-added tests * Small fixes * Add tests for acmetxt cidrslice and util funcs * Remove the last dangling reference to old logging package * Refactoring (#327) * chore: enable more linters and fix linter issues * ci: enable linter checks on all branches and disable recurring checks recurring linter checks don't make that much sense. The code & linter checks should not change on their own over night ;) * chore: update packages * Revert "chore: update packages" This reverts commit 30250bf28c4b39e9e5b3af012a4e28ab036bf9af. * chore: manually upgrade some packages * Updated dependencies, wrote changelog entry and fixed namespace for release * Refactoring - improving coverage (#371) * Increase code coverage in acmedns * More testing of ReadConfig() and its fallback mechanism * Found that if someone put a '"' double quote into the filename that we configure zap to log to, it would cause the the JSON created to be invalid. I have replaced the JSON string with proper config * Better handling of config options for api.TLS - we now error on an invalid value instead of silently failing. added a basic test for api.setupTLS() (to increase test coverage) * testing nameserver isOwnChallenge and isAuthoritative methods * add a unit test for nameserver answerOwnChallenge * fix linting errors * bump go and golangci-lint versions in github actions * Update golangci-lint.yml Bumping github-actions workflow versions to accommodate some changes in upstream golanci-lint * Bump Golang version to 1.23 (currently the oldest supported version) Bump golanglint-ci to 2.0.2 and migrate the config file. This should resolve the math/rand/v2 issue * bump golanglint-ci action version * Fixing up new golanglint-ci warnings and errors --------- Co-authored-by: Joona Hoikkala <5235109+joohoi@users.noreply.github.com> * Minor refactoring, error returns and e2e testing suite * Add a few tests * Fix linter and umask setting * Update github actions * Refine concurrency configuration for GitHub actions * HTTP timeouts to API, and self-validation mutex to nameserver ops --------- Co-authored-by: Florian Ritterhoff <32478819+fritterhoff@users.noreply.github.com> Co-authored-by: Jason Playne <jason@jasonplayne.com>
136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/joohoi/acme-dns/pkg/acmedns"
|
|
|
|
"github.com/caddyserver/certmagic"
|
|
"github.com/julienschmidt/httprouter"
|
|
"github.com/rs/cors"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type AcmednsAPI struct {
|
|
Config *acmedns.AcmeDnsConfig
|
|
DB acmedns.AcmednsDB
|
|
Logger *zap.SugaredLogger
|
|
errChan chan error
|
|
}
|
|
|
|
func Init(config *acmedns.AcmeDnsConfig, db acmedns.AcmednsDB, logger *zap.SugaredLogger, errChan chan error) AcmednsAPI {
|
|
a := AcmednsAPI{Config: config, DB: db, Logger: logger, errChan: errChan}
|
|
return a
|
|
}
|
|
|
|
func (a *AcmednsAPI) Start(dnsservers []acmedns.AcmednsNS) {
|
|
var err error
|
|
//TODO: do we want to debug log the HTTP server?
|
|
stderrorlog, err := zap.NewStdLogAt(a.Logger.Desugar(), zap.ErrorLevel)
|
|
if err != nil {
|
|
a.errChan <- err
|
|
return
|
|
}
|
|
api := httprouter.New()
|
|
c := cors.New(cors.Options{
|
|
AllowedOrigins: a.Config.API.CorsOrigins,
|
|
AllowedMethods: []string{"GET", "POST"},
|
|
OptionsPassthrough: false,
|
|
Debug: a.Config.General.Debug,
|
|
})
|
|
if a.Config.General.Debug {
|
|
// Logwriter for saner log output
|
|
c.Log = stderrorlog
|
|
}
|
|
if !a.Config.API.DisableRegistration {
|
|
api.POST("/register", a.webRegisterPost)
|
|
}
|
|
api.POST("/update", a.Auth(a.webUpdatePost))
|
|
api.GET("/health", a.healthCheck)
|
|
|
|
host := a.Config.API.IP + ":" + a.Config.API.Port
|
|
|
|
// TLS specific general settings
|
|
cfg := &tls.Config{
|
|
MinVersion: tls.VersionTLS12,
|
|
}
|
|
|
|
switch a.Config.API.TLS {
|
|
case acmedns.ApiTlsProviderLetsEncrypt, acmedns.ApiTlsProviderLetsEncryptStaging:
|
|
magic := a.setupTLS(dnsservers)
|
|
err = magic.ManageAsync(context.Background(), []string{a.Config.General.Domain})
|
|
if err != nil {
|
|
a.errChan <- err
|
|
return
|
|
}
|
|
cfg.GetCertificate = magic.GetCertificate
|
|
srv := &http.Server{
|
|
Addr: host,
|
|
Handler: c.Handler(api),
|
|
TLSConfig: cfg,
|
|
ErrorLog: stderrorlog,
|
|
ReadTimeout: 5 * time.Second,
|
|
WriteTimeout: 10 * time.Second,
|
|
IdleTimeout: 120 * time.Second,
|
|
}
|
|
a.Logger.Infow("Listening HTTPS",
|
|
"host", host,
|
|
"domain", a.Config.General.Domain)
|
|
err = srv.ListenAndServeTLS("", "")
|
|
case acmedns.ApiTlsProviderCert:
|
|
srv := &http.Server{
|
|
Addr: host,
|
|
Handler: c.Handler(api),
|
|
TLSConfig: cfg,
|
|
ErrorLog: stderrorlog,
|
|
ReadTimeout: 5 * time.Second,
|
|
WriteTimeout: 10 * time.Second,
|
|
IdleTimeout: 120 * time.Second,
|
|
}
|
|
a.Logger.Infow("Listening HTTPS",
|
|
"host", host,
|
|
"domain", a.Config.General.Domain)
|
|
err = srv.ListenAndServeTLS(a.Config.API.TLSCertFullchain, a.Config.API.TLSCertPrivkey)
|
|
default:
|
|
a.Logger.Infow("Listening HTTP",
|
|
"host", host)
|
|
err = http.ListenAndServe(host, c.Handler(api))
|
|
}
|
|
if err != nil {
|
|
a.errChan <- err
|
|
}
|
|
}
|
|
|
|
func (a *AcmednsAPI) setupTLS(dnsservers []acmedns.AcmednsNS) *certmagic.Config {
|
|
provider := NewChallengeProvider(dnsservers)
|
|
certmagic.Default.Logger = a.Logger.Desugar()
|
|
storage := certmagic.FileStorage{Path: a.Config.API.ACMECacheDir}
|
|
|
|
// Set up certmagic for getting certificate for acme-dns api
|
|
certmagic.DefaultACME.DNS01Solver = &provider
|
|
certmagic.DefaultACME.Agreed = true
|
|
certmagic.DefaultACME.Logger = a.Logger.Desugar()
|
|
if a.Config.API.TLS == acmedns.ApiTlsProviderLetsEncrypt {
|
|
certmagic.DefaultACME.CA = certmagic.LetsEncryptProductionCA
|
|
} else {
|
|
certmagic.DefaultACME.CA = certmagic.LetsEncryptStagingCA
|
|
}
|
|
certmagic.DefaultACME.Email = a.Config.API.NotificationEmail
|
|
|
|
magicConf := certmagic.Default
|
|
magicConf.Logger = a.Logger.Desugar()
|
|
magicConf.Storage = &storage
|
|
magicConf.DefaultServerName = a.Config.General.Domain
|
|
magicCache := certmagic.NewCache(certmagic.CacheOptions{
|
|
GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
|
|
return &magicConf, nil
|
|
},
|
|
Logger: a.Logger.Desugar(),
|
|
})
|
|
magic := certmagic.New(magicCache, magicConf)
|
|
return magic
|
|
}
|