Forum Discussion
How to create iRule to deliver an alternate page response other than 'page unavailable'
When we currently disable one of the virtual servers in our setup, we get an 'unable to display this page' message in the browser. Rather than this, we would like to display a maintenance page so that users are made aware that there is an issue. We had thought of implementing this as an irule (and have created one), but it does not seem to be working. We have the following code:
when HTTP_REQUEST {
set hostvar [HTTP::host]
set urivar [HTTP::uri]
}
when HTTP_RESPONSE {
if { [HTTP::status] eq "404" } {
HTTP::respond 200 content {
The site ($hostvar$urivar) is currently down for essential maintenance.
} Cache-Control No-Cache Pragma No-Cache
}
} We hoped that by just creating an irule that this would be fired when a virtual site was disabled - but this isn't the case. We have tried adding the irule to the resources area of the virtual server, but it still does not display the message. As a result, we're not sure what we're doing wrong and need some assistance to get this working. For a start, the code parses correctly, but does this code look reasonable to what we need to achieve? Finally, how do we get the irule to fire?
Another option was to just redirect to a different web server and page. We tried the following, but again, it didn't seem to work.
when LB_FAILED { if { [active_members [LB::server pool]] < 1 } { HTTP::fallback "http://internalsite.co.uk/slp/maintenance.html" } }
So we're just after some advice as to what would be the best way to go about this - if we've made any mistakes in the creation of the irules, or if there is a better way of implementing what we are trying to do?
14 Replies
- Andres_4712Historic F5 Account
You may find useful the following docs:
Automatic maintenance page sorry page with images
( Contributed by: thepacketmaster )
( Contributed by: spark, based off several other contributors including citizen_elah )
Note: your example shows that you are trying to run the iRule on a disabled vip. That wont work because disabled vips does not receive new conns.
- MrRichard
Nimbostratus
Thanks Andres, I see where I am going wrong now. :)
- nathe
Cirrocumulus
Richard,
Might a Fallback Host entry set as "http://internalsite.co.uk/slp/maintenance.html" in a HTTP Profile on the VIP work for you? Also, do you disable the VIP itself or the pool member(s) within?
Hope this helps, N
- Dan_Cox_24281
Nimbostratus
Here's what we use on our public web sites. Stored the HTML and images in iFiles for use elsewhere.
when HTTP_REQUEST { if {[active_members [LB::server pool]] < 1} { switch [HTTP::uri] { "/guardian_header.jpg" { HTTP::respond 200 content [ifile get "guardian_header_jpg"] } "/guardian_logo.jpg" { HTTP::respond 200 content [ifile get "guardian_logo_jpg"] } default { HTTP::respond 200 content [ifile get "maint_index_html"] } } } }- MrRichard
Nimbostratus
Great thanks Dan. I've not used iFiles yet, so I may look to doing this if all else fails. Cheers :) - Dan_Cox_24281
Nimbostratus
I like going the iFile route mainly because our web developers here insist on writing their own maintenance page and they require background images, logos, and such. With iFiles I don't have to convert them to base64 and embed them in an iRule. But, if you don't need to serve up any images or large HTML files it would be simpler to just put the HTML directly in the iRule as suggested by Kevin below.
- Kevin_Stewart
Employee
The problem is that you're disabling the virtual server. A disabled VIP isn't going to respond to any requests or evaluate any iRule events. A simple alternative would be to disable the pool members and use an active_member check in the CLIENT_ACCEPTED event.
- melcaniac
Cirrus
When you disable the virtual server the F5 no longer responds on that IP/port, so no iRules will be triggered. I think that you want to disable the servers in the pools instead of the F5 virtual server instead. If all of the pool member servers are disabled, either manually or due to failing health monitors and an HTTP request comes in, a LB_FAILED event will be triggered and you can craft your response. I recommend something simpler, this is the basics of what we use, where your can add your own html, you could also do a HTTP::redirect instead. Remember that the virtual server will need to have an HTTP profile.
when LB_FAILED { log local0.info "LoadBalanceFailureHost [HTTP::host]" HTTP::respond 500 content { Put your HTML here. } }
- MrRichard
Nimbostratus
Thanks all , very much for your ideas and help. This is such a good forum, I was not expecting anything back for a while, so really pleased. Looks like I can work this out now, but I'll post back if I need any more help. Thanks again
- Kevin_Stewart
Employee
See: https://devcentral.f5.com/wiki/iRules.active_members.ashx
when HTTP_REQUEST { if { [active_members http_pool] < 1 } { HTTP::respond 200 content "html maintenance page..." } } - Arie
Altostratus
One big problem I see with the various options above is that they use the Status Code 200, which signifies "OK". Since the situation is not OK the proper code should be issued, for instance:
HTTP::respond 404 content "html maintenance page..."See section 10 of RFC 2616 for a list of proper Status Codes.
- Andres_4712Historic F5 Account
Dont want to be tricky, but RFC actually states the Oposite. 404 is given when "The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent."
"..10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable."
- IheartF5_45022
Nacreous
For what it's worth we use a 503 (Service Unavailable) from LB_FAILED;-
when LB_FAILED { HTTP::respond 503 Content [b64decode [class lookup $sorry dg_content]] noserver Content-Type "text/html" Retry-After "600" Content-Encoding "gzip" Connection "close" return }We have the HTML gzipped, b64-encoded, and stored in a data group (dg_content). The Retry-After header is for SEO.
- IheartF5_45022
Nacreous
Sorry just realised this question was about 404s, not when servers down. Ignore :-)
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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