For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Serving or browsing iFiles

Problem this snippet solves:

Browse iFiles from internal IPs, serve the files externally by name.

How to use this snippet:

Create DNS name like ifile-*.example.org and point to a vip.

Add iRule to a vip. before other events.

Code :

 

# rule_ifile-star
# This file allows browsing iFile content in a web browser
# add the rule to shared-* and add dns alias to shared-* for any F5
# Tim Riker <Tim@Rikers.org>

when HTTP_REQUEST {
    switch -glob -- [HTTP::host] {
        "ifile-*" {
            set uri [HTTP::uri]
            set contenttype "text/html; charset=utf-8"
            switch -- [getfield $uri . 2] {
                js {
                    set contenttype "application/javascript; charset=utf-8"
                }
                png {
                    set contenttype "image/png"
                }
                svg {
                    set contenttype "image/svg+xml"
                }
            }
            # format '%s' work around for F5 ifile get bug 913385
            if { [catch { HTTP::respond 200 content [ifile get [format "%s" $uri]] Content-Type $contenttype Connection close} ] } {
                if { ([class match -- [IP::client_addr] equals private_net]) } {
                    # browse only from private_net
                    set response "<!DOCTYPE html><html lang=\"en\"><head><title>[HTTP::host]</title>"
                    append response "<script src=\"//code.jquery.com/jquery-3.3.1.js\"></script>\n"
                    append response "<script src=\"//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js\"></script>\n"
                    append response "<script>\$(document).ready(function() {\$('#ifiles').DataTable();} );</script>\n"
                    append response "<link rel=\"stylesheet\" type=\"text/css\" href=\"//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css\">"
                    append response "</head><body><h1>[HTTP::host]</h1>"
                    append response "<p>[virtual name]</p>"
                    append response "<table id='ifiles'><thead><tr><th>file</th><th>size</th><th>who</th><th>date</th><th>ver</th></tr></thead><tbody>\n"
                    foreach {ifile} [ifile listall] {
                        append response "<tr><td><a href=\"$ifile\">$ifile</a></td>"
                        append response "<td>[ifile size $ifile]</td>"
                        append response "<td>[ifile last_updated_by $ifile]</td>"
                        append response "<td>[clock format [ifile last_update_time $ifile] -format "%Y-%m-%d %H:%M:%S"]</td>"
                        append response "<td>[ifile revision $ifile]</td>"
                        append response "</tr>\n"
                    }
                    append response "</tbody></table></body>"
                    HTTP::respond 200 content $response "Content-Type" "text/html; charset=utf-8" Connection close
                } else {
                    set error_page [string map [list TITLE "Not Found" ERRORURI "[URI::encode "https://[HTTP::host][HTTP::uri]"]" TEXT "Not Found"] [ifile get "/Common/error.html"]]
                    HTTP::respond 404 content $error_page "Content-Type" "text/html; charset=utf-8" Connection close
                }
            }
            event disable
            return
        }
    }
}

 

Tested this on version:

15.1

Updated Jan 27, 2023
Version 3.0
No CommentsBe the first to comment