Skip to content
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

About RemoteAddrPrivateSubnet #1567

Closed
linanh opened this issue Jul 23, 2020 · 9 comments
Closed

About RemoteAddrPrivateSubnet #1567

linanh opened this issue Jul 23, 2020 · 9 comments

Comments

@linanh
Copy link

linanh commented Jul 23, 2020

The config "RemoteAddrPrivateSubnet" variable is allowed to append, but not to be removed or set new.
For the users of local network, "ctx.RemoteAddr()" can only get proxy server ip, can't get real ip.

@Dexus
Copy link

Dexus commented Jul 24, 2020

Sure, you can look at

// app.Listen(":8080", iris.WithConfiguration(iris.Configuration{/* fields here */ }))

It describes how to customize the configuration. That way you should get exactly what you want, you just have to create your own list.

@Dexus
Copy link

Dexus commented Jul 24, 2020

Here a Example:

iris.WithConfiguration(iris.Configuration{
	RemoteAddrPrivateSubnets: []netutil.IPRange{
		{
			Start: net.ParseIP("10.0.0.0"),
			End:   net.ParseIP("10.255.255.255"),
		},
	},
}),

@kataras
Copy link
Owner

kataras commented Jul 24, 2020

@linanh look what @Dexus posted, that's the way.

@linanh
Copy link
Author

linanh commented Jul 25, 2020

@kataras For local network users, the default value of "RemoteAddrPrivateSubnet" will cause incompatibility problem with version v12.1.

@kataras
Copy link
Owner

kataras commented Jul 25, 2020

@linanh These default values are the recommended to use on a typical web application. You can modify them with ease. Do you prefer to leave the default list as empty instead, what's your suggestion? Thanks

@linanh
Copy link
Author

linanh commented Jul 25, 2020

@kataras In https://github.com/kataras/iris/blob/master/core/netutil/ip.go#L44, if a public IP address is not found, return the first IP address, and don't return false.

@kataras
Copy link
Owner

kataras commented Jul 26, 2020

@linanh The core/netutil/ip.go is for the IPs retrieved by request headers such as X-Forwarded-For, look at:

iris/configuration.go

Lines 782 to 800 in a50f0ed

// RemoteAddrHeaders are the allowed request headers names
// that can be valid to parse the client's IP based on.
// By-default no "X-" header is consired safe to be used for retrieving the
// client's IP address, because those headers can manually change by
// the client. But sometimes are useful e.g., when behind a proxy
// you want to enable the "X-Forwarded-For" or when cloudflare
// you want to enable the "CF-Connecting-IP", inneed you
// can allow the `ctx.RemoteAddr()` to use any header
// that the client may sent.
//
// Defaults to an empty map but an example usage is:
// RemoteAddrHeaders {
// "X-Real-Ip": true,
// "X-Forwarded-For": true,
// "CF-Connecting-IP": true,
// }
//
// Look `context.RemoteAddr()` for more.
RemoteAddrHeaders map[string]bool `json:"remoteAddrHeaders,omitempty" yaml:"RemoteAddrHeaders" toml:"RemoteAddrHeaders"`
Its job is to return a valid "public" IP, if there is not a single valid public IP available then it SHOULD return empty and false so the context.RemoteAddr can continue its job by fetching the address from Request.RemoteAddr, if non of the above passes. Look at:

iris/context/context.go

Lines 827 to 835 in a50f0ed

addr := strings.TrimSpace(ctx.request.RemoteAddr)
if addr != "" {
// if addr has port use the net.SplitHostPort otherwise(error occurs) take as it is
if ip, _, err := net.SplitHostPort(addr); err == nil {
return ip
}
}
return addr

Your suggestion will break part of the Private Subnet feature, because if it's private then it will return it, which we try to avoid, that's why it's implemented at the first place. If you think a private/local sub network should be treated as a remote network then you can just edit the Configuration.RemoteAddrPrivateSubnets as @Dexus pointed out above.

However, if you really want to extract the IP from headers, even e non-public one and not from Request.RemoteAddr as fallback, we can add a Configuration.RemoteAddrHeadersForce bool which will force Iris to return the first IP, even if it's found as part of private sub networks. Is that OK with you?

UPDATE: Note that because of RemoteAddrHeaders is a map, it has no order, so that field may not always return the first entry of the same request header. For that reason, I will introduce a breaking change for RemoteAddrHeaders, from a map[string]bool to just a []string, which seems more appropriate for devs that care about the matching order of those request headers.

UPDATE: Upgrade to the latest master, add the RemoteAddrHeadersForce: true and you are ready to Go.

$ cd your project
$ go get -u github.com/kataras/iris/v12@master

Thanks,
Gerasimos Maropoulos

@kataras kataras added this to the v12.2.0 milestone Jul 26, 2020
kataras added a commit that referenced this issue Jul 26, 2020
…ange RemoteAddrHeaders from map to string slice

Read HISTORY.md entry
@linanh
Copy link
Author

linanh commented Jul 26, 2020

@kataras Thanks.

@linanh linanh closed this as completed Jul 26, 2020
@kataras
Copy link
Owner

kataras commented Jul 27, 2020

You are welcome @linanh !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants