Documentation
Introduction
Configuration
- HTTPProxy Fundamentals
- Gateway API Support
- Ingress v1 Support
- Virtual Hosts
- Inclusion and Delegation
- TLS Termination
- Upstream TLS
- Request Routing
- External Service Routing
- Request Rewriting
- CORS
- Websockets
- Upstream Health Checks
- Client Authorization
- TLS Delegation
- Rate Limiting
- Access logging
- Cookie Rewriting
- Overload Manager
- JWT Verification
- IP Filtering
- Annotations Reference
- Slow Start Mode
- Tracing Support
- API Reference
Deployment
- Deployment Options
- Contour Configuration
- Upgrading Contour
- Enabling TLS between Envoy and Contour
- Redeploy Envoy
Guides
- Deploying Contour on AWS with NLB
- AWS Network Load Balancer TLS Termination with Contour
- Deploying HTTPS services with Contour and cert-manager
- External Authorization Support
- FIPS 140-2 in Contour
- Using Gatekeeper with Contour
- Using Gateway API with Contour
- Global Rate Limiting
- Configuring ingress to gRPC services with Contour
- Health Checking
- Creating a Contour-compatible kind cluster
- Collecting Metrics with Prometheus
- How to Configure PROXY Protocol v1/v2 Support
- Contour/Envoy Resource Limits
Troubleshooting
- Troubleshooting Common Proxy Errors
- Envoy Administration Access
- Contour Debug Logging
- Envoy Debug Logging
- Visualize the Contour Graph
- Show Contour xDS Resources
- Profiling Contour
- Envoy Container Stuck in Unready State
Resources
- Support Policy
- Compatibility Matrix
- Contour Deprecation Policy
- Release Process
- Frequently Asked Questions
- Tagging
- Adopters
- Ecosystem
Security
Contribute
If you deploy Contour as a Deployment or Daemonset, you will likely use a type: LoadBalancer Service to request an
external load balancer from your hosting provider.
If you use the Elastic Load Balancer (ELB) service from Amazon’s EC2, you need to perform a couple of additional steps to enable the
PROXY protocol. Here’s why:
External load balancers typically operate in one of two modes: a layer 7 HTTP proxy, or a layer 4 TCP proxy. The former cannot be used to load balance TLS traffic, because your cloud provider attempts HTTP negotiation on port 443. So the latter must be used when Contour handles HTTP and HTTPS traffic.
However this leads to a situation where the remote IP address of the client is reported as the inside address of your cloud provider’s load balancer. To rectify the situation, you can add annotations to your service and flags to your Contour Deployment or DaemonSet to enable the PROXY protocol which forwards the original client IP details to Envoy.
Enable PROXY protocol on your service in GKE
In GKE clusters a type: LoadBalancer Service is provisioned as a Network Load Balancer and will forward traffic to your Envoy instances with their client addresses intact.
Your services should see the addresses in the X-Forwarded-For or X-Envoy-External-Address headers without having to enable a PROXY protocol.
Enable PROXY protocol on your service in AWS
To instruct EC2 to place the ELB into tcp+PROXY mode, add the following annotations to the contour Service:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'
name: contour
namespace: projectcontour
spec:
type: LoadBalancer
...
Enable PROXY protocol support for all Envoy listening ports
...
spec:
containers:
- image: ghcr.io/projectcontour/contour:<version>
imagePullPolicy: Always
name: contour
command: ["contour"]
args: ["serve", "--incluster", "--use-proxy-protocol"]
...
Set X-Forwarded-Proto when the load balancer terminates TLS
If the load balancer terminates TLS itself, for example an AWS NLB with a TLS listener and an ACM certificate, and forwards plaintext to Envoy with the PROXY protocol, every connection Envoy accepts is plaintext.
Envoy then sets X-Forwarded-Proto: http on every request, so backends cannot tell HTTPS requests from HTTP ones, and anything that redirects HTTP to HTTPS based on that header, in the application or in an HTTPProxy route, redirects in a loop.
Envoy can derive X-Forwarded-Proto from the destination port carried in the PROXY protocol header instead.
Enable it in the Contour configuration file, together with --use-proxy-protocol (Contour rejects the setting without it):
listener:
proxy-protocol-settings:
https-destination-ports: [443]
http-destination-ports: [80]
or in the ContourConfiguration resource:
spec:
envoy:
listener:
useProxyProtocol: true
proxyProtocolSettings:
httpsDestinationPorts: [443]
httpDestinationPorts: [80]
When Contour is deployed with the Gateway provisioner, set the same fields under spec.runtimeSettings.envoy.listener in the ContourDeployment resource.
Requests that reached the load balancer on a port listed in https-destination-ports get X-Forwarded-Proto: https, those on a port in http-destination-ports get http, and any other port keeps Envoy’s default behavior.
Because Envoy never sees TLS in this setup, the HTTPProxy has no tls section and Contour’s built-in HTTP to HTTPS upgrade does not apply.
To redirect plaintext requests to HTTPS, add a route that matches X-Forwarded-Proto: http and redirects; with the setting above it only matches requests that arrived on an HTTP port:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: www
spec:
virtualhost:
fqdn: www.example.com
routes:
- conditions:
- header:
name: X-Forwarded-Proto
exact: http
requestRedirectPolicy:
scheme: https
statusCode: 301
- services:
- name: www
port: 80
Twitter
Slack