Compare commits
3 Commits
v1.2.1
...
registry-a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ff610f5af | ||
|
|
7534c64197 | ||
|
|
5928a0a9e4 |
5
.github/workflows/docker-ghcr.yml
vendored
5
.github/workflows/docker-ghcr.yml
vendored
@@ -52,10 +52,9 @@ jobs:
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
docker buildx build --push \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--platform linux/amd64 \
|
||||
--tag ghcr.io/${{ env.REPO_LOWER }}:${{ env.VERSION }} \
|
||||
--tag ghcr.io/${{ env.REPO_LOWER }}:latest \
|
||||
--build-arg VERSION=${{ env.VERSION }} \
|
||||
-f Dockerfile .
|
||||
env:
|
||||
GHCR_PUBLIC: true
|
||||
GHCR_PUBLIC: true
|
||||
|
||||
@@ -83,6 +83,12 @@ authHost = "registry.k8s.io"
|
||||
authType = "anonymous"
|
||||
enabled = true
|
||||
|
||||
# Default Registry
|
||||
[defaultRegistry]
|
||||
upstream = "registry-1.docker.io"
|
||||
authHost = "auth.docker.io"
|
||||
enabled = true
|
||||
|
||||
[tokenCache]
|
||||
# 是否启用缓存(同时控制Token和Manifest缓存)显著提升性能
|
||||
enabled = true
|
||||
|
||||
@@ -49,6 +49,8 @@ type AppConfig struct {
|
||||
} `toml:"download"`
|
||||
|
||||
Registries map[string]RegistryMapping `toml:"registries"`
|
||||
|
||||
DefaultRegistry RegistryMapping `toml:"defaultRegistry"`
|
||||
|
||||
TokenCache struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -16,6 +17,8 @@ import (
|
||||
"hubproxy/utils"
|
||||
)
|
||||
|
||||
var realmRegex = regexp.MustCompile(`realm="(https?://)([^/"]+)(/?[^"]*)"`)
|
||||
|
||||
// DockerProxy Docker代理配置
|
||||
type DockerProxy struct {
|
||||
registry name.Registry
|
||||
@@ -68,7 +71,13 @@ var registryDetector = &RegistryDetector{}
|
||||
|
||||
// InitDockerProxy 初始化Docker代理
|
||||
func InitDockerProxy() {
|
||||
registry, err := name.NewRegistry("registry-1.docker.io")
|
||||
cfg := config.GetConfig()
|
||||
upstream := "registry-1.docker.io"
|
||||
if cfg.DefaultRegistry.Upstream != "" {
|
||||
upstream = cfg.DefaultRegistry.Upstream
|
||||
}
|
||||
|
||||
registry, err := name.NewRegistry(upstream)
|
||||
if err != nil {
|
||||
fmt.Printf("创建Docker registry失败: %v\n", err)
|
||||
return
|
||||
@@ -353,17 +362,21 @@ func (r *ResponseRecorder) Write(data []byte) (int, error) {
|
||||
}
|
||||
|
||||
func proxyDockerAuthOriginal(c *gin.Context) {
|
||||
var authURL string
|
||||
cfg := config.GetConfig()
|
||||
|
||||
authHost := "auth.docker.io"
|
||||
if cfg.DefaultRegistry.AuthHost != "" {
|
||||
authHost = cfg.DefaultRegistry.AuthHost
|
||||
}
|
||||
|
||||
if targetDomain, exists := c.Get("target_registry_domain"); exists {
|
||||
if mapping, found := registryDetector.getRegistryMapping(targetDomain.(string)); found {
|
||||
authURL = "https://" + mapping.AuthHost + c.Request.URL.Path
|
||||
} else {
|
||||
authURL = "https://auth.docker.io" + c.Request.URL.Path
|
||||
authHost = mapping.AuthHost
|
||||
}
|
||||
} else {
|
||||
authURL = "https://auth.docker.io" + c.Request.URL.Path
|
||||
}
|
||||
|
||||
authURL := "https://" + authHost + c.Request.URL.Path
|
||||
|
||||
if c.Request.URL.RawQuery != "" {
|
||||
authURL += "?" + c.Request.URL.RawQuery
|
||||
}
|
||||
@@ -406,10 +419,15 @@ func proxyDockerAuthOriginal(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
scheme := "http"
|
||||
if c.Request.TLS != nil || c.GetHeader("X-Forwarded-Proto") == "https" {
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
for key, values := range resp.Header {
|
||||
for _, value := range values {
|
||||
if key == "Www-Authenticate" {
|
||||
value = rewriteAuthHeader(value, proxyHost)
|
||||
value = rewriteAuthHeader(value, scheme, proxyHost)
|
||||
}
|
||||
c.Header(key, value)
|
||||
}
|
||||
@@ -420,13 +438,8 @@ func proxyDockerAuthOriginal(c *gin.Context) {
|
||||
}
|
||||
|
||||
// rewriteAuthHeader 重写认证头
|
||||
func rewriteAuthHeader(authHeader, proxyHost string) string {
|
||||
authHeader = strings.ReplaceAll(authHeader, "https://auth.docker.io", "http://"+proxyHost)
|
||||
authHeader = strings.ReplaceAll(authHeader, "https://ghcr.io", "http://"+proxyHost)
|
||||
authHeader = strings.ReplaceAll(authHeader, "https://gcr.io", "http://"+proxyHost)
|
||||
authHeader = strings.ReplaceAll(authHeader, "https://quay.io", "http://"+proxyHost)
|
||||
|
||||
return authHeader
|
||||
func rewriteAuthHeader(authHeader, scheme, proxyHost string) string {
|
||||
return realmRegex.ReplaceAllString(authHeader, fmt.Sprintf(`realm="%s://%s$3"`, scheme, proxyHost))
|
||||
}
|
||||
|
||||
// handleMultiRegistryRequest 处理多Registry请求
|
||||
@@ -605,12 +618,5 @@ func createUpstreamOptions(mapping config.RegistryMapping) []remote.Option {
|
||||
remote.WithTransport(utils.GetGlobalHTTPClient().Transport),
|
||||
}
|
||||
|
||||
// 预留将来不同Registry的差异化认证逻辑扩展点
|
||||
switch mapping.AuthType {
|
||||
case "github":
|
||||
case "google":
|
||||
case "quay":
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user