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

Documentation for Ingress Gateways #8045

Closed
nicholasjackson opened this issue Jun 7, 2020 · 2 comments
Closed

Documentation for Ingress Gateways #8045

nicholasjackson opened this issue Jun 7, 2020 · 2 comments
Labels
theme/connect Anything related to Consul Connect, Service Mesh, Side Car Proxies theme/ingress-gw Track ingress work type/docs Documentation needs to be created/updated/clarified type/enhancement Proposed improvement or new feature

Comments

@nicholasjackson
Copy link
Contributor

The documentation for Ingress Gateways states that you can specify Host header matching for services using the Hosts parameter for a service.

https://github.com/hashicorp/consul/blob/master/website/pages/docs/agent/config-entries/ingress-gateway.mdx

However a port is required in this setting if anything other than port 80 is used.

Reproduction Steps

Given the following example:

Kind = "ingress-gateway"
Name = "ingress-service"

Listeners = [
  {
    Port = 8080
    Protocol = "http"
    Services = [
      {
        Name = "api"
        Hosts = ["api.ingress.container.shipyard.run"]
      },
      {
        Name = "web"
        Hosts = ["web.ingress.container.shipyard.run"]
      }
    ]
  }
]

This would generate the following dynamic route config:

   "dynamic_route_configs": [
    {
     "version_info": "00000008",
     "route_config": {
      "@type": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
      "name": "8080",
      "virtual_hosts": [
       {
        "name": "api",
        "domains": [
         "api.ingress.container.shipyard.run"
        ],
        "routes": [
         {
          "match": {
           "prefix": "/"
          },
          "route": {
           "cluster": "api.default.dc1.internal.b1eddb34-f2af-f8ab-bd64-bc44fb9d4392.consul"
          }
         }
        ]
       },
       {
        "name": "web",
        "domains": [
         "web.ingress.container.shipyard.run"
        ],
        "routes": [
         {
          "match": {
           "prefix": "/"
          },
          "route": {
           "cluster": "web.default.dc1.internal.b1eddb34-f2af-f8ab-bd64-bc44fb9d4392.consul"
          }
         }
        ]
       }
      ],
      "validate_clusters": true
     },
     "last_updated": "2020-06-07T09:43:08.259Z"
    }
   ]
  },
  {
   "@type": "type.googleapis.com/envoy.admin.v3.SecretsConfigDump"
  }
 ]
}

When calling the public listener with curl the following headers would be sent

curl -v web.ingress.container.shipyard.run:8080
* Rebuilt URL to: web.ingress.container.shipyard.run:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to web.ingress.container.shipyard.run (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: web.ingress.container.shipyard.run:8080
> User-Agent: curl/7.58.0
> Accept: */*

NOTE Host has a value of web.ingress.container.shipyard.run:8080 the envoy route filter is rejecting this as it is matching on a value of web.ingress.container.shipyard.run without the port.

A quick fix for this is to add the listener port to the Hosts array as shown in the example below.

    Services = [
      {
        Name = "api"
        Hosts = ["api.ingress.container.shipyard.run:8080"]
      },
      {
        Name = "web"
        Hosts = ["web.ingress.container.shipyard.run:8080"]
      }
    ]
@nicholasjackson
Copy link
Contributor Author

In addition to the above, if you add the port to Hosts it causes problems when TLS is enabled as the port is added to the DNS SAN for the TLS cert..

 ➜ echo | openssl s_client -showcerts -servername web.ingress.container.shipyard.run -connect web.ingress.container.shipyard.run:8080 2>/dev/null | openssl x509 -inform pem -noout -text  
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 12 (0xc)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = pri-1hw6eku.consul.ca.b1eddb34.consul
        Validity
            Not Before: Jun  7 10:01:57 2020 GMT
            Not After : Jun 10 10:01:57 2020 GMT
        Subject: CN = ingressservice.svc.default.b1eddb34.consul
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:e2:7f:4b:d6:a0:d9:de:c7:4f:9f:09:2f:7a:22:
                    60:2a:ce:2c:c5:ba:88:11:8a:66:9f:80:50:7f:40:
                    52:1c:0f:15:de:23:fc:03:38:41:47:6b:8f:0c:47:
                    d4:ba:e0:28:c7:62:30:1a:ce:79:96:f4:27:52:81:
                    12:43:1e:37:72
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Data Encipherment, Key Agreement
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                49:C2:3C:B4:B6:75:3A:5F:6F:5D:4A:DC:68:B8:14:37:2D:65:62:86:9D:0F:28:06:4D:C1:BF:CD:AB:E2:E8:A0
            X509v3 Authority Key Identifier: 
                keyid:07:19:20:58:4C:D2:2A:89:5B:00:72:F5:45:2D:6B:56:BB:64:F1:AF:DF:81:6F:81:89:3F:AA:1F:4C:2B:8A:60

            X509v3 Subject Alternative Name: 
                DNS:*.ingress.consul., DNS:*.ingress.dc1.consul., DNS:api.ingress.container.shipyard.run:8080, DNS:web.ingress.container.shipyard.run:8080, URI:spiffe://b1eddb34-f2af-f8ab-bd64-bc44fb9d4392.consul/ns/default/dc/dc1/svc/ingress-service
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:fd:22:d1:86:6c:cd:e3:9b:c4:34:d5:ab:4b:
         1f:79:90:3f:be:72:27:96:03:34:06:01:ce:d5:b0:42:e5:7d:
         18:02:20:04:49:4d:94:e7:8b:df:5c:cc:c5:b4:d6:2a:24:fa:
         22:d2:28:ba:a2:d2:46:a9:bd:1d:64:9c:e5:75:7d:57:1f

This would cause TLS certificate validation failures as TLS is only looking at the hostname not the hostname port combination.

A work around for this it to add the hostname with and without the port to the L7 config, this enables Envoy routing to function and the TLS certificate validation.

Kind = "ingress-gateway"
Name = "ingress-service"

TLS {
  Enabled = true
}

Listeners = [
  {
    Port = 8080
    Protocol = "http"
    Services = [
      {
        Name = "api"
        Hosts = ["api.ingress.container.shipyard.run", "api.ingress.container.shipyard.run:8080"]
      },
      {
        Name = "web"
        Hosts = ["web.ingress.container.shipyard.run", "web.ingress.container.shipyard.run:8080"]
      }
    ]
  }
]

@jsosulska jsosulska added type/docs Documentation needs to be created/updated/clarified type/enhancement Proposed improvement or new feature theme/connect Anything related to Consul Connect, Service Mesh, Side Car Proxies theme/ingress-gw Track ingress work labels Jun 8, 2020
@jsosulska
Copy link
Contributor

Closed by #8062

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme/connect Anything related to Consul Connect, Service Mesh, Side Car Proxies theme/ingress-gw Track ingress work type/docs Documentation needs to be created/updated/clarified type/enhancement Proposed improvement or new feature
Projects
None yet
Development

No branches or pull requests

2 participants