Forum Discussion
Brian_69413
Nimbostratus
Nov 06, 2007iRule not capturing HTTP_REQUEST
I am working on parsing the payload of an HTTP_REQUEST event and encrypting/decrypting usernames/passwords. I am having trouble triggering the iRule for the specified request.
I do a tcpdump on the LTM to capture the request and I see a POST from the client to the server to a specific authentication URL. This should be captured in the HTTP_REQUEST event, correct? Having no success, I simplified the process by simply logging the [HTTP::method]. All I see are GET's when clicking the same link. Also, I tried logging the [HTTP::header names] and it is not the same list as the one I see in the dump.
Does anyone have any ideas why this iRule is not "seeing" the POST? Could this be in the [TCP::payload]? I tried logging the [TCP::payload] and got jibberish(at least to me ):D)
I can show code if you would like, but I think it might not be relevant to the problem at hand.
Any help would be appreciated, Thanks!
- Brian_69413
Nimbostratus
Perhaps some insight into where the iRule "intercepts" the request would be helpful. Does anyone know whether the tcpdump facility will get the packets first or will the iRule for the HTTP_REQUEST event? - hoolio
Cirrostratus
I believe that the output from tcpdump would be written before LTM parses the HTTP headers and the HTTP_REQUEST event is triggered. Maybe a developer could comment on that? - Brian_69413
Nimbostratus
Thanks for the reply, below is the code, I will have to get back to you on the others. I am encrypting the username/password from the server and decrypting on the way back from the client. I have it limited to my IP for now as I do not want to interrupt others. It is the Client communication(POST) that I am not seeing, although it looks as if it is in the same TCP connection.when RULE_INIT { SET THE ENCRYPTION KEY set ::key [AES::key 128] } when HTTP_REQUEST { LIMIT TO A TEST PC's IP if { ([IP::client_addr] equals "x.x.x.x") } { COLLECT THE CONTENT switch [HTTP::method] { "GET" { log local0. "GET Request" } "POST" { log local0. "POST Request" if { [HTTP::header Content-Type] eq "application/x-www-form-urlencoded" } { HTTP::collect [HTTP::header Content-Length] } } } } } when HTTP_REQUEST_DATA { TESTING set namevals [split [HTTP::payload] "&"] for {set i 0} {$i < [llength $namevals]} {incr i} { set params [split [lindex $namevals $i] "="] log local0. " [lindex $params 0] : [lindex $params 1]" } } when HTTP_RESPONSE { WHEN SERVER SENDS PASSWORD, START COLLECTING if { [IP::client_addr] equals "x.x.x.x" } { if { [HTTP::header "Content-Length"] == 733 } { HTTP::collect [HTTP::header Content-Length] } } } when HTTP_RESPONSE_DATA { EXTRACT USERNAME AND PASSWORD set user [findstr [HTTP::payload] "j_username\" value=\"" 19 "\""] set pass [findstr [HTTP::payload] "j_password\" value=\"" 19 "\""] ENCRYPT THE USERNAME AND PASSWORD set encrypted_user [b64encode [AES::encrypt $::key $user]] set encrypted_pass [b64encode [AES::encrypt $::key $pass]] DETERMINE THE LOCATION AND LENGTH OF THE USERNAME set user_begin [string first "j_username" [HTTP::payload] 0] set user_begin [incr user_begin 19] set user_end [string first "\"" [HTTP::payload] $user_begin] set user_end [incr user_end -1] set user_len [string length [string range [HTTP::payload] $user_begin $user_end]] REPLACE THE USERNAME HTTP::payload replace $user_begin $user_len $encrypted_user DETERMINE THE LOCATION AND LENGTH OF THE PASSWORD set encrypt_user_len [string length $encrypted_user] set encrypt_user_end [incr user_begin $encrypt_user_len] set pass_begin [string first "j_password" [HTTP::payload] $encrypt_user_end] set pass_begin [incr pass_begin 19] set pass_end [string first "\"" [HTTP::payload] $pass_begin] set pass_end [incr pass_end -1] set pass_len [string length [string range [HTTP::payload] $pass_begin $pass_end]] REPLACE THE PASSWORD HTTP::payload replace $pass_begin $pass_len $encrypted_pass HTTP::release }
- hoolio
Cirrostratus
Can you add a few log statements to the rule?when CLIENT_ACCEPTED { if { ([IP::client_addr] equals "x.x.x.x") } { log local0. "client [IP::client_addr]:[TCP::client_port] connected" } } when HTTP_REQUEST { log local0. "client [IP::client_addr]:[TCP::client_port] -> [HTTP::method] -> [HTTP::host][HTTP::uri] (HTTP v[HTTP::version])"
log local0. "client [IP::client_addr]:[TCP::client_port] -> \ [HTTP::method] -> Content-Type: [HTTP::header value Content-Type], \ Content-Length: [HTTP::header value Content-Length], \ Transfer-Encoding: [HTTP::header value Transfer-Encoding]"
- Brian_69413
Nimbostratus
I added the logging. It only confirms what I saw before, the tcpdump shows a POST and the iRule logs only GET's - Deb_Allen_18Historic F5 AccountYour iRule looks correct to me.
- Brian_69413
Nimbostratus
Turns out the assumption was correct that this post was on a different TCP connection. Same server, new connection(new app, I guess you could say) - Paula_Livingsto
Altocumulus
Interesting post. I'm pretty certain tcpdump is way ahead of any input parsing on the LTM. I ran across this post after experiencing a similar problem myself and was able to use tcpdump as a clean input from which to troubleshoot.
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