Forum Discussion

Yaniv_99962's avatar
Yaniv_99962
Icon for Nimbostratus rankNimbostratus
Mar 22, 2011

SNAT persistency

Hi F5 experts.

 

 

i want to achieve the following:

 

1) I want the F5 to choose an IP in round-robin manner from a SNAT pool and to persist using the same IP from the SNAT pool in case an HTTP header called "Username" value is the same.

 

2) Every HTTP request which will come in less than 5 minutes with the same "username" header value should receive the same SNAT IP from the pool. additionally that SNAT IP must be marked as "used" so that no other "username" will get this SNAT IP (unless 5 minutes has passed with no HTTP request with the same username value. after the 5 minutes that SNAT IP can be available again in the pool).

 

3) I want the F5 to chop off the username header before forwarding the HTTP request using the SNAT IP.

 

4) I want the F5 to log every NAT action it does to some syslog server (like: = )

 

 

 

Example:

 

SNAT pool is 192.118.0.0/16 and the Username possible values can be any string.

 

HTTP request arrives from source IP 172.16.1.1 with header “Username: aaa”

 

F5 will replace the source IP 172.16.1.1 to be 192.118.0.1

 

After less than 5 minutes another HTTP request arrives from source IP 172.16.1.1 with header “Username: aaa”

 

F5 will replace the source IP 172.16.1.1 to be 192.118.0.1

 

After less than 5 minutes HTTP request arrives from source IP 172.16.1.1 with header “Username: bbb”

 

F5 must not replace the source IP to be 192.118.0.1 as it is taken by username aaa.

 

 

After more than 5 minutes another HTTP request arrives from source IP 172.16.1.1 with header “Username: aaa”

 

F5 can replace the source IP 172.16.1.1 to be other than 192.118.0.1 (for example: 192.118.0.2)

 

 

 

 

Hope it is clear enough, if not please comment.

 

 

 

Thanks in advance,

 

Yaniv

 

  • WOW! I will look into that and give it a try.

    In the meantime I found some bugs in our iRule:

    1. The assignment of snatpool_member as a key to a username doesnt get refreshed. so there are case where an already assigned SNAT IP will be assign to other username.

    2. in case there are no more available IPs in the SNAT pool the F5 would still assign the last IP in the pool.

    I updated the iRule to address those 2 issues.

    Would appreciate if you have ideas for more improvements (maybe it's better to split to 2 tables?)

     when HTTP_REQUEST { 
    Set var with the header name used to persist the SNAT IP.
    set headername "username" 
    Set var with the value of the header name used to persist the SNAT IP.
    set headervalue [HTTP::header $headername] 
    Set var with the data group name (class) that contains all the SNAT IPs to choose from (data group must be of type string, and include only strings without values).
    set clname "snatpool_example" 
    Set var with the search id which is used to search the data group. 
    set searchID [class startsearch $clname ] 
    Set var with the SNAT pool name. the SNAT pool must contain same members as the data group.
    set mysnatpool "snatpool_example" 
    The snattable var contains the snattable name, if you want to call it something else change it here. 
    set snattable "snattable"
    Set var used for exiting the while loop in case an available SNAT IP is found.
    set match 0 
    Set var used for aging time of each table entry
    set timeout 180
    Check to see if the headervalue already has a SNAT IP .
    if { [table lookup -subtable $snattable $headervalue] ne "" } { 
    Headervalue already has SNAT IP --> persist using same SNAT IP and restart entry aging time (no "-notouch").
    set snatpool_member [table lookup -subtable $snattable $headervalue]
    table set -subtable $snattable $snatpool_member $headervalue $timeout
    set match 1
    } else { 
    Headervalue doesn't have SNAT IP --> choose new available SNAT IP from pool.
    Go over the data group that contains all the SNAT IPs until an available IP is found.
    while { ([class anymore $clname $searchID]) and ($match eq 0) } { 
    Set var with the next element (SNAT IP) from the data group.
    set snatpool_member [class nextelement -name $clname $searchID] 
    Assign the SNAT IP only if it is not already assigned to other.
    if { [table lookup -subtable $snattable -notouch $snatpool_member] eq "" } { 
    add snat assignement to tables
    table set -subtable $snattable $snatpool_member $headervalue $timeout
    table set -subtable $snattable $headervalue $snatpool_member $timeout
    local log entry this should be changed to a highspeed log off box. 
    log local0.info "SNAT assignment: $headervalue --> $snatpool_member"
    exiting the while loop as an available SNAT IP is found.
    set match 1 
    } 
    } 
    }
    if {[class anymore $clname $searchID] eq 1 } {
    snatpool $mysnatpool member $snatpool_member 
    log local0.info "SNAT action: $headervalue --> $snatpool_member"
    HTTP::header remove $headername
    } else {
    log local0.info "There are no more available SNAT IPs!!!"
    }
    }