question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Host header may include port

See original GitHub issue

Describe the bug If the Host header provided in a request includes the port, Ambassador responds with a 404 where there is an otherwise valid route.

To Reproduce Steps to reproduce the behavior:

  1. Setup a Host and Mapping
  2. curl https://myhostname.com will work because curl sends Host: myhostname.com
  3. curl https://myhostname.com -H "Host: myhostname.com:443" will return a 404 with an empty body

Expected behavior Ambassador should ignore the port portion of the Host header, or at least treat the default ports as equivalent to the absence of a port.

Versions (please complete the following information):

  • Ambassador: AES 1.1.0
  • Kubernetes environment: Digital Ocean Managed Kubernetes
  • Version: 1.16.2-do.3

Additional context Our client is using Qt’s QNetworkAccessManager to send requests, but upon testing Ambassador I have found that requests were failing from our client (but working from browsers, curl, etc.) Initially I assumed this was a bug in Qt, but the RFC states that the Host header may include a port.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:17
  • Comments:30 (11 by maintainers)

github_iconTop GitHub Comments

6reactions
bemipefecommented, Oct 27, 2021

So if I understood correctly you can’t expose ambassador on a port different than the default (either 80 or 443). Otherwise every request’s header will be filled with the port in the ‘Host’ field and Ambassador is not able to handle the mapping correctly. I can only make it working if I use curl with the option -H 'Host: myambassadorhost' otherwise I get a HTTP 404 not found error. This is a quite a bit limiting.

I tried to use the strip_matching_host_port: true but it’s not working. The official doc report this sentence:

This only applies if the port matches the underlying Envoy listener port.

Unfortunately I can’t understand what this means in practice. I tried using host_regex: true in the Mapping object definition but as already reported the port is not included in the regex evaluation so it doesn’t work.

The only thing that worked in my case was to add the Module object as suggested by @cakuros above.

6reactions
cakuroscommented, Sep 29, 2021

@dbaumgarten

This can be worked around with the below Lua script. It effectively strips the port from the host header prior to evaluating the routing behavior. This will work both with HTTP/1.1 and gRPC.

---
apiVersion: getambassador.io/v2
kind:  Module
metadata:
  name:  ambassador
  namespace: ambassador
spec:
  config:
  # Use the items below for config fields
    lua_scripts: |
      function envoy_on_request(request_handle)
        local authority = request_handle:headers():get(":authority")
        if(string.find(authority, ":") ~= nil)
        then
          local authority_index = string.find(authority, ":")
          local stripped_authority = string.sub(authority, 1, authority_index - 1)
          request_handle:headers():replace(":authority", stripped_authority)
        end
      end

edit: Also, to be clear, the issue you’re seeing is slightly different from the one fixed in the above issue. In your case, the problem is that the server name being requested by the application during SNI is mismatched with the Host header. If you were to run curl -H 'Host: somehost.de:443' https://somehost.de:443/metrics, you would get the expected behavior using strip_matching_host_port: true and using a Mapping that specified a hostname without the port.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is Port Number Required in HTTP "Host" Header Parameter?
YES, the server can use the actual port number that was connected to. In fact, to be reusable, the server MUST do so....
Read more >
HTTP headers | Host - GeeksforGeeks
HTTP headers | Host ... The HTTP Host represents the domain name of the server. It may also represent the Transmission Control Protocol...
Read more >
Host header may include port · Issue #2276 - GitHub
If the Host header provided in a request includes the port, Ambassador responds with a 404 where there is an otherwise valid route....
Read more >
What is the benefit of the port portion of the "Host" header in ...
Most of the internet website traffic is done on standard port 80. For this case, a port number can (according to RFC should)...
Read more >
Host HTTP Header: Syntax, Directive, Examples - Holistic SEO
The Host HTTP Header tells the user what hostname and the port number they are on. If no port is specified, the implied...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found