Proxy Protocol iRule support for L4 routes¶
Overview¶
F5 BIG-IP Next for Kubernetes supports Proxy Protocol iRules for Layer 4 (L4) routes. This lets you pass client connection information — such as IP addresses and port numbers — to backend servers when traffic passes through a load balancer.
This feature supports both TCP and UDP protocols and uses the Kubernetes Gateway API.
Before you begin¶
Before you configure Proxy Protocol iRule support, make sure you have:
A working BIG-IP Next for Kubernetes deployment
Access to the Kubernetes Gateway API
Permissions to create and apply Kubernetes resources in your cluster
How it works¶
TCP routes¶
By default, BIG-IP Next for Kubernetes creates a FastL4 profile for TCP L4 routes. FastL4 does not support the TCP::respond iRule command in the SERVER_CONNECTED event that Proxy Protocol iRules require.
When you attach a Proxy Protocol iRule to a TCP L4 route, BIG-IP Next for Kubernetes checks the iRule for the TCP::respond command.
Note: If the
TCP::respondcommand is present and the acceleration mode is set todisabled, BIG-IP Next for Kubernetes switches the virtual server from FastL4 to a standard TCP profile. This lets the iRule run as expected.
If the TCP::respond command is not present, BIG-IP Next for Kubernetes applies a FastL4 profile instead.
When you attach more than one iRule to a route, BIG-IP Next for Kubernetes treats the route as standard if any of the iRules contain the TCP::respond command.
UDP routes¶
Proxy Protocol iRules work with UDP L4 routes without any changes. BIG-IP Next for Kubernetes creates a standard UDP virtual server, which supports the iRule as expected.
Configure Proxy Protocol iRule support for L4 routes¶
The steps below show you how to set up Proxy Protocol iRule support for TCP and UDP L4 routes.
Step 1: Create the iRule¶
Create an F5BigCneIrule resource that contains the Proxy Protocol iRule logic.
apiVersion: k8s.f5net.com/v1
kind: F5BigCneIrule
metadata:
name: proxy-irule
namespace: spk-app
spec:
iRule: |
# Proxy Protocol iRule
# v1.0 - 21/02/2023
proc encode { version protocol src_ip dst_ip src_port dst_port} {
if {$version eq 4} {
# block containing the protocol signature : 12 bytes
# source IPv6 address : 32 bytes
# Destination IPv6 address : 32 bytes
# add extra 0 to prevent issues with :: at the beginning or end of address
set count [expr {8 - [string length $ipv6_compressed] + \
[string length [string map {: {}} $ipv6_compressed]]}]
set ipv6_temp "0[string map [list :: :[string repeat 0:0 $count]] $ipv6_compressed]"
# Destination port : 2 bytes
switch -- $protocol {
6 {
append proxy_addr [binary format SS $src_port $dst_port]
set fam_proto "[expr {$version == 4 ? 1 : 2}]1"
}
17 {
append proxy_addr [binary format SS $src_port $dst_port]
set fam_proto "[expr {$version == 4 ? 1 : 2}]2"
}
default {
set fam_proto "[expr {$version == 4 ? 1 : 2}]0"
}
}
}
}
when CLIENT_ACCEPTED {
if { [IP::protocol] == 6 } {
set proxy_hdr_v2 [call encode [IP::version] [IP::protocol] \
[IP::remote_addr] [IP::local_addr] [TCP::remote_port] [TCP::local_port]]
} else {
set proxy_hdr_v2 [call encode [IP::version] [IP::protocol] \
[IP::remote_addr] [IP::local_addr] [UDP::remote_port] [UDP::local_port]]
}
}
when SERVER_CONNECTED {
if { [IP::protocol] == 6 } {
TCP::respond $proxy_hdr_v2
} else {
UDP::respond $proxy_hdr_v2
}
}
Step 2: Create the Gateway¶
Create a Gateway resource that defines the entry point for your traffic.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tcp-gw
namespace: spk-app
spec:
addresses:
- type: IPAddress
value: 10.151.0.151
- type: IPAddress
value: 10.152.0.152
- type: IPAddress
value: 10.153.0.153
gatewayClassName: gateway-class
listeners:
- allowedRoutes:
kinds:
- kind: L4Route
namespaces:
from: Same
name: ubuntu
port: 8000
protocol: TCP
Step 3: Create the L4 route¶
Create an L4Route resource that links your backend service to the Gateway.
apiVersion: gateway.networking.k8s.io/v1
kind: L4Route
metadata:
name: ubuntu
namespace: spk-app
spec:
protocol: TCP
pvaAccelerationMode: "disabled"
parentRefs:
- name: tcp-gw
sectionName: ubuntu
rules:
- backendRefs:
- name: ubuntu
port: 80
Step 4: Apply the policy¶
Create a NetPolicy resource to attach the iRule to the route.
apiVersion: gateway.k8s.f5.com/v1alpha1
kind: NetPolicy
metadata:
name: proxy-net-policy
namespace: spk-app
spec:
extensionRefs:
- name: proxy-irule
targetRefs:
- name: tcp-gw
sectionName: ubuntu
Step 5: Create the backend service¶
Create a Service resource for your backend application.
apiVersion: v1
kind: Service
metadata:
labels:
app: ubuntu
name: ubuntu
namespace: spk-app
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: tcp
port: 80
protocol: TCP
targetPort: 80
selector:
app: ubuntu
sessionAffinity: None
type: ClusterIP
Step 6: Deploy the backend application¶
Create a Deployment resource for your backend application.
Note: This code is only a sample of the application deployment. You must already have an application with the proxy protocol option enabled for deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ubuntu
spec:
selector:
matchLabels:
app: ubuntu
replicas: 1
template:
metadata:
labels:
app: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
ports:
- containerPort: 80
command:
- "/bin/bash"
- "-c"
args:
- sysctl -w net.ipv6.conf.all.disable_ipv6=1 &&
sysctl -w net.ipv6.conf.default.disable_ipv6=1 &&
sysctl -w net.ipv6.conf.lo.disable_ipv6=1 &&
apt update &&
apt install -y iproute2 iputils-ping tcpdump net-tools lighttpd netcat-openbsd curl wget &&
service lighttpd start &&
sleep 365d
securityContext:
privileged: true
Note: Proxy Protocol is not enabled by default on lighttpd. You must update your deployment manually to enable Proxy Protocol on lighttpd. Following is an example of updates to be made to the lighttpd.conf file to enable proxy protocol:
server.modules += ( "mod_accesslog", )
accesslog.filename = "/var/log/lighttpd/access.log"
server.modules += ( "mod_extforward" )
extforward.hap-PROXY = "enable"
extforward.forwarder = ( "all" => "trust" )
# "proxy" indicates that the trusted proxy sends a PROXY protocol header
Verify your configuration¶
After you apply all resources, verify that your configuration works as expected:
Check that all resources are running in the
spk-appnamespace.Send test traffic to the Gateway IP address on port 8000.
Confirm that the backend server receives the Proxy Protocol header with the correct client IP address and port.