The Juniper SRX firewalls have a special application layer gateway (ALG) for the DNS protocol. This ALG performs the following tasks:
Some of these functions are interesting to provide a little bit more security but most of the have major drawbacks and their default settings are just plain stupid. The default maximum message size is 512, even though everyone has been using EDNS0 for years. DNS doctoring is enabled by default, very poorly documented and causes unexpected changes in DNS replies. I'll explain the issues a bit more in detail and then suggest what I would consider to be a better default configuration.
Feel free to skip the rant :)
Closing the session as soon as the DNS server responds sounds like a very good idea to reduce the number of sessions in use on the firewall. DNS transactions are typically just two packets, waiting for the UDP session timeout every time would mean the firewall has to keep track of a lot more sessions and as most will probably know, DNS is the easiest way to kill stateful firewalls.
The drawback here is that the ALG does not keep track of the DNS transaction IDs, it closes the session as soon as a reply packet is seen. If you have an ancient DNS server which sends all its requests from the same source port, this will cause problems when there is a lot of DNS traffic. The DNS server may send multiple requests in parallel to a remote server for different names, but as soon as the first response is received, the ALG closes the session and the subsequent responses are dropped.
In practice this isn't that much of an issue nowadays. Everyone should be using random source ports on their DNS servers, for security reasons. But years after the Kaminsky hype, there are still servers that haven't been patched.
I have no idea why Juniper even implemented this "feature", let alone make it the default behavior. When the first SRX was released, EDNS0 was already used by most DNS servers and that requires the firewall to allow larger DNS packet sizes.
EDNS0 is an extension which allows for larger DNS packet sizes. The original RFC only allowed 512 bytes, but now that more and more domains are switching to IPv6 and start using DNSSEC, responses are often larger than that. Nearly all DNS servers support EDNS0 and will attempt to to use it. The problem is that the SRX will block the responses, the DNS server waits for a timeout and then retries with a smaller packet size, which will get a response. To the end user, it will appear as if "the internet is slow".
BIND based name servers will generate a lot of these log messages:
named[666]: success resolving 'news.bbc.co.uk/AAAA' (in 'bbc.co.uk'?) after reducing the advertised EDNS UDP packet size to 512 octets
set security alg dns maximum-message-length 8192
DNS Doctoring is a functionality where the firewall will look at DNS responses from your DNS servers for addresses that have a static NAT rule defined and will then change the IP in the DNS response to the NAT address. This behavior is wrong in so many ways. There is very little documentation about this - as far as I know this behavior gets triggered when both the DNS server and the response have a static NAT rule, but I may be wrong. If you think you need functionality like this, you should rethink your DNS infrastructure. Other than it being an extremely ugly kludge, it doesn't always work and will fail in the future if you decide to use DNSSEC.
When this feature was first introduced, it couldn't even be disabled. But in more recent JunOS releases it can be disabled using the following command:
set security alg dns doctoring sanity-check
As documented on the Juniper KB, the SRX DNS ALG does not permit DDNS updates. Especially when the SRX is used as an internal firewall, separating clients from their Active Directory DNS servers, this can be a problem. Many people rely on DDNS to register client or server names in DNS. The SRX will drop these registrations, resulting in missing or outdated DNS records. The only solution until now is disabling the DNS ALG:
set security alg dns disable
There are no CLI commands to see how much traffic was dropped by the ALG, but the information can be obtained from the forwarding daemon directly:
admin@srx> request pfe execute target fwdd command "show usp alg dns stats" SENT: Ukern command: show usp alg dns stats GOT: GOT: dns-alg init state: 1 GOT: dns-alg (total 34) GOT: pkts received 32265728 GOT: pkts received NULL jbuf 0 GOT: pkts received dup NULL jbuf 0 GOT: pkts received ipfrag 0 GOT: pkts received V6 181659 GOT: pkts received V4 32084069 GOT: pkts invalid 0 GOT: pkts examine 32119585 GOT: pkts reply 15771693 GOT: pkts truncated message 2448 GOT: pkts oversize message 1 GOT: parse oversize name 0 GOT: parse oversize label 0 GOT: oversize compression pointer 0 GOT: undersize compression pointer 1 GOT: pkts parse quesion fail 3 GOT: pkts parse answers fail 0 GOT: pkts parse authority fail 227501 GOT: pkts parse additional fail 3 GOT: pkts parse fail 227507 GOT: pkts NAT need 2599821 GOT: pkts NAT V4 need 0 GOT: pkts NAT V6 need 0 GOT: pkts NAT xlated 0 GOT: pkts NATPT need 0 GOT: pkts DUP A query 0 GOT: pkts Dup A query fail 0 GOT: pkts receive A response 0 GOT: pkts receive DUP A response 0 GOT: pkts xlate A2AAAA fail 0 GOT: pkts xlate A2AAAA 0 GOT: session interest 13808061 GOT: session not interest 91325 GOT: pkts update name offset 0 GOT: max message length 8192 LOCAL: End of file
For branch SRX devices, I would use the following default configuration:
security {
alg {
dns {
maximum-message-length 8192;
doctoring {
sanity-check;
}
}
}
}This maintains some of the ALG advantages and fixes the annoying default behavior.
When you need to allow DDNS through the firewall, the only option is to disable the ALG entirely:
security {
alg {
dns {
disable;
}
}
}
Comments
Michael Kropat
Tue, 04/03/2012 - 16:49
Permalink
Thanks for documenting the
Thanks for documenting the DNS Doctoring “feature.” I suspected my issues were being caused by the DNS ALG, but your post confirmed it.
Stijn
Mon, 04/16/2012 - 16:56
Permalink
Hi Bart,
Hi Bart,
The doctoring feature is not configurable in 10.4R7.5. Any idea if it is enable by default in the ALG?
Keep up the good work :)
Stijn
Bart
Mon, 04/16/2012 - 20:02
Permalink
Hi Stijn,
Hi Stijn,
It's enabled by default since 10.1, along with the maximum-message-length check.
The option to disable most of this behavior was only added in 11.1 so in 10.x all you can do is disable the ALG entirely.
Andrew
Thu, 05/31/2012 - 08:49
Permalink
Great article, thanks.
Great article, thanks.
Henrik Kramshøj
Wed, 09/05/2012 - 12:36
Permalink
My recommended config for ALG
My recommended config for ALG is:
> show configuration security alg
dns disable;
ftp disable;
pptp disable;
just dont use it!
If you are afraid of long running session not being timed out, you can define application and use "inactivity-timeout 300" for specific traffic
Fredrik Gunger
Tue, 09/25/2012 - 18:37
Permalink
I do recommend 'dns disable'.
I do recommend 'dns disable'.
Especially if you're trying to do secure an Active Directory through an SRX firewall and try to make Secure DNS updates working from clients!
Jalal
Wed, 10/17/2012 - 15:40
Permalink
The CLI command to obtain ALG
The CLI command to obtain ALG DNS Statistics does not work on the SRX3600, are there any command that can be used on SRX3600?
Dekkster
Wed, 10/24/2012 - 03:50
Permalink
'dns disable' on SRX240
'dns disable' on SRX240 firewalls was the fix for me. Using the above recommended default config did not solve the problem. Thanks for this post as this problem was doing me head in :)
Keenan
Tue, 02/19/2013 - 02:02
Permalink
I ran into this last week and
A workaround exists. It's possible to set 'alg ignore' in a security policy term, which will avoid ALG for matching traffic:
set applications application dns-noalg term dns-tcp protocol tcp destination-port 53 alg ignore
set applications application dns-noalg term dns-udp protocol udp destination-port 53 alg ignore
edit security policies from-zone trust to-zone untrust
set policy dns-noalg match source-address any
set policy dns-noalg match destination-address any
set policy dns-noalg match application dns-noalg
set policy dns-noalg then permit
insert policy dns-noalg before policy default
Thanks for your article, it really helped with understand this "feature" and gave me that friendly "ahh I'm not the only one" feeling while tearing my hair out trying to find a workaround :D.
Tested on SRX650 10.4R9.2 and SRX100 11.4R3.7.
Add new comment