-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Refactor X-Forwarded-* headers #1381
Conversation
2e9f4b7
to
bc92b77
Compare
bc92b77
to
f38f49e
Compare
@aledbf Thanks for the implementation! It looks good |
default $scheme; | ||
} | ||
map $http_x_forwarded_port $pass_server_port { | ||
default $server_port; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation could be used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -143,27 +143,59 @@ http { | |||
'' close; | |||
} | |||
|
|||
{{ if (trustHTTPHeaders $cfg) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, trustHTTPHeaders is always returning true for me. This block here is always being created regardless of whether I set real-client-from: "http-proxy" or real-client-from: "tcp-proxy".
I checked to make sure whether it's loading real-client-from properly by setting an invalid value, and it does seem to show up on the logs and sets to "auto" so I'm almost certain this value is being read up to trustHTTPHeaders.
func trustHTTPHeaders(input interface{}) bool { | ||
conf, ok := input.(config.TemplateConfig) | ||
if !ok { | ||
return true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Continuing from my comment on nginx.tmpl:146)
Maybe !ok always evaluates to true here.
Could you check if input.(config.TemplateConfig) is returning conf correctly? Or maybe I'm missing something..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
{{ if $cfg.UseProxyProtocol }} | ||
'' $proxy_protocol_addr; | ||
{{ if (trustProxyProtocol $cfg) }} | ||
# Get IP address from Proxy Protocol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't created for me after setting real-client-from: "tcp-proxy"
} | ||
|
||
return conf.Cfg.RealClientFrom == "tcp-proxy" || | ||
(conf.Cfg.RealClientFrom == "auto" && !conf.Cfg.UseProxyProtocol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could be wrong, but shouldn't this be (conf.Cfg.RealClientFrom == "auto" && conf.Cfg.UseProxyProtocol)
?
@jammm image updated quay.io/aledbf/nginx-ingress-controller:0.233 |
I'm going to test this afternoon and will return you. |
@rikatz please use quay.io/aledbf/nginx-ingress-controller:0.242 |
@aledbf It's not working :( I'm running ingress as a baremetal container, and it's not fetching correctly the IP address. The mapping in nginx.conf is as the following:
I'm not using proxy protocol, and neither this is enabled in ConfigMap. Probably this was auto detected (I hadn't changed anything). Thanks |
"~*(?<ip>[0-9\.]+).*" $ip; | ||
{{ if $cfg.UseProxyProtocol }} | ||
'' $proxy_protocol_addr; | ||
{{ if (trustProxyProtocol $cfg) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be $all instead of $cfg, as defined also in trustHTTPHeaders?
I'm facing an issue here, that even when UseProxyProtocol is false, it's returning a 'true' value here, using $proxy_protocol_addr instead of $realip_remote_addr.
Edit: After changing this to $all in my template, it works fine. I'm now going to test this with other options to see what's the behaviour.
@rikatz please use quay.io/aledbf/nginx-ingress-controller:0.243 |
@rikatz this image works fine. telnet $(minikube ip) 80 Default configurationTests:
proxy-protocolConfigmap: Tests:
proxy-protocolConfigmap: Tests:
|
@aledbf Now I'm entering the other 'if', that accepts X-Forwarded-For as the realip. I'm trying to bypass this and see if the vulnerability still happens, but it seems fine now (I'll try to understand what changed and where later). The only thing that's still wrong here is the mapping for http_x_forwarded_proto, that accepts whatever the user passes. This allows the user to bypass SSL redirections as defined above:
An example: create a site, force the SSL redirection, and then set the Header Thanks! |
@rikatz enabling HSTS solves this issue. Also your service should use secure cookies. |
Test images:
quay.io/aledbf/nginx-ingress-controller:0.223
Replaces #1222
Fixes #1000