diff --git a/backend/internal/pkg/tlsfingerprint/dialer.go b/backend/internal/pkg/tlsfingerprint/dialer.go index c8d8369f..cc78cd14 100644 --- a/backend/internal/pkg/tlsfingerprint/dialer.go +++ b/backend/internal/pkg/tlsfingerprint/dialer.go @@ -160,7 +160,11 @@ func (d *SOCKS5ProxyDialer) DialTLSContext(ctx context.Context, network, addr st proxyAddr = net.JoinHostPort(d.proxyURL.Hostname(), "1080") // Default SOCKS5 port } - socksDialer, err := proxy.SOCKS5("tcp", proxyAddr, auth, proxy.Direct) + // Use a TCP-only forward dialer (no DNS resolution) so the SOCKS5 protocol + // sends the target hostname to the proxy for remote DNS resolution (socks5h semantics). + // proxy.Direct would attempt local DNS first, which fails inside Docker. + tcpDialer := &net.Dialer{} + socksDialer, err := proxy.SOCKS5("tcp", proxyAddr, auth, tcpDialer) if err != nil { slog.Debug("tls_fingerprint_socks5_dialer_failed", "error", err) return nil, fmt.Errorf("create SOCKS5 dialer: %w", err) @@ -168,7 +172,7 @@ func (d *SOCKS5ProxyDialer) DialTLSContext(ctx context.Context, network, addr st // Step 2: Establish SOCKS5 tunnel to target slog.Debug("tls_fingerprint_socks5_establishing_tunnel", "target", addr) - conn, err := socksDialer.Dial("tcp", addr) + conn, err := socksDialer.(proxy.ContextDialer).DialContext(ctx, "tcp", addr) if err != nil { slog.Debug("tls_fingerprint_socks5_connect_failed", "error", err) return nil, fmt.Errorf("SOCKS5 connect: %w", err) diff --git a/backend/internal/repository/claude_oauth_service.go b/backend/internal/repository/claude_oauth_service.go index c27150ed..72bcbd81 100644 --- a/backend/internal/repository/claude_oauth_service.go +++ b/backend/internal/repository/claude_oauth_service.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "net/http" "net/url" "strings" @@ -287,11 +288,9 @@ func createReqClient(proxyURL string) (*req.Client, error) { return nil, err } - logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: proxyURL=%q trimmed=%q", logredact.RedactProxyURL(proxyURL), logredact.RedactProxyURL(trimmed)) - if trimmed != "" && parsedProxy != nil { scheme := strings.ToLower(parsedProxy.Scheme) - logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: using proxy scheme=%s host=%s", scheme, parsedProxy.Hostname()) + slog.Info("oauth_create_client", "proxy_scheme", scheme, "proxy_host", parsedProxy.Hostname()) switch scheme { case "socks5", "socks5h": socks5Dialer := tlsfingerprint.NewSOCKS5ProxyDialer(profile, parsedProxy) @@ -303,7 +302,7 @@ func createReqClient(proxyURL string) (*req.Client, error) { client.SetProxyURL(trimmed) } } else { - logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: no proxy, using direct connection with utls") + slog.Info("oauth_create_client", "proxy_scheme", "none", "raw_proxy_url", proxyURL) dialer := tlsfingerprint.NewDialer(profile, nil) client.SetDialTLS(dialer.DialTLSContext) }