-
Notifications
You must be signed in to change notification settings - Fork 617
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
Using upstream hostname for request #294
Comments
That should work. You're sure that your |
To piggy back on @CGreenburg question. We're hoping to get Fabio to work like a reverse proxy (I think). HTTP -> HTTPS in this case so our users can simply hit Fabio and Fabio routes the traffic to the backend services. (An obvious use case for the tool.) However, we're stubbing our toes somewhere.
What are we missing? Are we fundamentally missing something on how this should all work, or missing something in the Fabio configuration? |
Here is my configuration for a Serverless REST API in Fabio:
(purposefully garbling the url there.) I get a Bad Request from Amazon when I run even though this is the use case we're looking for...
I should also note that I'm using the latest version of the |
@mitchelldavis Pls open another ticket in the future. I don't mind answering several questions but I'd prefer not to morph or merge issues. You probably need to add |
@magiconair yes, the tag does not contain the hostname. I've noticed when running I registered a service pointing to www.google.com port 443 with a tag So.... I'm unsure as to why the API Gateway URL is so picky about the Host header... |
That looks like a bug. |
@magiconair Sorry to confuse. @CGreenburg sits behind me, and we're working through the same problem. |
Indeed - that should have been obvious. Sorry for pushing :) |
What does your consul service record look like? |
|
Can you try setting the |
I did and same result:
|
And the service is accessible under |
Yes. We can curl it directly no problem. |
you should be able to curl it at: |
Can you use access logging to log the target url:
|
I was doing that already actually:
(That extra dollar sign on the upstream_host was a typo on the log.access.format in the properties) |
I'm getting a
|
That's expected, Sorry, we're not going to give you access. |
ok, late here (AMS, NL). I'll look at it probably on Monday. |
No Worries. Thank you! |
@magiconair, anymore thoughts on this? |
@mitchelldavis got sidetracked. I try to have a look later tonight or tomorrow morning. |
@magiconair, We got a response back from the Cloud Front Engineers at AWS and it turns out that it's not working with the API Gateway because we're passing the wrong host header. In this case, we're passing the IP of the fabio machine as the host header. Cloud Front can't do anything with that host header and is expecting a header with the URL of the service we're trying to hit. Does Fabio attempt to "re-write" the host header to the URL it's routing to? |
No, it uses the host header for routing and then passes the request on as is. |
OK, so the problem is this:
Your case is different. You register the service without a hostname but the upstream service only accepts a specific hostname. fabio cannot do this right now. I can see two options:
I think this should only work if the upstream service advertises a route with |
You've nailed it @magiconair. That's the issue. Do you see this as a viable pull request that won't destroy existing functionality? If so, I may be able to spend some cycles trying to get it implemented. |
WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP ----------------------------------------------- This patch is work in progress and demonstrates the desired behavior and adds a test to verify it. The feature needs to be made configurable per route. Fabio does not modify the Host header when forwarding the request to the upstream server. This patch enables a mode where for a specific route fabio will use the hostname of the upstream server as the host header. ----------------------------------------------- WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP Fixes #294
The following line to diff --git a/proxy/http_proxy.go b/proxy/http_proxy.go
index 4056d07..2e5d84f 100644
--- a/proxy/http_proxy.go
+++ b/proxy/http_proxy.go
@@ -99,6 +99,7 @@ func (p *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else {
targetURL.RawQuery = t.URL.RawQuery + "&" + r.URL.RawQuery
}
+ r.Host = targetURL.Host
// TODO(fs): The HasPrefix check seems redundant since the lookup function should
// TODO(fs): have found the target based on the prefix but there may be other |
I've pushed a branch which is WIP but contains an integration test to verify the behavior. The added line does what you want but now it needs to become configurable. |
This is awesome. Thank you for looking into this! |
@magiconair, I was thinking that a tag would be a great way to configure this. Just like the |
WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP ----------------------------------------------- This patch is work in progress and demonstrates the desired behavior and adds a test to verify it. The feature needs to be made configurable per route. Fabio does not modify the Host header when forwarding the request to the upstream server. This patch enables a mode where for a specific route fabio will use the hostname of the upstream server as the host header. ----------------------------------------------- WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP Fixes #294
WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP ----------------------------------------------- This patch is work in progress and demonstrates the desired behavior and adds a test to verify it. The feature needs to be made configurable per route. Fabio does not modify the Host header when forwarding the request to the upstream server. This patch enables a mode where for a specific route fabio will use the hostname of the upstream server as the host header. ----------------------------------------------- WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP WIP Fixes #294
Thanks @magiconair, I'm currently working on a pull request. I'm having trouble getting the vault tests to pass, but we'll get it in when we can. |
Can you try with vault 0.6.4? |
The way I usually run the tests is |
@magiconair, changing to vault 0.6.4 worked. Thank you so much for your guidance and I was able to run the changes against AWS API Gateway and it worked like a charm. |
This patch adds support for a 'host=dst' option on a route which will trigger the proxy to use the hostname of the target host for the outgoing request instead of the one provided by incoming request. This allows fabio to act as a reverse proxy for an external site.
merged PR #301 to master |
@mitchelldavis Thanks for this patch! |
You're very welcome! What kind of timeline are we looking at to get this released in a docker container? |
Early next week |
My team and I are working on figuring out a service discovery architecture for our multitude of Serverless stacks.
I've created two EC2 instances in AWS: one with Consul and the other with Fabio. I have a Serverless stack deployed with a single endpoint: /status. I registered a service in Consul with the address being the API Gateway URL (
xxxxxxx.execute-api....com
) and the port to 443. I set the tag tourlprefix-/status proto=https
.Now, maybe I'm confused on how all of this works, but how come I can't do
curl <fabio-ip>:9999/status
? When I run that command, I get a 403 status code and a body saying bad request from CloudFront. Adding a Trace header printsRouting to service status on https://xxxxxxx.execute-api....com:443/status
. If I runcurl https://xxxxxxx.execute-api....com:443/status
, I get back a response from my lambda function as I expect.It seems in order for it work, I need to add a Host header matching the API Gateway URL:
curl -H 'Host: xxxxxxx.execute-api....com' <fabio-ip>:9999/status
. That works fine and returns back a response from my lambda function, but that defeats the whole purpose. If I have clients go to curl the api, I can't expect them to know the API Gateway URL since Fabio and Consul are meant to abstract it.So, my main question is, what am I doing wrong? Am I thinking about this in the wrong way? Am I missing some configuration of some sort? Thanks.
The text was updated successfully, but these errors were encountered: