mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-01 15:39:35 +08:00
fix: #1337
This commit is contained in:
@@ -3,12 +3,15 @@ package internal
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-acme/lego/v5/challenge"
|
||||
"github.com/go-acme/lego/v5/challenge/http01"
|
||||
"github.com/go-acme/lego/v5/log"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/tools/ftp"
|
||||
xfilepath "github.com/certimate-go/certimate/pkg/utils/filepath"
|
||||
)
|
||||
|
||||
var _ challenge.Provider = (*HTTPProvider)(nil)
|
||||
@@ -37,6 +40,10 @@ func NewHTTPProviderConfig(config *Config) (*HTTPProvider, error) {
|
||||
return nil, fmt.Errorf("the configuration of the acme challenge provider is nil")
|
||||
}
|
||||
|
||||
if config.WebRootPath == "" {
|
||||
return nil, fmt.Errorf("ftp: webroot path must be set")
|
||||
}
|
||||
|
||||
return &HTTPProvider{
|
||||
config: config,
|
||||
}, nil
|
||||
@@ -48,10 +55,14 @@ func (p *HTTPProvider) Present(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ftp: failed to create FTP client: %w", err)
|
||||
}
|
||||
|
||||
defer client.Quit()
|
||||
log.Info("ftp: ftp connected")
|
||||
defer func() {
|
||||
client.Quit()
|
||||
log.Info("ftp: ftp closed")
|
||||
}()
|
||||
|
||||
challengePath := filepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengeDir := filepath.Dir(challengePath)
|
||||
challengePath := xfilepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengeDir := xfilepath.Dir(challengePath)
|
||||
challengeFile := filepath.Base(challengePath)
|
||||
if err := client.MkdirAll(ctx, challengeDir); err != nil {
|
||||
return fmt.Errorf("ftp: failed to create the \".well-known\" directory: %w", err)
|
||||
@@ -63,6 +74,8 @@ func (p *HTTPProvider) Present(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ftp: failed to write file for HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("ftp: authz file uploaded", slog.String("path", challengePath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -72,10 +85,14 @@ func (p *HTTPProvider) CleanUp(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ftp: failed to create FTP client: %w", err)
|
||||
}
|
||||
|
||||
defer client.Quit()
|
||||
log.Info("ftp: ftp connected")
|
||||
defer func() {
|
||||
client.Quit()
|
||||
log.Info("ftp: ftp closed")
|
||||
}()
|
||||
|
||||
challengePath := filepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengeDir := filepath.Dir(challengePath)
|
||||
challengePath := xfilepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengeDir := xfilepath.Dir(challengePath)
|
||||
challengeFile := filepath.Base(challengePath)
|
||||
if err := client.ChangeDir(ctx, challengeDir); err != nil {
|
||||
return fmt.Errorf("ftp: failed to change to the \".well-known\" directory: %w", err)
|
||||
@@ -84,6 +101,8 @@ func (p *HTTPProvider) CleanUp(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ftp: failed to remove file after HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("ftp: authz file removed", slog.String("path", challengePath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ func NewChallenger(config *ChallengerConfig) (core.ACMEChallenger, error) {
|
||||
return nil, fmt.Errorf("the configuration of the acme challenge provider is nil")
|
||||
}
|
||||
|
||||
if config.WebRootPath == "" {
|
||||
return nil, fmt.Errorf("local: webroot path must be set")
|
||||
}
|
||||
|
||||
provider, err := webroot.NewHTTPProvider(config.WebRootPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -3,10 +3,12 @@ package internal
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/go-acme/lego/v5/challenge"
|
||||
"github.com/go-acme/lego/v5/challenge/http01"
|
||||
"github.com/go-acme/lego/v5/log"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/tools/s3"
|
||||
)
|
||||
@@ -52,6 +54,8 @@ func (p *HTTPProvider) Present(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("s3: failed to upload file for HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("s3: authz file uploaded", slog.String("bucket", p.config.Bucket), slog.String("object", objectKey))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,6 +70,8 @@ func (p *HTTPProvider) CleanUp(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("s3: failed to remove file after HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("s3: authz file removed", slog.String("bucket", p.config.Bucket), slog.String("object", objectKey))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ package internal
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"log/slog"
|
||||
|
||||
"github.com/go-acme/lego/v5/challenge"
|
||||
"github.com/go-acme/lego/v5/challenge/http01"
|
||||
"github.com/go-acme/lego/v5/log"
|
||||
|
||||
"github.com/certimate-go/certimate/internal/tools/ssh"
|
||||
xfilepath "github.com/certimate-go/certimate/pkg/utils/filepath"
|
||||
xssh "github.com/certimate-go/certimate/pkg/utils/ssh"
|
||||
)
|
||||
|
||||
@@ -25,9 +27,8 @@ func NewDefaultConfig() *Config {
|
||||
defaultCfg := ssh.NewDefaultConfig()
|
||||
|
||||
return &Config{
|
||||
Config: *defaultCfg,
|
||||
UseSCP: false,
|
||||
WebRootPath: "/var/www/html",
|
||||
Config: *defaultCfg,
|
||||
UseSCP: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +41,10 @@ func NewHTTPProviderConfig(config *Config) (*HTTPProvider, error) {
|
||||
return nil, fmt.Errorf("the configuration of the acme challenge provider is nil")
|
||||
}
|
||||
|
||||
if config.WebRootPath == "" {
|
||||
return nil, fmt.Errorf("ssh: webroot path must be set")
|
||||
}
|
||||
|
||||
return &HTTPProvider{
|
||||
config: config,
|
||||
}, nil
|
||||
@@ -51,13 +56,19 @@ func (p *HTTPProvider) Present(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ssh: failed to create SSH client: %w", err)
|
||||
}
|
||||
|
||||
defer client.Close()
|
||||
log.Info("ssh: ssh connected")
|
||||
defer func() {
|
||||
client.Close()
|
||||
log.Info("ssh: ssh closed")
|
||||
}()
|
||||
|
||||
challengePath := filepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengePath := xfilepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
if err := xssh.WriteRemoteString(client.RawClient(), challengePath, keyAuth, p.config.UseSCP); err != nil {
|
||||
return fmt.Errorf("ssh: failed to write file for HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("ssh: authz file uploaded", slog.String("path", challengePath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,14 +78,20 @@ func (p *HTTPProvider) CleanUp(ctx context.Context, domain, token, keyAuth strin
|
||||
return fmt.Errorf("ssh: failed to create SSH client: %w", err)
|
||||
}
|
||||
|
||||
defer client.Close()
|
||||
log.Info("ssh: ssh connected")
|
||||
defer func() {
|
||||
client.Close()
|
||||
log.Info("ssh: ssh closed")
|
||||
}()
|
||||
|
||||
// 删除质询文件
|
||||
challengePath := filepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
challengePath := xfilepath.Join(p.config.WebRootPath, http01.ChallengePath(token))
|
||||
if err := xssh.RemoveRemote(client.RawClient(), challengePath, p.config.UseSCP); err != nil {
|
||||
return fmt.Errorf("ssh: failed to remove file after HTTP challenge: %w", err)
|
||||
}
|
||||
|
||||
log.Info("ssh: authz file removed", slog.String("path", challengePath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ func NewChallenger(config *ChallengerConfig) (core.ACMEChallenger, error) {
|
||||
}
|
||||
providerConfig.JumpServers = append(providerConfig.JumpServers, jumpServerCfg)
|
||||
}
|
||||
providerConfig.WebRootPath = config.WebRootPath
|
||||
|
||||
provider, err := internal.NewHTTPProviderConfig(providerConfig)
|
||||
if err != nil {
|
||||
|
||||
+41
-11
@@ -5,6 +5,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
separatorOnWindows = "\\"
|
||||
separatorOnUnix = "/"
|
||||
)
|
||||
|
||||
// 与标准库中的 [filepath.Dir] 类似,但会尝试保留原有的路径分隔符。
|
||||
//
|
||||
// 入参:
|
||||
@@ -13,21 +18,46 @@ import (
|
||||
// 出参:
|
||||
// - 目录路径。
|
||||
func Dir(path string) string {
|
||||
const SEP_WIN = "\\"
|
||||
const SEP_UNIX = "/"
|
||||
|
||||
sep := SEP_UNIX
|
||||
if strings.Contains(path, SEP_WIN) && !strings.Contains(path, SEP_UNIX) {
|
||||
sep = SEP_WIN
|
||||
sep := string(stdfilepath.Separator)
|
||||
if strings.Contains(path, separatorOnWindows) && !strings.Contains(path, separatorOnUnix) {
|
||||
sep = separatorOnWindows
|
||||
} else if strings.Contains(path, separatorOnUnix) && !strings.Contains(path, separatorOnWindows) {
|
||||
sep = separatorOnUnix
|
||||
}
|
||||
|
||||
dir := stdfilepath.Dir(path)
|
||||
return normalizePath(sep, dir)
|
||||
}
|
||||
|
||||
if sep != SEP_UNIX && strings.Contains(dir, SEP_UNIX) {
|
||||
dir = strings.ReplaceAll(dir, SEP_UNIX, sep)
|
||||
} else if sep != SEP_WIN && strings.Contains(dir, SEP_WIN) {
|
||||
dir = strings.ReplaceAll(dir, SEP_WIN, sep)
|
||||
// 与标准库中的 [filepath.Join] 类似,但会尝试保留原有的路径分隔符。
|
||||
//
|
||||
// 入参:
|
||||
// - elem: 路径元素。
|
||||
//
|
||||
// 出参:
|
||||
// - 连接后的路径。
|
||||
func Join(elem ...string) string {
|
||||
sep := string(stdfilepath.Separator)
|
||||
for _, e := range elem {
|
||||
if strings.Contains(e, separatorOnWindows) && !strings.Contains(e, separatorOnUnix) {
|
||||
sep = separatorOnWindows
|
||||
break
|
||||
} else if strings.Contains(e, separatorOnUnix) && !strings.Contains(e, separatorOnWindows) {
|
||||
sep = separatorOnUnix
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return dir
|
||||
path := stdfilepath.Join(elem...)
|
||||
return normalizePath(sep, path)
|
||||
}
|
||||
|
||||
func normalizePath(separator, path string) string {
|
||||
if separator != separatorOnUnix && strings.Contains(path, separatorOnUnix) {
|
||||
path = strings.ReplaceAll(path, separatorOnUnix, separator)
|
||||
} else if separator != separatorOnWindows && strings.Contains(path, separatorOnWindows) {
|
||||
path = strings.ReplaceAll(path, separatorOnWindows, separator)
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user