New to Voyager? Please start here.
Frontend Rules
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/v1
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:
service:
name: s1
port:
number: 80
- host: bar.foo.com
http:
paths:
- backend:
service:
name: s2
port:
number: 80
- host: tcp.bar.com
tcp:
port: 9898
backend:
service:
name: tcp-service
port:
number: 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/v1
kind: Ingress
metadata:
name: test-ingress
namespace: default
annotations:
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 128.196.0.5 128.196.0.5
- block if !network_allowed
- port: 9898
rules:
- acl network_allowed src 20.30.40.50 8.9.9.0/27
- tcp-request connection reject if !network_allowed
rules:
- host: foo.bar.com
http:
paths:
- backend:
service:
name: s1
port:
number: 80
- host: tcp.bar.com
tcp:
port: 9898
backend:
service:
name: tcp-service
port:
number: 50077
Example: ACL from file
This example demonstrates how to use additional files with frontend rules. First create a configmap containing whitelisted IPs:
apiVersion: v1
kind: ConfigMap
metadata:
name: whitelist-config
namespace: default
data:
whitelist.lst: 192.168.1.1/32 192.168.2.1/32 192.168.0.1/24
Then mount this configmap using spec.configVolumes
and specify the file path using frontend rules.
apiVersion: voyager.appscode.com/v1
kind: Ingress
metadata:
name: test-ingress
namespace: default
annotations:
ingress.appscode.com/keep-source-ip: "true"
spec:
configVolumes:
- name: whitelist-vol
configMap:
name: whitelist-config
mountPath: /etc/haproxy
frontendRules:
- port: 80
rules:
- acl network_allowed src -f /etc/haproxy/whitelist.lst
- block if !network_allowed
rules:
- host: foo.bar.com
http:
paths:
- backend:
service:
name: s1
port:
number: 80
See here for complete example of configVolumes
.
FAQ
Why does not IP whitelisting work in LoadBalancer type Ingress in AWS?
From HAProxy official documentation:
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, HAProxy 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.