Baldinof / roadrunner-bundle

A RoadRunner worker integrated in your Symfony app
MIT License
255 stars 46 forks source link

Feat: support for RR in Docker behind proxy in another Docker #131

Open FluffyDiscord opened 7 months ago

FluffyDiscord commented 7 months ago

If RR is running inside Docker and we simply pass https requests from proxy (basicaly proxy manages certificates) to the RR instance as http, the parsed uri scheme in this bundle will always be in this case http and Symfony will now use invalid schema or add 443 port when generating URLs.

Checking if X-Forwarded-Proto is trusted header and making it priority in HttpFoundationWoker->configureServer() fixes this issue. To make the rest of Symfony proxy features work we also need to set REMOTE_ADDR to the X-Forwarded-For header, also only if its trusted.

This should be a non breaking change for everyone.

Baldinof commented 6 months ago

Did you tried the framework.trusted_proxies option, like here: https://symfony.com/doc/current/deployment/proxies.html

If the proxy is local, you should add 127.0.0.1.

I did it locally and it seems to work as expected:

$ curl http://localhost:8080/test -H 'x-forwarded-proto: https'
{"url":"https:\/\/localhost:8080\/home"}

$ curl http://localhost:8080/test
{"url":"http:\/\/localhost:8080\/home"}
FluffyDiscord commented 6 months ago

I did try, my framework.yaml looks like this (I was desperate):

framework:
    trusted_proxies: '127.0.0.1/8,REMOTE_ADDR,SERVER_NAME'
    trusted_headers: [ 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix' ]

That did not work, until I added changes in this PR.

Basically, my setup is like this: HTTPS Web > Nginx in Docker > HTTP to RR & Symfony in another Docker

Baldinof commented 6 months ago

By chance, would you be able to provide a reproducer repo?

FluffyDiscord commented 6 months ago

Not sure if entirely possible. I bumped into that issue after deploying to production - on real domain. The docker nginx proxy cannot generate/use self signed certificates to simulate it locally. You need to have live domain. If thats okay, I can probably create reproducer with docker-compose, tho you will need to deploy it somewhere yourself.

Baldinof commented 6 months ago

Yeah I have domains to test it :)

yunicot commented 6 months ago

@FluffyDiscord I had the similar problem and the problem was in "trusted_proxies" param

framework:
    trusted_proxies: '10.0.0.0/8,127.0.0.0/8,172.16.0.0/12,192.168.0.0/16'
    trusted_headers: [ 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port' ]

For example, on local env I am using "nginx-proxy" docker image and it pass the ip 192.168.0.0/16 Did you try to check what you receive in REMOTE_ADDR?

Also, we are mapping the x-forwarded-* in nginx config for prod