Forum Discussion
GTM iRule - cname
Hi all,
I'm trying to test a simple iRule to return a cname for a wide IP. I looked at the cname Wiiki on dev central and my syntax looks correct, however, it is not returning the cname response. Ultimatly this will be used in a more complex iRule but I need to verify this works first.
Here is the simple iRule:
when DNS_REQUEST {
cname "test.test.com"
}
When i do an nslookup all I get in return is the name of the host I queried
Any ideas what I'm missing for this?
Btw, if I substitute the cname command for host it works.
i.e.
when DNS_REQUEST {
host 10.10.10.10
}
18 Replies
- Mohamed_Lrhazi
Altocumulus
Can you show full nslookup of both cases? is it nslookup directly against the listener? - Hamish
Cirrocumulus
Better yet, use dig to debug it... You getbbetter and more detailed output on he queries and responses. Nslookup was deprecated about 10+ years ago..
H - dstogsdill_2492
Nimbostratus
Thanks for the reply Mohamed. here is the nslookup output. test1.test.com is the Wide IP with the CNAME irule applied. BTW, i am using a lab GTM hence the test.com domain.
> server 10.226.133.194
Default Server: [10.226.133.194]
Address: 10.226.133.194
> test1.test.com
Server: [10.226.133.194]
Address: 10.226.133.194
Name: test1.test.com
Here is the output when I change the iRule to return a host address rather than a cname.
> test1.test.com
Server: [10.226.133.194]
Address: 10.226.133.194
Name: test1.test.com
Addresses: 10.10.10.10
10.10.10.10
And here are the iRules:
when DNS_REQUEST {
cname "test.test.com"
}
when DNS_REQUEST {
host 10.10.10.10
}
Hamish, I will try out dig and see what info i get back. Thanks! - dstogsdill_2492
Nimbostratus
Here is the dig output. It shows the cname was sent so i'm not sure why nslookup doesn't, other than as Hamish said that it's depreciated....One thing does look off though. The response doesn't show the resolution of the cname response. The second output below shows a query to a cname created through ZoneRunner, there are obvious differences.
H:\>dig @10.226.133.194 test1.test.com. a
; <<>> DiG 9.9.2 <<>> @10.226.133.194 test1.test.com. a
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7526
;; flags: qr aa rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test1.test.com. IN A
;; ANSWER SECTION:
test1.test.com. 0 IN CNAME test.test.com.
H:\>dig @10.226.133.194 test2.test.com. a
; <<>> DiG 9.9.2 <<>> @10.226.133.194 test2.test.com. a
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6554
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 2
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test2.test.com. IN A
;; ANSWER SECTION:
test2.test.com. 300 IN CNAME test.test.com.
test.test.com. 300 IN A 10.10.10.10
;; AUTHORITY SECTION:
test.com. 300 IN NS ns1.lab.company.com.
;; ADDITIONAL SECTION:
ns1.lab.company.com. 300 IN A 10.226.133.194 - Mohamed_Lrhazi
Altocumulus
The are two diffeent DNS servers... The first is GTM (Not DNS Express or DNS cache service) but GTM module itself. The second is BIND runnning in Linux.
Looks like you first query worked, right? It return:
;; ANSWER SECTION:
test1.test.com. 0 IN CNAME test.test.com.
Whcih is valid response and which a real DNS server, unlike dig/nslookup, would know to requry to follow the aliases chain.
What is the probme you are trying to solve?
What version of BIGIP GTM is this?
There is a bug related to CNAME queries to wide_ips though... What exactly do you need to do, and why? - dstogsdill_2492
Nimbostratus
The ultimate goal is to provide an ANAME like service, which is to allow CNAME like behavior for root zone queries. ANAMES are not an RFC standard so I may be looking at this all wrong but since I'm testing I want to make sure I'm using the correct syntax and getting a proper return value. Why? This is needed to host Domains using Amazon Web Services.
Since I'm not getting the same returned values as I would when querying a Bind CNAME I'm assuming i'm either using the CNAME method incorrectly or i'm hitting a bug as you suggested. I'm running version 11.1 HF4, although, i'm planning an upgrade to 11.2 in early December.
What i'm uncertain about is if I can even return a CNAME in response to a root zone query which is why i'm testing in a lab. If this is not possible I may need to use a combination of a perl script and iFile.
BTW, at this point i'm testing with host names NOT root zones. I figured I need to get a valid reply before testing with root zones. - Mohamed_Lrhazi
Altocumulus
You're iRule feels to fake... this a wide_ip, so it's some DNS name, say example.com
What would an iRule that says, for any request, respond with this CNAME... why is it a wide_ip then?
I understand you're just testing, but it is confusing for us, external people trying to help you out, to understand....
You project sounds intersting, though I dont underdtand it:) care to explian a bit more?
Explain what the wide_ip if any, would be used for, then what the iRules job would be.
Do you mean to interespt quey_type == CNAME, and some other query_types, and act on them, while letting GTM handle A or ANY types?
I've never heard of ANAME... will be looking it up soon though. - Mohamed_Lrhazi
Altocumulus
FYI, the bug I run into is:
Bug 391315 - GTM: CNAME qtype mishandled when pool iRule cmd used
and has been resolved in 11.2.0 HF2
https://support.f5.com/kb/en-us/solutions/public/13000/600/sol13668.html?sr=25075665 - gbbaus_104974Historic F5 Account
Hi ... had a similar request ...... here is the txt version of the write up .. HTH
GTM Configuration to allow:
1. Monitor a remote site (eg: AWS_FQDN/health.html) via FQDN (not IP Address)
a. If health is good then serve up a CNAME
b. If the health is bad then serve up a IP address from a GTM Pool
The above requirement can be accomplished by assigning an iRule to the GTM WideIP, and calling on an External Monitor to check the availability of the Cloud based service.The Steps are:
• Create a Server object to reference the AWS Cloud
a. This will be used in the GTM Pool
i. The IP Address is not important as the External Monitor will do a dynamic lookup• Create an External Monitor to check the availability of the Cloud service
a. The Health monitor will control the GTM Pool status
(based on using CURL -s https://aws.amazon.com)• Assign an CNAME iRule to a GTM Wide-IP with pool members
1) AWS Cloud Pool and
2) ‘GTM owned’ virtual server pool
== Step 1: ==Create the AWS ‘Generic Server Object’, which will be used in the GTM Pool ‘gtmpool_AWS’
== Step 2:==Create an External Monitor to check the availability of the Cloud service
• The “Arguments” form the basis of the $3 variables within the monitor script
• The RESPONSE_CHECK is used to verify the successful connection to the site in $3
• The DEBUG variable is used to enable/disable logging to /var/log/ltm
o Set to 1 initially to see if check it successful
o Manually run CURL command without the ‘grep’ to see what the site returns
Part of Step 2 is to create an External health monitor.A good reference on EAV is on DevCentral: https://devcentral.f5.com/Tutorials...itors.aspx
The External monitor we will use, makes use of CURL to a 443 site.
We will look for the tag, which shows the DNS lookup and the connection was successful<br /> • curl -s <a href="https://${MY_FQDN">https://${MY_FQDN</a>} | grep "<title>" 2>&1 > /dev/null</p> <p><br /> External GTM Monitor file : cloud_dns_monitor<br /> ---------------------------------------------</p> <p>!/bin/bash</p> <p> These arguments are normally supplied automatically based on the<br /> pool members that the EAV is assigned to<br /> $1 = IP (::ffff:nnn.nnn.nnn.nnn notation or hostname)<br /> $2 = port (decimal, host byte order)<br /> <br /> Our EAV will not really use $1 or $2, as it is based off CURL<br /> dynamically resolving the host, and looking at the response.</p> <p> Log debug to /var/log/ltm<br /> Check if a variable named DEBUG exists from the monitor definition<br /> DEBUG=0 or 1 must be set in the EAV GUI<br /> RESPONSE_CHECK must be set in the EAV GUI</p> <p><br /> if [ -n "$DEBUG" ]<br /> then<br /> if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: \$DEBUG: $DEBUG" | logger -p local0.debug; fi<br /> fi</p> <p> Remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format)<br /> We are not actually using it in this monitor<br /> IP=`echo $1 | sed 's/::ffff://'`</p> <p> Save the port for use in the shell command<br /> We are not actually using it in this monitor<br /> PORT=$2</p> <p> Save the FQDN of the server for use in the shell command<br /> $3 is supplied in the GUI of the EAV<br /> MY_FQDN=$3</p> <p> Check if there is a prior instance of the monitor running<br /> pidfile="/var/run/`basename $0`.$IP.$PORT.pid"<br /> if [ -f $pidfile ]<br /> then<br /> kill -9 `cat $pidfile` > /dev/null 2>&1<br /> echo "EAV `basename $0`: exceeded monitor interval, needed to kill ${MY_FQDN} with PID `cat $pidfile`" | logger -p local0.error</p> <p>fi</p> <p> Add the current PID to the pidfile<br /> echo "$$" > $pidfile</p> <p> Debug<br /> if [ $DEBUG -eq 1 ]<br /> then<br /> Customize the log statement here if you want to log the command run or the output<br /> echo "EAV `basename $0`: Running for ${MY_FQDN} using CURL to <a href="https://${MY_FQDN">https://${MY_FQDN</a>}" | logger -p local0.debug</p> <p>fi</p> <p><br /> Customize the shell command to run here. <br /> Use $IP and $PORT to specify which host/port to perform the check against<br /> Modify the netcat example portion of the line:<br /> curl -s –I <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep 200<br /> And leave this portion as is:<br /> '2>&1 > /dev/null'<br /> The above code redirects stderr and stdout to nothing to ensure we<br /> don't errantly mark the pool member up</p> <p> Send the request and check the response<br /> eg: curl -s -I <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep 200 2>&1 > /dev/null<br /> We will look for the <title> tag, which shows the DNS lookup and the<br /> connection was successful<br /> RESPONSE_CHECK must be set in the EAV GUI<br /> curl -s <a href="http://${MY_FQDN">http://${MY_FQDN</a>} | grep "<title>Amazon Web Services" 2>&1 > /dev/null
curl -s } | grep “${RESPONSE_CHECK}” 2>&1 > /dev/nullCheck if the command ran successfully
Note that any standard output will result in the script execution being stopped
So do any cleanup before echoing to STDOUT
if [ $? -eq 0 ]
then
rm -f $pidfile
if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Succeeded for ${MY_FQDN}" | logger -p local0.debug; fi
echo "UP"
else
rm -f $pidfile
if [ $DEBUG -eq 1 ]; then echo "EAV `basename $0`: Failed for ${MY_FQDN}" | logger -p local0.debug; fi
fi----end-----
== Step 3 ==
Create an GTM Wide-IP
- The pool members will be (1) the AWS Cloud Pool and (2) the ‘GTM owned’ virtual serversAttach the iRule to the WideIP , that returns
- the CNAME, or
- the IP address of the GTM pool member in ‘gtmpool_CBA’
iRule: AWS-CNAME-return
-----------------------
when DNS_REQUEST {
GTM External Monitor will determine the health of gtmpool_AWS
based on DNS lookup, and HTTP GET
if { [ active_members gtmpool_AWS] > 0 } {
log local0. "Positive External check to aws.amazon.com using CURL,
puts 'gtmpool_AWS' as Active -- therefore Returning cname aws.amazon.com"
cname aws.amazon.com
} else {
GTM monitor will determine the health of internal
internal pool gtmpool_CBA based on known IP, and HTTP GET
if { [ active_members gtmpool_ACME] > 0 } {
log local0. "External health check to aws.amazon.com failed -- BUT
there are active pool members in 'gtmpool_ACME' -- therefore
Responding with local address from 'gtmpool_ACME'"
pool gtmpool_ACME
}
}
}--end ---
Details of the iRule components can be found at : https://devcentral.f5.com/wiki/iRules.GTM.ashx
• active_members : Returns the number or list of active members in the specified pool.
• cname : Causes the specified name to be sent as a CNAME response.
• pool : Causes the system to load balance traffic to the specified pool or pool member regardless of monitor status. - dstogsdill_2492
Nimbostratus
GbbAus,
This is excellent and I think it's a great place to start. Have you applied this to a root record? i.e. example.com
There is no RFC for returning a CNAME when the client sends an A query to a root record so i'm unsure if the client will even accept a CNAME in response and act upon it. Amazon returns an IP address which is what I think I'm going to have to do.
Here is an explanation of ANAME's and what I'm trying to solve with the GTM.
http://www.dnsmadeeasy.com/press/dns-made-easy-introduces-aname-records/
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