mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-03 06:07:20 +02:00
Restructured log format in acme module
- Replaced all log.Println in acme module to system wide logger - Fixed file manager path escape bug #274
This commit is contained in:
parent
a5ef6456c6
commit
a7f89086d4
@ -38,7 +38,7 @@ func initACME() *acme.ACMEHandler {
|
||||
port = getRandomPort(30000)
|
||||
}
|
||||
|
||||
return acme.NewACME("https://acme-v02.api.letsencrypt.org/directory", strconv.Itoa(port), sysdb)
|
||||
return acme.NewACME("https://acme-v02.api.letsencrypt.org/directory", strconv.Itoa(port), sysdb, SystemWideLogger)
|
||||
}
|
||||
|
||||
// create the special routing rule for ACME
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -26,6 +25,7 @@ import (
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
"imuslab.com/zoraxy/mod/database"
|
||||
"imuslab.com/zoraxy/mod/info/logger"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
@ -68,25 +68,31 @@ type ACMEHandler struct {
|
||||
DefaultAcmeServer string
|
||||
Port string
|
||||
Database *database.Database
|
||||
Logger *logger.Logger
|
||||
}
|
||||
|
||||
// NewACME creates a new ACMEHandler instance.
|
||||
func NewACME(acmeServer string, port string, database *database.Database) *ACMEHandler {
|
||||
func NewACME(defaultAcmeServer string, port string, database *database.Database, logger *logger.Logger) *ACMEHandler {
|
||||
return &ACMEHandler{
|
||||
DefaultAcmeServer: acmeServer,
|
||||
DefaultAcmeServer: defaultAcmeServer,
|
||||
Port: port,
|
||||
Database: database,
|
||||
Logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *ACMEHandler) Logf(message string, err error) {
|
||||
a.Logger.PrintAndLog("ACME", message, err)
|
||||
}
|
||||
|
||||
// ObtainCert obtains a certificate for the specified domains.
|
||||
func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string, skipTLS bool, useDNS bool) (bool, error) {
|
||||
log.Println("[ACME] Obtaining certificate...")
|
||||
a.Logf("Obtaining certificate for: "+strings.Join(domains, ", "), nil)
|
||||
|
||||
// generate private key
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Private key generation failed", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -102,7 +108,7 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
// skip TLS verify if need
|
||||
// Ref: https://github.com/go-acme/lego/blob/6af2c756ac73a9cb401621afca722d0f4112b1b8/lego/client_config.go#L74
|
||||
if skipTLS {
|
||||
log.Println("[INFO] Ignore TLS/SSL Verification Error for ACME Server")
|
||||
a.Logf("Ignoring TLS/SSL Verification Error for ACME Server", nil)
|
||||
config.HTTPClient.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
@ -129,16 +135,16 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
|
||||
// if not custom ACME url, load it from ca.json
|
||||
if caName == "custom" {
|
||||
log.Println("[INFO] Using Custom ACME " + caUrl + " for CA Directory URL")
|
||||
a.Logf("Using Custom ACME "+caUrl+" for CA Directory URL", nil)
|
||||
} else {
|
||||
caLinkOverwrite, err := loadCAApiServerFromName(caName)
|
||||
if err == nil {
|
||||
config.CADirURL = caLinkOverwrite
|
||||
log.Println("[INFO] Using " + caLinkOverwrite + " for CA Directory URL")
|
||||
a.Logf("Using "+caLinkOverwrite+" for CA Directory URL", nil)
|
||||
} else {
|
||||
// (caName == "" || caUrl == "") will use default acme
|
||||
config.CADirURL = a.DefaultAcmeServer
|
||||
log.Println("[INFO] Using Default ACME " + a.DefaultAcmeServer + " for CA Directory URL")
|
||||
a.Logf("[INFO] Using Default ACME "+a.DefaultAcmeServer+" for CA Directory URL", nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +152,7 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to spawn new ACME client from current config", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -164,32 +170,32 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
var dnsCredentials string
|
||||
err := a.Database.Read("acme", certificateName+"_dns_credentials", &dnsCredentials)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Read DNS credential failed", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
var dnsProvider string
|
||||
err = a.Database.Read("acme", certificateName+"_dns_provider", &dnsProvider)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Read DNS Provider failed", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
provider, err := GetDnsChallengeProviderByName(dnsProvider, dnsCredentials)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Unable to resolve DNS challenge provider", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = client.Challenge.SetDNS01Provider(provider)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to resolve DNS01 Provider", err)
|
||||
return false, err
|
||||
}
|
||||
} else {
|
||||
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", a.Port))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to resolve HTTP01 Provider", err)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@ -205,7 +211,7 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
var reg *registration.Resource
|
||||
// New users will need to register
|
||||
if client.GetExternalAccountRequired() {
|
||||
log.Println("External Account Required for this ACME Provider.")
|
||||
a.Logf("External Account Required for this ACME Provider", nil)
|
||||
// IF KID and HmacEncoded is overidden
|
||||
|
||||
if !a.Database.TableExists("acme") {
|
||||
@ -220,20 +226,18 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
var kid string
|
||||
var hmacEncoded string
|
||||
err := a.Database.Read("acme", config.CADirURL+"_kid", &kid)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to read kid from database", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = a.Database.Read("acme", config.CADirURL+"_hmacEncoded", &hmacEncoded)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to read HMAC from database", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
log.Println("EAB Credential retrieved.", kid, hmacEncoded)
|
||||
a.Logf("EAB Credential retrieved: "+kid+" / "+hmacEncoded, nil)
|
||||
if kid != "" && hmacEncoded != "" {
|
||||
reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{
|
||||
TermsOfServiceAgreed: true,
|
||||
@ -242,14 +246,14 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Register with external account binder failed", err)
|
||||
return false, err
|
||||
}
|
||||
//return false, errors.New("External Account Required for this ACME Provider.")
|
||||
} else {
|
||||
reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Unable to register client", err)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@ -262,7 +266,7 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
}
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Obtain certificate failed", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -270,12 +274,12 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
// private key, and a certificate URL.
|
||||
err = os.WriteFile("./conf/certs/"+certificateName+".pem", certificates.Certificate, 0777)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to write public key to disk", err)
|
||||
return false, err
|
||||
}
|
||||
err = os.WriteFile("./conf/certs/"+certificateName+".key", certificates.PrivateKey, 0777)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to write private key to disk", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -289,13 +293,13 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
|
||||
certInfoBytes, err := json.Marshal(certInfo)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Marshal certificate renew config failed", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = os.WriteFile("./conf/certs/"+certificateName+".json", certInfoBytes, 0777)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to write certificate renew config to file", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -313,7 +317,7 @@ func (a *ACMEHandler) CheckCertificate() []string {
|
||||
expiredCerts := []string{}
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
a.Logf("Failed to load certificate folder", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@ -410,14 +414,14 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
ca, err := utils.PostPara(r, "ca")
|
||||
if err != nil {
|
||||
log.Println("[INFO] CA not set. Using default")
|
||||
a.Logf("CA not set. Using default", nil)
|
||||
ca, caUrl = "", ""
|
||||
}
|
||||
|
||||
if ca == "custom" {
|
||||
caUrl, err = utils.PostPara(r, "caURL")
|
||||
if err != nil {
|
||||
log.Println("[INFO] Custom CA set but no URL provide, Using default")
|
||||
a.Logf("Custom CA set but no URL provide, Using default", nil)
|
||||
ca, caUrl = "", ""
|
||||
}
|
||||
}
|
||||
@ -465,7 +469,7 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ
|
||||
func jsonEscape(i string) string {
|
||||
b, err := json.Marshal(i)
|
||||
if err != nil {
|
||||
log.Println("Unable to escape json data: " + err.Error())
|
||||
//log.Println("Unable to escape json data: " + err.Error())
|
||||
return i
|
||||
}
|
||||
s := string(b)
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"os"
|
||||
@ -12,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"imuslab.com/zoraxy/mod/info/logger"
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
@ -36,6 +36,7 @@ type AutoRenewer struct {
|
||||
RenewTickInterval int64
|
||||
EarlyRenewDays int //How many days before cert expire to renew certificate
|
||||
TickerstopChan chan bool
|
||||
Logger *logger.Logger //System wide logger
|
||||
}
|
||||
|
||||
type ExpiredCerts struct {
|
||||
@ -45,7 +46,7 @@ type ExpiredCerts struct {
|
||||
|
||||
// Create an auto renew agent, require config filepath and auto scan & renew interval (seconds)
|
||||
// Set renew check interval to 0 for auto (1 day)
|
||||
func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64, earlyRenewDays int, AcmeHandler *ACMEHandler) (*AutoRenewer, error) {
|
||||
func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64, earlyRenewDays int, AcmeHandler *ACMEHandler, logger *logger.Logger) (*AutoRenewer, error) {
|
||||
if renewCheckInterval == 0 {
|
||||
renewCheckInterval = 86400 //1 day
|
||||
}
|
||||
@ -87,6 +88,7 @@ func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64,
|
||||
AcmeHandler: AcmeHandler,
|
||||
RenewerConfig: &renewerConfig,
|
||||
RenewTickInterval: renewCheckInterval,
|
||||
Logger: logger,
|
||||
}
|
||||
|
||||
if thisRenewer.RenewerConfig.Enabled {
|
||||
@ -100,6 +102,10 @@ func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64,
|
||||
return &thisRenewer, nil
|
||||
}
|
||||
|
||||
func (a *AutoRenewer) Logf(message string, err error) {
|
||||
a.Logger.PrintAndLog("CertRenew", message, err)
|
||||
}
|
||||
|
||||
func (a *AutoRenewer) StartAutoRenewTicker() {
|
||||
//Stop the previous ticker if still running
|
||||
if a.TickerstopChan != nil {
|
||||
@ -118,7 +124,7 @@ func (a *AutoRenewer) StartAutoRenewTicker() {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
log.Println("Check and renew certificates in progress")
|
||||
a.Logf("Check and renew certificates in progress", nil)
|
||||
a.CheckAndRenewCertificates()
|
||||
}
|
||||
}
|
||||
@ -233,12 +239,12 @@ func (a *AutoRenewer) HandleAutoRenewEnable(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
a.RenewerConfig.Enabled = true
|
||||
a.saveRenewConfigToFile()
|
||||
log.Println("[ACME] ACME auto renew enabled")
|
||||
a.Logf("ACME auto renew enabled", nil)
|
||||
a.StartAutoRenewTicker()
|
||||
} else {
|
||||
a.RenewerConfig.Enabled = false
|
||||
a.saveRenewConfigToFile()
|
||||
log.Println("[ACME] ACME auto renew disabled")
|
||||
a.Logf("ACME auto renew disabled", nil)
|
||||
a.StopAutoRenewTicker()
|
||||
}
|
||||
} else {
|
||||
@ -283,7 +289,7 @@ func (a *AutoRenewer) CheckAndRenewCertificates() ([]string, error) {
|
||||
certFolder := a.CertFolder
|
||||
files, err := os.ReadDir(certFolder)
|
||||
if err != nil {
|
||||
log.Println("Unable to renew certificates: " + err.Error())
|
||||
a.Logf("Read certificate store failed", err)
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
@ -303,7 +309,7 @@ func (a *AutoRenewer) CheckAndRenewCertificates() ([]string, error) {
|
||||
DNSName, err := ExtractDomains(certBytes)
|
||||
if err != nil {
|
||||
//Maybe self signed. Ignore this
|
||||
log.Println("Encounted error when trying to resolve DNS name for cert " + file.Name())
|
||||
a.Logf("Encounted error when trying to resolve DNS name for cert "+file.Name(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -327,11 +333,10 @@ func (a *AutoRenewer) CheckAndRenewCertificates() ([]string, error) {
|
||||
}
|
||||
if CertExpireSoon(certBytes, a.EarlyRenewDays) || CertIsExpired(certBytes) {
|
||||
//This cert is expired
|
||||
|
||||
DNSName, err := ExtractDomains(certBytes)
|
||||
if err != nil {
|
||||
//Maybe self signed. Ignore this
|
||||
log.Println("Encounted error when trying to resolve DNS name for cert " + file.Name())
|
||||
a.Logf("Encounted error when trying to resolve DNS name for cert "+file.Name(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -358,7 +363,7 @@ func (a *AutoRenewer) Close() {
|
||||
func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, error) {
|
||||
renewedCertFiles := []string{}
|
||||
for _, expiredCert := range certs {
|
||||
log.Println("Renewing " + expiredCert.Filepath + " (Might take a few minutes)")
|
||||
a.Logf("Renewing "+expiredCert.Filepath+" (Might take a few minutes)", nil)
|
||||
fileName := filepath.Base(expiredCert.Filepath)
|
||||
certName := fileName[:len(fileName)-len(filepath.Ext(fileName))]
|
||||
|
||||
@ -366,10 +371,10 @@ func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, erro
|
||||
certInfoFilename := fmt.Sprintf("%s/%s.json", filepath.Dir(expiredCert.Filepath), certName)
|
||||
certInfo, err := LoadCertInfoJSON(certInfoFilename)
|
||||
if err != nil {
|
||||
log.Printf("Renew %s certificate error, can't get the ACME detail for cert: %v, trying org section as ca", certName, err)
|
||||
a.Logf("Renew "+certName+"certificate error, can't get the ACME detail for certificate, trying org section as ca", err)
|
||||
|
||||
if CAName, extractErr := ExtractIssuerNameFromPEM(expiredCert.Filepath); extractErr != nil {
|
||||
log.Printf("extract issuer name for cert error: %v, using default ca", extractErr)
|
||||
a.Logf("Extract issuer name for cert error, using default ca", err)
|
||||
certInfo = &CertificateInfoJSON{}
|
||||
} else {
|
||||
certInfo = &CertificateInfoJSON{AcmeName: CAName}
|
||||
@ -378,9 +383,9 @@ func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, erro
|
||||
|
||||
_, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl, certInfo.SkipTLS, certInfo.UseDNS)
|
||||
if err != nil {
|
||||
log.Println("Renew " + fileName + "(" + strings.Join(expiredCert.Domains, ",") + ") failed: " + err.Error())
|
||||
a.Logf("Renew "+fileName+"("+strings.Join(expiredCert.Domains, ",")+") failed", err)
|
||||
} else {
|
||||
log.Println("Successfully renewed " + filepath.Base(expiredCert.Filepath))
|
||||
a.Logf("Successfully renewed "+filepath.Base(expiredCert.Filepath), nil)
|
||||
renewedCertFiles = append(renewedCertFiles, filepath.Base(expiredCert.Filepath))
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ func (this *defaultDialer) Dial(address string) Socket {
|
||||
if socket, err := net.DialTimeout("tcp", address, this.timeout); err == nil {
|
||||
return socket
|
||||
} else {
|
||||
this.logger.Printf("[INFO] Unable to establish connection to [%s]: %s", address, err)
|
||||
this.logger.Printf("Unable to establish connection to [%s]: %s", address, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -17,7 +17,7 @@ func (this *loggingInitializer) Initialize(client, server Socket) bool {
|
||||
result := this.inner.Initialize(client, server)
|
||||
|
||||
if !result {
|
||||
this.logger.Printf("[INFO] Connection failed [%s] -> [%s]", client.RemoteAddr(), server.RemoteAddr())
|
||||
this.logger.Printf("Connection failed [%s] -> [%s]", client.RemoteAddr(), server.RemoteAddr())
|
||||
}
|
||||
|
||||
return result
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"embed"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -185,7 +184,6 @@ func (m *Manager) GetCert(helloInfo *tls.ClientHelloInfo) (*tls.Certificate, err
|
||||
//Load the cert and serve it
|
||||
cer, err := tls.LoadX509KeyPair(pubKey, priKey)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package uptime
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"strconv"
|
||||
@ -242,7 +241,7 @@ func getWebsiteStatus(url string) (int, error) {
|
||||
// Create a one-time use cookie jar to store cookies
|
||||
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
|
@ -44,7 +44,9 @@ func (fm *FileManager) HandleList(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Clean path to prevent path escape #274
|
||||
targetDir = filepath.ToSlash(filepath.Clean(targetDir))
|
||||
targetDir = strings.ReplaceAll(targetDir, "../", "")
|
||||
for strings.Contains(targetDir, "../") {
|
||||
targetDir = strings.ReplaceAll(targetDir, "../", "")
|
||||
}
|
||||
|
||||
// Open the target directory
|
||||
dirEntries, err := os.ReadDir(targetDir)
|
||||
|
@ -285,6 +285,7 @@ func startupSequence() {
|
||||
int64(*acmeAutoRenewInterval),
|
||||
*acmeCertAutoRenewDays,
|
||||
acmeHandler,
|
||||
SystemWideLogger,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user