防DDOS攻击 防DDOS攻击


经典解决方案

让防御节点正确透传用户IP并在Go服务中安全读取,具体方法

发布于:2025-09-08 12:56来源:网络 作者:小编 点击:

让防御节点正确透传用户IP并在Go服务中安全读取,具体方法如下:

 

一、核心解决步骤:配置防御节点透传用户真实IP

 

这是前提,需先让防御节点在转发请求时,将用户源IP写入 X-Forwarded-For  X-Real-IP 请求头,再传递给你的Go服务。

配置路径类似,通用流程如下:

 

1. 确认透传的请求头字段(推荐同时启用 X-Forwarded-For  X-Real-IP ,兼容性更强)。

 

二、Go服务端读取真实IP(配置防御节点后操作)

 

防御节点配置完成后,Go服务可通过标准库 net/http 读取请求头中的IP,代码示例如下:

 

1. 直接读取指定请求头

 

适用于已确认防御节点仅透传单个字段(如 X-Real-IP )的场景:

 

go   

package main

 

import (

    "fmt"

    "net/http"

)

 

func main() {

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        // 1. 优先读取X-Real-IP(部分防御节点用此字段)

        realIP := r.Header.Get("X-Real-IP")

        if realIP == "" {

            // 2. X-Real-IP为空,读取X-Forwarded-For(多个IP时取第一个,即用户源IP

            realIP = r.Header.Get("X-Forwarded-For")

        }

        // 3. 若仍为空, fallback 到请求的远程地址(此时是防御节点IP

        if realIP == "" {

            realIP = r.RemoteAddr

        }

        fmt.Fprintf(w, "用户真实IP: %s", realIP)

    })

    http.ListenAndServe(":8080", nil)

}

 

 

2. 处理 X-Forwarded-For IP场景

 

 X-Forwarded-For 格式通常为 用户IP, 防御节点IP1, 防御节点IP2 ,需提取第一个IP作为用户源IP

 

go   

import "strings"

 

func getRealIP(r *http.Request) string {

    // 处理X-Forwarded-For,分割后取第一个非空IP

    xff := r.Header.Get("X-Forwarded-For")

    if xff != "" {

        // 按逗号分割,取第一个IP并去除空格

        ips := strings.Split(strings.TrimSpace(xff), ",")

        if len(ips) > 0 {

            return strings.TrimSpace(ips[0])

        }

    }

    //  fallback X-Real-IPRemoteAddr

    if realIP := r.Header.Get("X-Real-IP"); realIP != "" {

        return realIP

    }

    return r.RemoteAddr

}

 

 

三、关键注意事项:过滤伪造IP(安全必做)

 

直接信任请求头存在风险(客户端可能伪造 X-Forwarded-For ),必须仅信任防御节点IP传递的请求头,步骤如下:

 

1. 从防御节点厂商获取其回源IP段列表(如阿里云安全回源IP段)。

2. Go服务中添加校验:仅当请求的 RemoteAddr (即防御节点IP)在官方IP段内时,才读取 X-Forwarded-For / X-Real-IP ,否则直接拒绝或使用 RemoteAddr 

 

示例代码(简化版IP段校验):

 

go   

// 假设已从防御节点厂商获取的回源IP段(示例,需替换为真实IP段)

var defenseNodeIPRanges = []string{"103.232.110.0/22", "180.101.49.0/24"}

 

// 校验IP是否在防御节点回源IP段内(实际需用net包解析CIDR

func isDefenseNodeIP(ip string) bool {

    // 真实场景需用github.com/icza/netx等库解析CIDR并校验,此处简化逻辑

    for _, cidr := range defenseNodeIPRanges {

        if strings.Contains(cidr, ip[:strings.LastIndex(ip, ".")]) {

            return true

        }

    }

    return false

}

 

func getSafeRealIP(r *http.Request) string {

    // 1. 先获取请求的远程IP(防御节点IP

    defenseIP := strings.Split(r.RemoteAddr, ":")[0] // 提取IP(去除端口)

    // 2. 仅信任防御节点IP传递的请求头

    if isDefenseNodeIP(defenseIP) {

        if xff := r.Header.Get("X-Forwarded-For"); xff != "" {

            return strings.TrimSpace(strings.Split(xff, ",")[0])

        }

        if realIP := r.Header.Get("X-Real-IP"); realIP != "" {

            return realIP

        }

    }

    // 非防御节点请求,直接返回远程IP(可能是客户端IP或恶意请求)

    return defenseIP

}

 

 

四、排查步骤(若配置后仍无法获取)

 

1. 验证防御节点是否透传头:用 curl 模拟防御节点请求(或通过防御节点日志),检查请求是否携带 X-Forwarded-For / X-Real-IP 

示例: curl -H "X-Forwarded-For: 21.23.44.78" http://你的域名 ,在Go服务中打印 r.Header 确认头是否存在。

2. 检查Go服务是否被反向代理二次拦截:若Go服务前还有Nginx等反向代理,需确保Nginx也配置了转发请求头(如 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; )。

3. 确认防御节点配置生效:部分防御节点需清空缓存或等待配置同步,可通过更换设备访问(避免本地缓存)测试。

 

总结:核心是先让防御节点正确透传IP头,再在Go服务中安全读取,二者配合才能有效获取用户真实IP


tag标签:
------分隔线----------------------------
------分隔线----------------------------
[相关文章]
    • 24小时技术QQ:1767559921 24小时技术电话:13221000030
    • 公司总台电话:400-901-5608 售前咨询热线:0731-85380877
    小蚁网络-小小 小蚁网络-马马 小蚁网络-蚁蚁 小蚁网络-杨过 小蚁网络-anyyx 小蚁网络-奕奕 小蚁网络-令狐冲 小蚁网络-东邪 小蚁网络-富富 小蚁网络-鬼脚七 小蚁网络-三丰 小蚁网络-风清扬 小蚁网络-技术 投诉与建议

    投诉QQ :512360903
    非法信息举报 :[email protected]
    24小时网维支持 投诉与建议
    故障申报、处理
    24小时技术 24小时网管 企业技术支撑
    域名白名单、信息安全、备案咨询
    白名单审核周一至周六8:30-21:00 周日8:30-18:00 备案专员周一至周五8:30-18:00
    财务续费、发票
    财务续费直线:18073151018