haproxy
2 TopicsProxy Protocol Receiver
Problem this snippet solves: iRule for BIG-IP to receive PROXY protocol (v1 and v2) header in TCP Payload and remove it before forwarding remaining TCP Payload to server side pool member. How to use this snippet: Enable iRule on virtual server where upstream proxy will be sending PROXY header. Testing done using proxied IPv6 and IPv4 HTTP connections from HAProxy using Proxy Protocol v1 and v2. Use of client or server SSL profiles slated for testing and validation since ELB promotes use of Proxy Protocol as a solution for customers that don't want to have ELB terminate HTTPS traffic but do want servers to see original IP addresses. Code : #PROXY Protocol Receiver iRule # c.jenison at f5.com (Chad Jenison) # v2.0 - Added support for PROXY Protocol v2, control for v1,v2 or lack of proxy via static:: variables set in RULE_INIT # v2.1 - Fix for skipping bytes in v2 code when RULE_INIT { set static::allowProxyV1 0 set static::allowProxyV2 1 set static::allowNoProxy 0 } when CLIENT_ACCEPTED { TCP::collect } when CLIENT_DATA { binary scan [TCP::payload 12] H* v2_protocol_sig if {$static::allowProxyV1 && [TCP::payload 0 5] eq "PROXY"} { set proxy_string [TCP::payload] set proxy_string_length [expr {[string first "\r" [TCP::payload]] + 2}] scan $proxy_string {PROXY TCP%s%s%s%s%s} tcpver srcaddr dstaddr srcport dstport log "Proxy Protocol v1 conn from [IP::client_addr]:[TCP::client_port] for an IPv$tcpver stream from Src: $srcaddr:$srcport to Dst: $dstaddr:$dstport" TCP::payload replace 0 $proxy_string_length "" } elseif {$static::allowProxyV2 && $v2_protocol_sig eq "0d0a0d0a000d0a515549540a"}{ binary scan [TCP::payload] @12H* v2_proxyheaderremainder binary scan [TCP::payload] @12H2H* v2_verCommand v2_remainder if {$v2_verCommand == 21}{ binary scan [TCP::payload] @13H2 v2_addressFamilyTransportProtocol if {$v2_addressFamilyTransportProtocol == 11} { binary scan [TCP::payload] @16ccccccccSS v2_sourceAddress1 v2_sourceAddress2 v2_sourceAddress3 v2_sourceAddress4 v2_destAddress1 v2_destAddress2 v2_destAddress3 v2_destAddress4 v2_sourcePort1 v2_destPort1 set v2_sourceAddress "[expr {$v2_sourceAddress1 & 0xff}].[expr {$v2_sourceAddress2 & 0xff}].[expr {$v2_sourceAddress3 & 0xff}].[expr {$v2_sourceAddress4 & 0xff}]" set v2_destAddress "[expr {$v2_destAddress1 & 0xff}].[expr {$v2_destAddress2 & 0xff}].[expr {$v2_destAddress3 & 0xff}].[expr {$v2_destAddress4 & 0xff}]" set v2_sourcePort [expr {$v2_sourcePort1 & 0xffff}] set v2_destPort [expr {$v2_destPort1 & 0xffff}] log "Proxy Protocol v2 conn from [IP::client_addr]:[TCP::client_port] for an IPv4 Stream from Src: $v2_sourceAddress:$v2_sourcePort to Dst: $v2_destAddress:$v2_destPort" binary scan [TCP::payload] @14S address_size set skip_bytes [expr 16 + $address_size] TCP::payload replace 0 $skip_bytes "" } elseif {$v2_addressFamilyTransportProtocol == 21} { binary scan [TCP::payload] @16H4H4H4H4H4H4H4H4 v2_v6sourceAddress1 v2_v6sourceAddress2 v2_v6sourceAddress3 v2_v6sourceAddress4 v2_v6sourceAddress5 v2_v6sourceAddress6 v2_v6sourceAddress7 v2_v6sourceAddress8 binary scan [TCP::payload] @32H4H4H4H4H4H4H4H4 v2_v6destAddress1 v2_v6destAddress2 v2_v6destAddress3 v2_v6destAddress4 v2_v6destAddress5 v2_v6destAddress6 v2_v6destAddress7 v2_v6destAddress8 binary scan [TCP::payload] @48SS v2_v6sourcePort1 v2_v6destPort1 set v2_v6sourcePort [expr {$v2_v6sourcePort1 & 0xffff}] set v2_v6destPort [expr {$v2_v6destPort1 & 0xffff}] set v2_v6sourceAddress "$v2_v6sourceAddress1:$v2_v6sourceAddress2:$v2_v6sourceAddress3:$v2_v6sourceAddress4:$v2_v6sourceAddress5:$v2_v6sourceAddress6:$v2_v6sourceAddress7:$v2_v6sourceAddress8" set v2_v6destAddress "$v2_v6destAddress1:$v2_v6destAddress2:$v2_v6destAddress3:$v2_v6destAddress4:$v2_v6destAddress5:$v2_v6destAddress6:$v2_v6destAddress7:$v2_v6destAddress8" log "Proxy Protocol v2 conn from from [IP::client_addr]:[TCP::client_port] for an IPv6 Stream from Src: $v2_v6sourceAddress:$v2_v6sourcePort to Dst: $v2_v6destAddress:$v2_v6destPort" binary scan [TCP::payload] @14S address_size set skip_bytes [expr 16 + $address_size] TCP::payload replace 0 $skip_bytes "" } else { log "v2_proxy conn from [IP::client_addr]:[TCP::client_port] - possible unknown/malformed transportProtocol or addressFamily" reject } } elseif {$v2_verCommand == 20}{ log "Proxy Protocol v2 and LOCAL command from [IP::client_addr]:[TCP::client_port]; skipping" binary scan [TCP::payload] @14S address_size set skip_bytes [expr 16 + $address_size] TCP::payload replace 0 $skip_bytes "" binary scan [TCP::payload] H* local_remainder } else { log "Proxy Protocol Protocol Signature Detected from [IP::client_addr]:[TCP::client_port] but protocol version and command not legal; connection reset" reject } } elseif {$static::allowNoProxy} { log "Connection from [IP::client_addr]:[TCP::client_port] allowed despite lack of PROXY protocol header" } else { reject log "Connection rejected from [IP::client_addr]:[TCP::client_port] due to lack of PROXY protocol header" } TCP::release } Tested this on version: 12.05.1KViews0likes9CommentsURI HASH persistence based on URI depth and string length
Problem this snippet solves: When dealing with caching or AV analysis systems, we may need to define a static persistence method to maximize hits and performances on backend servers. How to use this snippet: Installation You just need to assign the irule to a standard Virtual Server. The VS require at least an http profile and ssl profiles (if doing ssl offloafing or ssl bridging) Variables static::lb_depth - define a subset of the path to use for HASH calculation static::lb_len - define the number of chars to retrieve in the path for HASH calculation static::timeout - define the timeout of the persistence record Features Universal persistence Persistence using URI Hash Specify a depth and/or a string length to get a subset of the URI for the Hash calculation Code : when RULE_INIT { # define the depth of the path that will be used for HASH calculation set static::lb_depth 5 # lb_len variable should be set to 0 if you don't want to use it set static::lb_len 0 set static::timeout 3600 } when HTTP_REQUEST { # initialize required variables set path [string tolower [HTTP::path]] set depth [URI::path [HTTP::uri] depth] # define the depth of the path for hash calculation if { $depth < $static::lb_depth } { set depth_path [HTTP::path] } else { set depth_path [URI::path [HTTP::uri] 1 $static::lb_depth] } set len [string length $depth_path] # define the chars length to be processed for hash calculation if { $static::lb_len > 0 and $static::lb_len < $len } { binary scan [sha1 [string range $depth_path 0 $static::lb_len-1]] w1 key } else { binary scan [sha1 $depth_path] w1 key } persist uie $key $static::timeout } Tested this on version: 11.3361Views0likes0Comments