tcl
30 TopicsiRule [string range...] not chunking data properly
I have an irule (much of which I found here) that is to gather some much needed troubleshooting data I need in regards to the headers and payload I have coming in. The payload is obvisouly too large for a single log line so this was supposed to chunk it into manageable bytes. I had to make some modifications to the original irule which did not work, but now it is working, sort of. It logs the first 900 bytes as it should, then something happens and skips a bunch, and then logs the final bytes of data. I can't understand why it's not grabbing either the proper amount of data or failing to output this second chunk of missing data before making its final loop. iRule is here: when RULE_INIT { # Log debug to /var/log/ltm? 1=yes, 0=no set static::payload_dbg 1 # Limit payload collection to 5Mb set static::max_collect_len 5368709 # Max characters to log locally (must be less than 1024 bytes) # https://clouddocs.f5.com/api/irules/log.html set static::max_chars 900 set static::min_chars 0 } when HTTP_REQUEST { # Only collect POST request payloads if {[HTTP::method] equals "POST"}{ if {$static::payload_dbg}{log local0. "POST request"} # Get the content length so we can request the data to be processed in the HTTP_REQUEST_DATA event. if {[HTTP::header exists "Content-Length"]}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 0 } # content_length of 0 indicates chunked data (of unknown size) if {$content_length > 0 && $content_length < $static::max_collect_len}{ set collect_length $content_length } else { set collect_length $static::max_collect_len } if {$static::payload_dbg}{log local0. "Content-Length: $content_length, Collect length: $collect_length"} foreach aHeader [HTTP::header names] { log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]" } #set payload [HTTP::collect $collect_length] HTTP::collect $collect_length } } when HTTP_REQUEST_DATA { # Log the bytes collected if {$static::payload_dbg}{log local0. "Collected [HTTP::payload length] bytes"} # Log the payload locally if {[HTTP::payload length] < $static::max_chars}{ log local0. "Payload=[HTTP::payload]" } else { # Initialize variables set remaining [HTTP::payload] set position 0 set count 1 set bytes_logged 0 # Loop through and log each chunk of the payload while {[string length $remaining] > $static::min_chars}{ #chunk = 899 set chunk [expr {$position + $static::max_chars -1}] log local0. "Chunk: $chunk" log local0. "Position start: $position" # Get the current chunk to log (subtract 1 from the end as string range is 0 indexed) set current [string range $remaining $position $chunk] log local0. "chunk $count=$current" log local0. "Current chunks bytes: [string length $current]" # Add the length of the current chunk to the position for the next chunk incr position [string length $current] # Get the next chunk to log set remaining [string range $remaining $position end] incr count incr bytes_logged $position log local0. "remaining bytes=[string length $remaining], \$position=$position, \$count=$count, \$bytes_logged=$bytes_logged" } if {[string length $remaining]}{ log local0. "chunk $count=$current" incr bytes_logged [string length $remaining] } log local0. "Logged $count chunks for a total of $bytes_logged bytes" } } when HTTP_RESPONSE { foreach aHeader [HTTP::header names] { log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]" } } The image below shows what I'm talking about - it even says "Oh I found 3 chunks", but I'm only being presented 2. I added some logging around the position, chunk value (aka end position), and bytes logged to help illustrate that it's clearly skipping over something. Any help would be appreciated! ThanksSolved2.1KViews0likes6CommentsAutomated ASM Backup - working bash script now to automate or convert to iCall/tcl
Hi All, I have put together a BASH script that when run performs a backup of the ASM policies and copies them to a remote location. The script runs great and I have had it set as a Cron job in my lab setup to automate the backups. Unfortunately, the business does not want a script running as a Cron job on the F5. I have had it suggested to me to use iCall. I have seen only limited information regarding iCall that was written in a way that someone that has never seen iCall could understand. This got me far enough to understand that iCall runs tcl scripts, not bash scripts! The result being if I was to use iCall I would need to re-write the script completely. I am looking for 2 options here: A means to automate running a bash script on the F5. OR detailed information or getting started with iCall - Better yet, converting bash to tcl. To illustrate my issue, my bash script lives on the F5 and does the following: reads a counter value from a file curl command to the management interface and copies a list of ASM policy details to a txt file. greps the policy names from the original txt file to a new txt file. greps the policy IDs from the original txt file to a new txt file. sets a parameter with the current data and time as the value makes a localDirectory using the data and time parameter as the folder name (this ensures a known date of the backup - also ensures you can re-run and get a new folder on the same day if required) uses curl post and get commands to get the policies from the F5. curl upload-file command to copy files to remote smb location adjust the counter performs a cleanup of any files that were created locally. If I switch over to using iCall the above all needs to be done with tcl - I am not sure how much of that is supported. I have found that "echo" is replaced with "puts", is there a "curl", "cat", etc equivalent? Thanks in advanceSolved1.3KViews0likes6CommentsTrying to convert pwdLastSet to Day Month Year Time format
I'm trying to take session.ad.last.attr.pwdLastSet and convert it to a more user-friendly readable format. I'm very weak on both Active Directory as well as Tcl. Here's what I have so far: if { [ACCESS::policy agent_id] eq "pwdLastSetCheck" } { log local0. "Entered pwdLastSetCheck" set pwdLastSet_epoch [ACCESS::session data get session.ad.last.attr.pwdLastSet] log local0. "epoch time $pwdLastSet_epoch" set clockFormat "[clock format $pwdLastSet_epoch]" log local0. "formatted $clockFormat" } However my output looks like: Apr 3 13:36:30 dmdc-f5-lab01 info tmm1[15679]: Rule /Common/cp_GenerateReset : Event Fired Apr 3 13:36:30 dmdc-f5-lab01 info tmm1[15679]: Rule /Common/cp_GenerateReset : Entered pwdLastSetCheck Apr 3 13:36:30 dmdc-f5-lab01 info tmm1[15679]: Rule /Common/cp_GenerateReset : epoch time 130722168433333201 Apr 3 13:36:30 dmdc-f5-lab01 info tmm1[15679]: Rule /Common/cp_GenerateReset : formatted Thu Jul 11 18:40:01 CDT -152544714 Any idea why my "year" looks like that? Or a better recommendation on how I should code this? thanks in advance, GeoffSolved916Views0likes4Commentstcl logic in SAML Attribute value field possible?
Hi. We're running BigIP as a SAML IDP. Can I somehow issue tcl logic in a SAML attributes? I'm talking about the Access ›› Federation : SAML Identity Provider : Local IdP Services, editing an object, under SAML Attributes. Based on what's in the memberOf attribute, I need to issue as a value either empty string or "SpecificValue". I am familiar with the %{session.variable} construct, but I don't want to clutter the session with more variables if I can avoid it, as that impacts all sessions using our IDP (30 or so federated services on the same VIP and AP). I tried these two approches: %{ set result {} ; if { [mcget {session.ad.last.attr.memberOf}] contains {| CN=SpecificGroup,OU=Resource groups,OU=Groups,DC=Domain,DC=com |}} { set result {SpecificValue} } ; return $result } expr { set result {} ; if { [mcget {session.ad.last.attr.memberOf}] contains {| CN=SpecificGroup,OU=Resource groups,OU=Groups,DC=Domain,DC=com |}} { set result {SpecificValue} } ; return $result } Expected result: An issued claim with the value "" or "SpecificValue" Actual result: An issued claim with the above code as the value As I mentioned, we've set it up using one VIP that is hosting 30 or so services. We're running 16.1.3.1. They are using the same SSO configuration and there's an iRule triggerd at ACCESS_POLICY_AGENT_EVENT, which does some magic to extract issuer and suchlike, and that helps to make decisions later in the Access Policy. It also populates a few session variables under the session.custom namespace for use in the Access Policy. Additional session variables are being populated in the Access Policy, such as resolved manager and their email address. I have looked briefly at the ASSERT::saml functions, but even if it would bepossible to manipulate that way, I wish to keep this set up as stream lined as possible and with as few new "special cases" in an iRule. So while I appreciate pointers along that route as well, I would first of all like to know if there is a way to do it natively in the SAML attribute value field. And if there are any options I have not yet explored here?864Views0likes5Commentscalling a tcl script inside another tcl script on f5
Hi, I have a TCL script which will help me create pool. Now I am creating another tcl script for VIP creation and i want to call the pool creation script inside the VIP creation scripts. is there any way to do that? Thanks, Ashish717Views0likes3CommentsBranch evaluation fails with Rule evaluation error: invalid command name "session.logon.last.username"
Hopefully somebody is able to enlighten me, I have the code below in a branch rule expression of an AD Query element. I get an 'Rule evaluation failed with error: invalid command name "session.logon.last.username"' error. The purpose is to translate an email entered to the matching AD logon username from AD. The AD query succeeds (mail=%{session.logon.last.username}). It looks like the variable assign element is not able to change the session.logon.last.username variable. if { [mcget {session.ad.last.queryresult}] == 1 } { session.logon.last.username = mcget {session.ad.last.attr.sAMAccountName}; return 1; }; return 0; Thanks for sharing your thoughts / ideas.707Views0likes2CommentsiRule to drop Public IP access to DNS Wide-ip
We have wide-ip "abc01.example.com" which we want only to access from internal user (private ip) Do we have iRule to drop only public ip and allow private ip on that wide-ip? So when nslookup to "abc01.example.com" via public ip, F5 drop and when nslookup to "abc01.example.com" via private ip, F5 allow Thank you672Views0likes3CommentsiRule Encode special charaters in URI String
I have an iRule, which is capturing the current URI, and appending it as a variable onto another URL string later on. when HTTP_REQUEST { ... ... set host [HTTP::host] set uri [HTTP::uri] set url "http://internal-address.local.lan/index.html?aup-key=$aupkey&$schema&$host&$uri" } However, if the original URI contains an ampersand itself, it's truncating it at that character so that the full original URI never gets passed on. I'm not overly familiar with TCL, is there an easy way I could encode the uri variable in my code above so that it includes all special characters as well? Many thanks632Views0likes1Commentusing tmsh commands in tcl script
Hey all, I am new to the community as well as f5 technologies in general. Ill give a synopsis as to I am looking to accomplish by using a tmsh script. At my company we do site switches where we fail over applications depending on work thats be done at DC or another. And at times we have failover close to 70 applications. My question is if I was going to use for instance the tmsh cmd: modify gtm pool members modify { :https { disabled } } modify gtm pool members modify { :https { enabled } } In a script how would I got about adding it to the script? Also, I created a test.tcl file in my home directory and executed (Active)(tmos) run cli script but couldnt find the file. How would I execute it? Thanks617Views0likes4CommentsIssue with HTTP_RESPONSE_RELEASE and redirect
Hi everyone, I'm pretty new to F5 and I'vea question, regarding the processing of iRules within the Virtual servers. Basically I have an irule that I use to log the requests and send a line into a pool: timing on when CLIENT_ACCEPTED { set logging_hsl [HSL::open -proto UDP -pool logging] } when HTTP_REQUEST { set requestURI "[HTTP::uri]" set virtual_server_name [getfield [virtual name] / 3] set domain "[HTTP::host]" set startTime [clock clicks -milliseconds] if {[HTTP::header "X-XXX"] ne ""} {set inXXX "[HTTP::header "X-XXX"]"} else {set inXXX "unkn"} set ts [clock format $timeInSeconds -format "%Y-%m-%dT%T.$frac" -gmt 1]Z when HTTP_REQUEST_DATA { set endRequestData [clock clicks -milliseconds] } when HTTP_RESPONSE { set now [clock clicks -milliseconds] set etimeResponse [expr {($now - $startTime)}] } when LB_SELECTED { set lt_lbPool [getfield [LB::server pool] / 3] set lt_lbServer [LB::server addr] } when HTTP_RESPONSE_RELEASE { if { [catch { ... set logging "$ts $src_addr > $virtual_server_name" HSL::send $logging_hsl $logging }] } { log local0. "Match error" } } The problem I'm having occurs in the HTTP_RESPONSE_RELEASE event in the case that a REDIRECT occurs, in which case it exits through the catch, logs the error but I lose logging that line in the pool. To solve part of the problem, I add a if { [HTTP::has_responded] } { return } block before the if { [catch , but I would also be missing the logging line. In addition, when you do the redirect, you no longer have access to the headers, so you don't have them cached and it fails. Does anyone have an idea of how I could do to be able to log that request even if it comes from a redirect?I'm struggling with this and I can't find how to avoid missing logging those requests that come out by redirect. Thanks in advance! Cheers.599Views0likes1Comment