New to Voyager? Please start here.
Frontend rules specify a set of rules that are applied to HAProxy frontend configuration.
The set of keywords are from here https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.1.
Only frontend sections can be applied here. It is up to user to provide valid sets of rules.
This allows acls or other options in frontend sections in HAProxy config. Frontend rules will be mapped to
spec.rules according to HAProxy port.
apiVersion: voyager.appscode.com/v1beta1 kind: Ingress metadata: name: test-ingress namespace: default spec: frontendRules: - port: 80 # Applies all the rule in frontend section for port 80 rules: - timeout client 5s # Set the maximum inactivity time on the client side. - port: 9898 # Applies all the rule in frontend section for port 9898 rules: - timeout client 500s # Set the maximum inactivity time on the client side. rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: '80' - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: '80' - host: tcp.bar.com tcp: port: '9898' backend: serviceName: tcp-service servicePort: '50077'
This example ingress shows how to configure frontend rules in ingress resource. All the frontend rules for port 80 will be applied to all the backends which listens to port 80.
Example: Whitelist IP Addresses using Frontend Rules
This example demonstrates How to whitelist some IP addresses for a backend using frontend rule.
apiVersion: voyager.appscode.com/v1beta1 kind: Ingress metadata: name: test-ingress namespace: default annotation: ingress.appscode.com/keep-source-ip: "true" spec: frontendRules: - port: 80 rules: # you can use IP addresses but also networks in the src acl. Both 192.168.20.0/24 and 192.168.10.3 work. - acl network_allowed src 220.127.116.11 18.104.22.168 - block if !network_allowed - port: 9898 rules: - acl network_allowed src 22.214.171.124 126.96.36.199/27 - tcp-request connection reject if !network_allowed rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: '80' - host: tcp.bar.com tcp: port: '9898' backend: serviceName: tcp-service servicePort: '50077'
Why does not IP whitelisting work in LoadBalancer type Ingress in AWS?
The PROXY protocol dictates the layer 3/4 addresses of the incoming connection to be used everywhere an address is used, with the only exception of "tcp-request connection" rules which will only see the real connection address.
The issue is that
keep-source-ip: true annotation will enable
accept-proxy option in HAProxy. But HAProxy does not use the IP received via PROXY protocol with
tcp-request connection reject. Instead HAProxy uses the real IP it detected (which is the IP address of ELB in this case). This is actually an important security feature. Otherwise, any one can open a TCP connection and spoof their IP using the PROXY protocol header and by pass the whitelist. This works with HTTP on the backend rules, because in HTTP mode, HAPproxy checks the header and by using
accept-proxy, we have told HAProxy to trust the header in PROXY protocol. So, for TCP connections that are behind ELB, you need to reject connection at ELB layer using
spec.loadBalancerSourceRanges in Ingress. If you were running a bare-metal cluster, where traffic directly hits HAProxy,
tcp-request connection reject will behave as expected.