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

Refactor X-Forwarded-* headers #1381

Merged
merged 12 commits into from
Sep 30, 2017

Conversation

aledbf
Copy link
Member

@aledbf aledbf commented Sep 17, 2017

Test images: quay.io/aledbf/nginx-ingress-controller:0.223

Replaces #1222
Fixes #1000

@k8s-reviewable
Copy link

This change is Reviewable

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Sep 17, 2017
@aledbf
Copy link
Member Author

aledbf commented Sep 17, 2017

@boazy @rikatz please test

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 17, 2017
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 43.89% when pulling f38f49e on aledbf:refactor-template-headers into f478084 on kubernetes:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 43.89% when pulling 669428e on aledbf:refactor-template-headers into 1a68536 on kubernetes:master.

@boazy
Copy link

boazy commented Sep 18, 2017

@aledbf Thanks for the implementation! It looks good
I'll try to test that as soon as possible.

default $scheme;
}
map $http_x_forwarded_port $pass_server_port {
default $server_port;
Copy link

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.

Copy link
Member Author

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) }}
Copy link

@jammm jammm Sep 19, 2017

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
Copy link

@jammm jammm Sep 19, 2017

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..

Copy link
Member Author

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
Copy link

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)
Copy link

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) ?

@aledbf
Copy link
Member Author

aledbf commented Sep 26, 2017

@jammm image updated quay.io/aledbf/nginx-ingress-controller:0.233

@coveralls
Copy link

Coverage Status

Coverage increased (+0.06%) to 43.828% when pulling 6ee2b72 on aledbf:refactor-template-headers into 47ea2d7 on kubernetes:master.

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Sep 26, 2017
@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 43.816% when pulling 78e166f on aledbf:refactor-template-headers into 47ea2d7 on kubernetes:master.

@aledbf
Copy link
Member Author

aledbf commented Sep 28, 2017

ping @rikatz @jammm @boazy please check the content of the PR
Temporal image quay.io/aledbf/nginx-ingress-controller:0.233

@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 29, 2017
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 43.52% when pulling db12b51 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.04%) to 43.545% when pulling db12b51 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 43.557% when pulling b1b75f9 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.04%) to 43.545% when pulling b1b75f9 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@rikatz
Copy link
Contributor

rikatz commented Sep 29, 2017

I'm going to test this afternoon and will return you.

@aledbf
Copy link
Member Author

aledbf commented Sep 29, 2017

@rikatz please use quay.io/aledbf/nginx-ingress-controller:0.242

@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 43.52% when pulling f549e03 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@rikatz
Copy link
Contributor

rikatz commented Sep 29, 2017

@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:

   map $http_x_forwarded_for $the_real_ip {
        # Get IP address from Proxy Protocol
        default          $proxy_protocol_addr;
    }

    map $http_x_forwarded_host $best_http_host {
        default          $this_host;

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) }}
Copy link
Contributor

@rikatz rikatz Sep 29, 2017

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.

@aledbf
Copy link
Member Author

aledbf commented Sep 29, 2017

@rikatz please use quay.io/aledbf/nginx-ingress-controller:0.243

@aledbf
Copy link
Member Author

aledbf commented Sep 29, 2017

@rikatz this image works fine.

telnet $(minikube ip) 80

Default configuration

Tests:

  • case 1
GET / HTTP/1.0
  • case 2
GET / HTTP/1.0
X-Forwarded-For: 10.0.0.1, fake.ip, 198.51.100.1

proxy-protocol

Configmap:
use-proxy-protocol: true

Tests:

  • case 1
PROXY TCP4 1.1.1.1 1.1.1.2 1 2 
GET / HTTP/1.0
  • case 2
PROXY TCP4 1.1.1.1 1.1.1.2 1 2 
GET / HTTP/1.0
X-Forwarded-For: 10.0.0.1, fake.ip, 198.51.100.1

proxy-protocol

Configmap:
use-proxy-protocol: true

Tests:

  • case 1
PROXY TCP4 1.1.1.1 1.1.1.2 1 2 
GET / HTTP/1.0
  • case 2
PROXY TCP4 1.1.1.1 1.1.1.2 1 2 
GET / HTTP/1.0
X-Forwarded-For: 10.0.0.1, fake.ip, 198.51.100.1

@coveralls
Copy link

Coverage Status

Coverage increased (+0.04%) to 43.553% when pulling f253d24 on aledbf:refactor-template-headers into ba6c896 on kubernetes:master.

@rikatz
Copy link
Contributor

rikatz commented Sep 29, 2017

@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:

 if ($pass_access_scheme = http) {
                return 301 https://$best_http_host$request_uri;
            }

An example: create a site, force the SSL redirection, and then set the Header X-Forwarded-Proto: https but call the HTTP Port/VHost and You'll not be redirected, bypassing this directive.

Thanks!

@aledbf
Copy link
Member Author

aledbf commented Sep 29, 2017

@rikatz enabling HSTS solves this issue. Also your service should use secure cookies.
I am not sure we can do more than this. We need to allow the header to be able to run behind a load balancer.

@aledbf aledbf merged commit 1c67da5 into kubernetes:master Sep 30, 2017
@aledbf aledbf deleted the refactor-template-headers branch September 30, 2017 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants