-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
c.ClientIP() #2697
Comments
me too |
框架升级是不是需要考虑平滑?这就意味着用过这个方法的用户,升完级都要出问题了。。。。 |
Translate: |
The best way is roll back the trusted proxy update and make it optional. Almost everyone uses Nginx and add-on packages so that there is no doubt about the client. |
// ClientIP implements a best effort algorithm to return the real client IP.
// It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
// If it's it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
// If the headers are nots syntactically valid OR the remote IP does not correspong to a trusted proxy,
// the remote IP (coming form Request.RemoteAddr) is returned. According to the documentation of the If it is a trusted IP (which means the request is redirected by a proxy), then it will try to parse the "real user IP" from Conclusion: You can think For Chinese: |
Thanks for the answer, I saw the documentation and code comments. Why is 127.0.0.1 not the default trusted address? Most people use Nginx for serve to WAN. |
// New returns a new blank Engine instance without any middleware attached.
// By default the configuration is:
// - RedirectTrailingSlash: true
// - RedirectFixedPath: false
// - HandleMethodNotAllowed: false
// - ForwardedByClientIP: true
// - UseRawPath: false
// - UnescapePathValues: true
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedProxies: []string{"0.0.0.0/0"},
AppEngine: defaultAppEngine,
UseRawPath: false,
RemoveExtraSlash: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
}
engine.RouterGroup.engine = engine
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine
} As you can see, the default value of the And alternative IP in |
it does not work for me, as well as for many who opened topics with such a problem. |
Interesting, let me go to take a look and test it. |
log from SSH
In all responses localhost (127.0.0.1) the proxy configuration was thrown above
|
client/main.go package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080", nil)
req.Header.Add("X-Forwarded-For", "123.123.123.123")
res, _ := http.DefaultClient.Do(req)
body := res.Body
data, _ := io.ReadAll(body)
fmt.Println(string(data))
defer body.Close()
} server/main.go package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "%s", c.ClientIP())
})
r.Run()
} I created a simple client and server. Here is the output. As you can see, the result is correct and the feature is working. |
Header X-Forwarded-For from Nginx in my case is correct too If I use I can't understand how to work with Nginx & GIN 1.7+ |
Just in case, I post the source code to check
|
Did you deploy your Nginx to the same machine as the server and the client?
I know you said that you can get the correct address through header. |
GO and Nginx are on the same server, everything was ok before the update gin 1.7 |
Try to send a request to Nginx with another machine, because if you send the request using the same machine with Nginx, Nginx will set the |
Are you proposing to change the server infrastructure, which works fine due to the fact that the GIN version has been updated? |
No, I didn't mean you need to change the server infrastructure. I just want to make sure that you are actually testing it in the right way.
As the result, I think it may be caused by the 3 point I just mentioned. So I call you to try to "send request" to your Nginx proxy with a different machine, I didn't mean moving the Golang application to another machine. |
I meet the same problem too, after debug the application, I found this issue occur when engine.Run() was not called. |
Good catch! I didn't actually notice that too. |
well, I pointed it out at the beginning. #2692 |
@artlevitan Please take a look and sorry for my misleading information. |
I have also run into this problem. I see there is a PR to expose a workaround for setting trusted proxies, but I can't tell if it was abandoned. |
when we start with RunTLS instand of Run, ClientIP() will always return 127.0.0.1 while prepareTrustedCIDRs() not called |
看了下源码,prepareTrustedCIDRs只在run里有调用,RunTLS没调,也就是ClientIP只能在http环境使用,上面某评论说一直返回127.0.0.1其实也是因为走的https环境 |
nginx and gin v1.7 same machine, and send request to nginx from another machine, but method ClientIP return "127.0.0.1", which is not we want |
这个升级的破坏性真是神坑 |
Bad and very destructive upgrade!!! |
@axiaoxin I had same problem, I used @leungyauming When will the fix for code that doesn't use |
By the way I ended up just using this function since I wanted the old logic and my servers are behind cloudfront: func getClientIP(c *gin.Context) string {
forwardHeader := c.Request.Header.Get("x-forwarded-for")
firstAddress := strings.Split(forwardHeader, ",")[0]
if net.ParseIP(strings.TrimSpace(firstAddress)) != nil {
return firstAddress
}
return c.ClientIP()
} Then replaced |
Also having this issue. We don't call |
Also waiting for this to be fixed... Without that method exposed, I can't enable the feature, as I don't start the server using |
I used your code, but modified it to be as a middleware which I invoke before all. I did it this way in order to avoid wrapping and changing everywhere ctx.ClientIP() func Preprocess(logger *zap.Logger) gin.HandlerFunc {
return func(ctx *gin.Context) {
_, port, _ := net.SplitHostPort(strings.TrimSpace(ctx.Request.RemoteAddr))
ip := getClientIP(ctx)
ctx.Request.RemoteAddr = fmt.Sprintf("%s:%s", ip, port)
ctx.Next()
}
} Of course this is only mitigation, we're all waiting for regular fix of this issue. |
any updates on this issue? |
just discovered issues wtih this today as well.... |
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;#在多级代理的情况下,记录每次代理之前的客户端真实ip
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass https://remote_app_proxy_url; after add NGINX configurations use code below to get real client IP also Gin egine router := gin.New()
router.TrustedProxies := []string{"0.0.0.0/0"}
router.RemoteIPHeaders := []string{"X-Forwarded-For", "X-Real-IP"} func GetRealIP(c *gin.Context) string {
ip := c.GetHeader("X-Real-IP")
if len(ip) == 0 {
return c.ClientIP()
}
return ip
} will this comment help you? i hope that |
Hey! No, it didn't help me, I tried this method at the beginning. |
I use this code until Gin is updated normally.
|
v1.7.7 have released, thanks! https://github.com/gin-gonic/gin/releases |
Who cares about Trusted Proxies and Trusted shit... The bugs introduced by this feature are ridiculous. That's an env security stuff. This is the job of a load balancer or something like that in front of the gin server. Not suitable for enterprise users |
Still not working if remote IP is |
|
Gin update to 1.7 broke the work with IP addresses of clients: now 'X-Forwarded-For' and 'X-Real-Ip' headers needs to be set as trusted for 'c.ClientIP()' method to successfully read the client's IP in case 'gin.Run' method is not used. Related issue: gin-gonic/gin#2697
I just bumped into this; this "feature" is full of defects, imho. |
just set trusted proxies []string to have ::1 and get nginx to pass down the real ip... |
Friends, the update to 1.7 broke the work with IP addresses of clients.
I am proxying Go through Nginx
I read this #2693
But I don't understand what to write in router.TrustedProxies
Thanks everyone 🙏🏻
The text was updated successfully, but these errors were encountered: