diff --git a/internal/server/labels.go b/internal/server/labels.go index 4c5c10a..bb9cd83 100644 --- a/internal/server/labels.go +++ b/internal/server/labels.go @@ -161,15 +161,15 @@ func (lm *LabelManager) Remove(tunKey string) error { } // generateHTPasswd creates a bcrypt-hashed htpasswd entry for Traefik basicauth. -// The output format is user:$$hash (with $ escaped for Docker label values). +// The output format is user:$hash. Dollar signs are NOT doubled here because +// we pass labels via docker service update with single-quoted values, which +// preserves them literally. Doubling is only needed in compose files. func generateHTPasswd(user, pass string) (string, error) { hash, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost) if err != nil { return "", fmt.Errorf("bcrypt hash: %w", err) } - // Traefik in Docker labels requires dollar signs to be doubled. - escaped := strings.ReplaceAll(string(hash), "$", "$$") - return fmt.Sprintf("%s:%s", user, escaped), nil + return fmt.Sprintf("%s:%s", user, string(hash)), nil } // labelFlag formats a --label-add value, quoting properly for shell.