Proxy protocol

Preserve connection information such as the client IP address for traffic that goes through your gateway listener.

For more information, see the following resources.

If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.

Before you begin

This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started, and that your Kubernetes context is set to the cluster you store your Gloo config in (typically the management cluster). If you have different names, make sure to update the sample configuration files in this guide.

Follow the getting started instructions to:

  1. Set up Gloo Gateway in a single cluster.
  2. Deploy sample apps.
  3. Configure an HTTP listener on your gateway and set up basic routing for the sample apps.

Configure proxy protocol policies

You can apply a proxy protocol policy at the listener level. For more information, see Applying policies.

Review the following sample configuration file.

apiVersion: trafficcontrol.policy.gloo.solo.io/v2
kind: ProxyProtocolPolicy
metadata:
  annotations:
    cluster.solo.io/cluster: ""
  name: haproxy-policy
  namespace: bookinfo
spec:
  applyToListeners:
  - port:
      number: 443
    virtualGateway:
      cluster: cluster-1
      name: istio-ingressgateway
      namespace: bookinfo
  config:
    enableProxyProtocol: true

Review the following table to understand this configuration. For more information, see the API docs.

Setting Description
spec.applyToListeners Select the virtual gateways and ports to apply the policy. You must have a Gloo VirtualGateway custom resource to select. If you do not specify a valid listener, the policy takes no effect.
spec.config.enabledProxyProtocol To enable the proxy protocol, set to true. Now, traffic that goes through the selected listeners preserves connection information such as the client IP address.

Verify proxy protocol policies

  1. Send a request to the ratings app. The request succeeds, but you do not have any PROXY TCP4 information about the originating client IP address.

    curl -vik --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1
    
    curl -vik --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1
    

    Example output:

    * Added www.example.com:443:35.xxx.xxx.xx1 to DNS cache
    * Hostname www.example.com was found in DNS cache
    *   Trying 35.xxx.xxx.xx1...
    * TCP_NODELAY set
    * Connected to www.example.com (35.xxx.xxx.xx1) port 443 (#0)
    * ALPN, offering h2
    ...
    
  2. To send the client IP address as a header in the request, you can include the --haproxy-protocol flag. However, you get an error because proxy protocol is not yet enabled.

    curl -vik --haproxy-protocol --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1
    
    curl -vik --haproxy-protocol --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1
    
    Example output:

    curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.example.com:443 
    
  3. Apply the proxy protocol policy to the ingress gateway in your cluster.

    kubectl apply -f- <<EOF
    apiVersion: trafficcontrol.policy.gloo.solo.io/v2
    kind: ProxyProtocolPolicy
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: haproxy-policy
      namespace: bookinfo
    spec:
      applyToListeners:
      - port:
          number: 443
        virtualGateway:
          cluster: cluster-1
          name: istio-ingressgateway
          namespace: bookinfo
      config:
        enableProxyProtocol: true
    EOF
    
  4. Send the request again with the --haproxy-protocol flag. This time, you see the PROXY TCP4 information with the original client IP address, such as 192.xxx.x.xx in the following example.

    curl -vik --haproxy-protocol --resolve www.example.com:80:${INGRESS_GW_IP} http://www.example.com:80/ratings/1
    
    curl -vik --haproxy-protocol --resolve www.example.com:443:${INGRESS_GW_IP} https://www.example.com:443/ratings/1
    

    Example output:

       * Added www.example.com:443:35.xxx.xxx.xx1 to DNS cache
       * Hostname www.example.com was found in DNS cache
       *   Trying 35.xxx.xxx.xx1...
       * TCP_NODELAY set
       * Connected to www.example.com (35.xxx.xxx.xx1) port 443 (#0)
       > PROXY TCP4 192.xxx.x.xx 35.xxx.xxx.xx1 65273 443
       * ALPN, offering h2
       

Cleanup

You can optionally remove the resources that you created as part of this guide.

kubectl delete ProxyProtocolPolicy haproxy-policy -n bookinfo