You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang使用Tor SOCKS5代理报错connection reset by peer求助

问题排查与解决方案

先别急,咱们一步步来拆解这个connection reset by peer错误,核心原因大概率是容器内的Tor默认配置限制了外部连接,再加上Tor启动需要初始化时间,才导致你的Go程序请求被拒绝。

1. 修正Tor容器的核心配置

默认的Tor只会监听容器内部的回环地址(127.0.0.1),并且只允许容器本地发起SOCKS连接,宿主机通过端口映射过来的请求会直接被拒绝。我们需要修改配置放开限制:

更新Dockerfile

在你的Dockerfile中添加自定义Tor配置:

FROM alpine:edge
RUN apk update && apk add tor
# 让Tor监听容器所有网卡接口,并允许任意IP的SOCKS连接
RUN echo -e "SocksPort 0.0.0.0:9050\nSocksPolicy accept 0.0.0.0/0" > /etc/tor/torrc
EXPOSE 9050
USER tor
CMD ["/usr/bin/tor"]

重新构建并启动容器

# 先删除旧容器(如果存在)
docker rm -f tor
# 构建新镜像
docker build -t tor-custom .
# 启动容器
docker run --name tor -p 11000:9050 tor-custom

2. 等待Tor完全启动

Tor启动时需要生成加密密钥并完成网络引导,这个过程大概需要30-60秒。你可以通过容器日志确认启动状态:

docker logs tor

当看到日志里出现Bootstrapped 100% (done): Done时,再运行你的Go程序,避免过早发起请求导致连接失败。

3. 修正Go代码的细节问题

第一种代码(访问普通HTTP网站)

你的代码逻辑没问题,但建议延长超时时间(Tor网络速度较慢),并使用更稳定的测试URL:

package main
import (
    "fmt"
    "net/http"
    "net/url"
    "time"
)
func main() {
    proxyUrl, err := url.Parse("socks5://127.0.0.1:11000")
    if err != nil {
        panic(err)
    }
    cl := http.Client{
        Transport: &http.Transport{
            Proxy: http.ProxyURL(proxyUrl),
        },
        Timeout: 30 * time.Second, // 延长超时适配Tor网络
    }
    resp, err := cl.Get("http://example.com/")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    fmt.Println("Response Status:", resp.Status)
}

第二种代码(访问.onion网站)

你的代码缺失了部分依赖包导入,修正后的完整版本:

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "net"
    "net/http"
    "os"

    "golang.org/x/net/proxy"
)

const (
    PROXY_ADDR = "127.0.0.1:11000"
    URL        = "http://facebookcorewwwi.onion"
)

func main() {
    // 创建socks5拨号器
    dialer, err := proxy.SOCKS5("tcp", PROXY_ADDR, nil, proxy.Direct)
    if err != nil {
        fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err)
        os.Exit(1)
    }

    dialContext := func(ctx context.Context, network, address string) (net.Conn, error) {
        return dialer.Dial(network, address)
    }

    // 设置HTTP客户端
    httpTransport := &http.Transport{
        DialContext: dialContext,
    }
    httpClient := &http.Client{
        Transport: httpTransport,
        Timeout:   30 * time.Second, // 延长超时
    }

    // 创建请求
    req, err := http.NewRequest("GET", URL, nil)
    if err != nil {
        fmt.Fprintln(os.Stderr, "can't create request:", err)
        os.Exit(2)
    }

    resp, err := httpClient.Do(req)
    if err != nil {
        fmt.Fprintln(os.Stderr, "cannot make get request: ", err)
        os.Exit(2)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Fprintln(os.Stderr, "cannot read response body: ", err)
        os.Exit(2)
    }

    fmt.Println("received response length:", len(body))
    fmt.Println("response preview:", string(body[:100])) // 只打印前100个字符避免输出过长
}

额外验证步骤

如果还是有问题,先用curl测试代理是否正常:

curl -x socks5://127.0.0.1:11000 http://example.com/

如果curl能正常返回内容,说明代理没问题,再检查Go代码的细节即可。

内容的提问来源于stack exchange,提问作者aquaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:12:51