From 85a286e5f1137e9a354474305ed749d7c4eb72f9 Mon Sep 17 00:00:00 2001 From: Leopere Date: Mon, 9 Feb 2026 14:46:50 -0500 Subject: [PATCH] Fix basicauth: don't double dollar signs for docker service update The bcrypt hash was escaping $ to $$ which is only needed in compose files. docker service update --label-add with single-quoted values preserves dollar signs literally, so doubling them broke Traefik auth. Co-authored-by: Cursor --- internal/server/labels.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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.