Forum Discussion
Xiaohui_Chen
Employee
Jun 22, 2019SNAT not working between two virtuals
Set up a bigip on aws with three servers at the backend. To preserve source IP, ppv2 support on AWS NLB is enabled. There is an irule on the first virtual to parse out the source address from ppv2 header and does a SNAT. Then the traffic is forwarded to virtual2 with "virtual stage_2". The setup is working without the SNAT. If SNAT is added, the traffic never reach the second virtual. Here is the setting
virtual 1
proxy TCP {
listen 0.0.0.0 $service(https) prefixlen 0 {
proto $ipproto(tcp)
name _vs_https
}
profile basic_http
profile sslc
clientside TCP SSL HTTP
serverside TCP HTTP
rule ppv2_snat_rule
}
virtual 2
# HTTPS Virtual
proxy TCP {
listen 0.0.0.0 4431 prefixlen 0 {
proto $ipproto(tcp)
name "vs_https"
}
profile basic_http
use pool pool_http
clientside TCP HTTP AVR
serverside TCP HTTP AVR
rule http_server_rule
}
irule. It is based on the one posted the Proxy Protocol receiver on devcenter
rule ppv2_snat_rule {
#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
when RULE_INIT {
set static::allowProxyV1 1
set static::allowProxyV2 1
set static::allowNoProxy 1
}
when CLIENT_ACCEPTED {
TCP::collect
}
when CLIENT_DATA {
set tcplen [TCP::payload length]
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] @13H2S v2_addressFamilyTransportProtocol v2_tlv_id
set v2_remainderLen "[expr {$v2_tlv_id & 0xffff}]"
set v2_payloadindex "[expr $v2_remainderLen + 16]"
log "TLV - [expr {$v2_tlv_id & 0xffff}]"
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 sourceAddress "[expr {$v2_sourceAddress1 & 0xff}].[expr {$v2_sourceAddress2 & 0xff}].[expr {$v2_sourceAddress3 & 0xff}].[expr {$v2_sourceAddress4 & 0xff}]"
set destAddress "[expr {$v2_destAddress1 & 0xff}].[expr {$v2_destAddress2 & 0xff}].[expr {$v2_destAddress3 & 0xff}].[expr {$v2_destAddress4 & 0xff}]"
set sourcePort [expr {$v2_sourcePort1 & 0xffff}]
set destPort [expr {$v2_destPort1 & 0xffff}]
log "Proxy Protocol v2 conn from [IP::client_addr]:[TCP::client_port] for an IPv4 Stream from Src: $sourceAddress:$sourcePort to Dst: $destAddress:$destPort"
TCP::payload replace 0 $v2_payloadindex ""
set proxy_xff 1
} elseif {$v2_addressFamilyTransportProtocol == 21} {
binary scan [TCP::payload] @16H4H4H4H4H4H4H4H v2_v6sourceAddress1 v2_v6sourceAddress2 v2_v6sourceAddress3 v2_v6sourceAddress4 v2_v6sourceAddress5 v2_v6sourceAddress6 v2_v6sourceAddress7 v2_v6sourceAddress8
binary scan [TCP::payload] @32H4H4H4H4H4H4H4H 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 sourcePort [expr {$v2_v6sourcePort1 & 0xffff}]
set destPort [expr {$v2_v6destPort1 & 0xffff}]
set sourceAddress "$v2_v6sourceAddress1:$v2_v6sourceAddress2:$v2_v6sourceAddress3:$v2_v6sourceAddress4:$v2_v6sourceAddress5:$v2_v6sourceAddress6:$v2_v6sourceAddress7:$v2_v6sourceAddress8"
set destAddress "$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: $sourceAddress:$sourcePort to Dst: $destAddress:$destPort"
TCP::payload replace 0 $v2_payloadindex ""
set proxy_xff 1
} else {
log "v2_proxy conn from [IP::client_addr]:[TCP::client_port] - possible unknown/malformed transportProtocol or addressFamily"
reject
}
} elseif {$v2_verCommand == 20}{
reject
} 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"
set proxy_xff 0
} else {
reject
log "Connection rejected from [IP::client_addr]:[TCP::client_port] due to lack of PROXY protocol header"
}
TCP::release
}
when HTTP_REQUEST {
log "http request"
if { $proxy_xff == 1 } {
log "snat to $sourceAddress"
snat $sourceAddress $sourcePort
}
set vs_stage2 [string range [virtual name] 1 end]
log "Set virtual to $vs_stage2"
virtual $vs_stage2
}
}
No RepliesBe the first to reply
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects