TypechoJoeTheme

至尊技术网

登录
用户名
密码

基于域名的透明反向代理实现(Go语言)

2025-12-01
/
0 评论
/
1 阅读
/
正在检测是否收录...
12/01

go
type DomainConfig struct {
Domain string
BackendURL string
}

var domainMap = map[string]*url.URL{
"blog.example.com": parseURL("http://127.0.0.1:8081"),
"shop.example.com": parseURL("http://127.0.0.1:8082"),
"api.example.com": parseURL("http://127.0.0.1:8083"),
}

其中parseURL是一个辅助函数,封装了url.Parse的错误处理。每当收到请求时,程序提取请求头中的Host字段,查找对应的后端地址。若未匹配,则返回404或默认站点。

构建透明代理处理器

关键在于自定义ReverseProxyDirector函数。这个函数控制如何修改出站请求。我们的目标是尽可能保留原始请求特征:

go
func newTransparentProxy(target *url.URL) *httputil.ReverseProxy {
return &httputil.ReverseProxy{
Director: func(req *http.Request) {
// 重写请求的目标地址
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)

        // 设置必要的转发头
        if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
            if prior, ok := req.Header["X-Forwarded-For"]; ok {
                clientIP = strings.Join(prior, ", ") + ", " + clientIP
            }
            req.Header.Set("X-Forwarded-For", clientIP)
        }
        req.Header.Set("X-Forwarded-Proto", req.Header.Get("X-Forwarded-Proto"))
        req.Header.Set("X-Real-IP", clientIP)

        // 清除可能干扰后端的代理头
        if _, ok := req.Header["User-Agent"]; !ok {
            req.Header.Set("User-Agent", "")
        }
    },
    Transport: &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    },
}

}

这里特别注意对X-Forwarded-For的拼接处理——这是为了在多层代理环境下仍能追踪原始客户端IP。同时跳过TLS验证是为了支持后端自签名证书(生产环境应谨慎使用)。

支持HTTPS透明代理

仅处理HTTP不足以满足现代需求。许多网站已全面启用HTTPS。为此,我们需要让代理支持TLS终止或透传。若希望代理本身提供SSL服务,可通过ListenAndServeTLS加载证书:

go go func() { log.Println("Starting HTTPS server on :443") if err := http.ListenAndServeTLS(":443", "cert.pem", "key.pem", mux); err != nil { log.Fatalf("HTTPS server failed: %v", err) } }()

而对于SNI(Server Name Indication)场景,可结合crypto/tlsGetConfigForClient实现动态证书加载,根据不同域名返回对应证书,从而在同一IP上托管多个HTTPS站点。

动态路由与中间件扩展

为增强灵活性,可引入中间件机制。例如添加日志记录、访问控制、速率限制等功能:

go func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) log.Printf("%s %s %s %v", r.RemoteAddr, r.Method, r.URL.Path, time.Since(start)) }) }

将此类中间件叠加在主路由之上,既能保持核心逻辑简洁,又便于功能扩展。

性能与稳定性考量

Go的Goroutine模型天然适合高并发场景。每个请求由独立Goroutine处理,无需担心阻塞问题。但需注意连接池管理。通过配置TransportMaxIdleConnsIdleConnTimeout等参数,可有效复用后端连接,减少握手开销。

此外,建议加入健康检查机制,定期探测后端服务可用性,并在故障时切换或返回友好提示,避免雪崩效应。

实际部署建议

在生产环境中,该代理可部署在Nginx之前作为动态路由层,或直接暴露在公网前端。配合Let's Encrypt自动化证书更新,能够实现全自动、免运维的多域名代理服务。

代码结构上建议分离配置加载、路由注册、服务启动等模块,提升可测试性与维护性。未来还可接入etcd或Consul实现配置热更新,进一步提升系统弹性。

朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/40015/(转载时请注明本文出处及文章链接)

评论 (0)

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月

最新回复

  1. 强强强
    2025-04-07
  2. jesse
    2025-01-16
  3. sowxkkxwwk
    2024-11-20
  4. zpzscldkea
    2024-11-20
  5. bruvoaaiju
    2024-11-14

标签云