Issue: my SPF Record (TXT) can not be retrieved from the DNS entry of the domain zwischengas.com
In my DNS entry I have one line for the SPF Record (as TXT entry):
# IN TXT "v=spf1 ip4:188.a.b.c ip4:xyz/22
ip4:xyz/24 ip4:xyz/21 ip4:xyz/24 ip4:xyz/24" "ip4:xyz ip4:xyz/22
ip4:xyz ip4:xyz/29 ip4:xyz/29 ip4:xyz/28" "ip4:xyz/24 ip4:xyz/24 a mx
?all"
I have the problem, that this SPF Record can not be found and I have no clue why.
According to the RFC splitting up a very long line into multiple strings is recommended in order to keep all substrings smaller than 255 characters.
My domain is zwischengas.com , the Mail Server's IP is 188.a.b.c, anybody a clue?
I tried these tests without success:
host -t txt zwischengas.com
spfquery -ip-address 188.a.b.c -m test#zwischengas.com -h zwischengas.com
Also the tests with online tools are without success:
http://www.kitterman.com/spf/validate.html
http://mxtoolbox.com/DNSLookup.aspx
Also Google Mail (gmail.com) can not retrieve my SPF record (according to the original mail header section):
Received-SPF: neutral (google.com: 188.a.b.c is neither permitted
nor denied by best guess record for domain of
noreply1#zwischengas.com) client-ip=188.a.b.c;
Working Solution
You can test the correctness of your SPF record by calling
host -t txt myhost.com
A simple SPF record could look like this:
# IN TXT "v=spf1 ip4:244.11.23.13 a mx ?all"
If you add IPs one after the other, you can end up in error messages from the DNS Server saying that the string is too long.
A valid solution to this is to introduce " " into it.
So instead of
# IN TXT "v=spf1 ip4:244.11.23.13 ip4:144.21.23.13 ip4:222.11.11.13 ip4:244.182.23.191 ip4:203.101.22.13 a mx ?all"
you would have (an example):
# IN TXT "v=spf1 ip4:244.11.23.13 ip4:144.21.23.13" " ip4:222.11.11.13 ip4:244.182.23.191" " ip4:203.101.22.13 a mx ?all"
The " " option is described in the appropriate RFC and is accepted by all DNS Servers (what actually happens is, the " " is removed and the substrings get concatenated).
But what if you have 20 IPs? You end up in a string which is by far longer than what is allowed. What can you do?
The solution to this is called: include
An example:
# IN TXT "v=spf1 include:_spf1.myhost.com include:_spf2.myhost.com a mx ?all"
_spf1 IN TXT "v=spf1 ip4:244.11.23.13 ip4:144.21.23.13 a mx ?all"
_spf2 IN TXT "v=spf1 ip4:222.11.11.13 ip4:244.182.23.191 ip4:203.101.22.13 a mx ?all"
You can extend that with N hierarchies. I hope this helps as it took me some time to find this out!!
What's that multiples "?
# IN TXT "v=spf1 ip4:188.a.b.c ip4:xyz/22 ip4:xyz/24 ip4:xyz/21 ip4:xyz/24 ip4:xyz/24" "ip4:xyz ip4:xyz/22 ip4:xyz ip4:xyz/29 ip4:xyz/29 ip4:xyz/28" "ip4:xyz/24 ip4:xyz/24 a mx ?all"
Shouldnt that have only a couple "", and then be:
# IN TXT "v=spf1 ip4:188.a.b.c ip4:xyz/22 ip4:xyz/24 ip4:xyz/21 ip4:xyz/24 ip4:xyz/24 ip4:xyz ip4:xyz/22 ip4:xyz ip4:xyz/29 ip4:xyz/29 ip4:xyz/28 ip4:xyz/24 ip4:xyz/24 a mx ?all"
Related
I'm using bind (named) name server to have a local DNSBL. The problem is, I'm getting 500+ spam mails a day from certain IP blocks and adding all the IPs one by one is an absurd amount of work.
Is it possible to define IP ranges in the zone file and if so, how?
I did google extensively but the DNSBL topic is very underrepresented in the search results.
here's a snippet of the record:
$TTL 1W
# IN SOA localhost. root.localhost. (
2008122601 ; Serial
28800 ; Refresh
14400 ; Retry
604800 ; Expire - 1 week
86400 ) ; Minimum
# IN NS localhost.
# IN A 127.0.0.1
# IN AAAA ::1
;------------------------------------------------------------------
2.0.0.127 IN A 127.0.0.2
IN TXT "example.com test record"
3.0.0.127 IN A 127.0.0.3
IN TXT "example.com verified spam source"
10.0.0.127 IN A 127.0.0.10
IN TXT "example.com confirmed DUL range"
;------------------------------------------------------------------
23.85.173.113 IN A 127.0.0.3
253.139.2.198 IN A 127.0.0.3
212.170.54.142 IN A 127.0.0.3
6.11.28.50 IN A 127.0.0.3
64.240.56.149 IN A 127.0.0.3
15.223.225.110 IN A 127.0.0.3
; etc
If you know DNSBL, you know those IPs are in reverse digit order e.g. 1.2.3.4.localhost. becomes 4.3.2.1.localhost.
So to repeat myself, how, if it's possible at all, do I define an IP range, let's say 1.2.3.0/24?
Yes, you use wildcards.
In the example of 1.2.3.4, you write
*.3.2.1 IN A 127.0.0.3
dig #127.0.0.1 4.3.2.1.localhost found
dig #127.0.0.1 254.3.2.1.localhost found
dig #127.0.0.1 4.4.2.1.localhost not found
Say I have these two records defined:
*.example.com CNAME <some name>
foo.example.com TXT <some text>
What is expected to happen if I run a DNS query like this?
dig TXT foo.example.com
I would expect to get the TXT record defined above in the answer section, since it's more explicitly defined. But, what I get from my DNS provider is the CNAME defined for the wildcard.
I've raised this issue with them, and they say they are following the correct behaviour. This is the explanation they gave me:
Refer section 2.4 in RFC1912 about "Common DNS errors". http://www.rfc-editor.org/rfc/rfc1912.txt "A CNAME record is not allowed to coexist with any other data. In other words, if suzy.podunk.xx is an alias for sue.podunk.xx, you can't also have an MX record for suzy.podunk.edu, or an A record, or even a TXT record."
Basically, this means that, if you add a CNAME record for *.example.com, it will always take priority over any other record, even if those records are added for a specific subdomain, they're still ignored. There is nothing we can do in this case. It's how DNS is supposed to work, according to the DNS-standard.
Is this correct? Does the section in the referred RFC cover the case of a wildcard? Can anyone give me an authoritative answer and provide a link to the source?
Wikipedia page on DNS wildcard is pretty clear with examples (see the one about host1.example).
In short, a wildcard is only used if the "direct" full name is not found.
You can find all the explanations in section 4.3.2 of https://www.rfc-editor.org/rfc/rfc1034 and specifically point 3.a and point 3.c:
a. If the whole of QNAME is matched, we have found the
node.
If the data at the node is a CNAME, and QTYPE doesn't
match CNAME, copy the CNAME RR into the answer section
of the response, change QNAME to the canonical name in
the CNAME RR, and go back to step 1.
Otherwise, copy all RRs which match QTYPE into the
answer section and go to step 6.
[..]
c. If at some label, a match is impossible (i.e., the
corresponding label does not exist), look to see if a
the "*" label exists.
See how it specifically first searches for the full name, with extra condition if it is a CNAME, but this is not your case if you query for a TXT.
In your case if you query for the TXT record specifically, then that should be returned, irrespective of any wildcard.
In fact the TXT on foo.example.com will hide any other type, a CNAME request on it, should not return the value in the wildcard but instead stop with NOERROR NODATA meaning that the name exists, just not for this type.
This is exactly the host1.example case in the above Wikipedia page.
It is very easy to try in fact.
With this zonefile:
$TTL 1
# IN SOA localhost. root.localhost. (1 604800 86400 419200 604800)
IN NS a.example.org.
IN NS b.example.org.
IN NS c.example.org.
*.example.com. IN CNAME foobar.example.net.
foobar.example.com. IN TXT "I am here."
(the beginning is just boilerplate to have bind really load the zone)
if you do dig #127.0.0.1 foobar.example.com TXT you get as expected:
;; ANSWER SECTION:
foobar.example.com. 1 IN TXT "I am here."
if you query for any other record type on same name, including CNAME you get NOERROR without any CNAME in reply (the wildcard is hidden by the explicit name in zonefile, and you get NOERROR but no data for any other record type than TXT on this name as this is the only record type in the zonefile) and the wildcard works for any other name, like dig #127.0.0.1 not-foobar.example.com TXT gives:
;; ANSWER SECTION:
not-foobar.example.com. 1 IN CNAME foobar.example.net.
The explanations you are given are not the correct ones and do not apply on your use case. The quote would only apply to this kind of (invalid) configuration:
*.example.com. CNAME <some name>
*.example.com. TXT <some text>
but this is not related to the wildcard, the same problem appears with the following configuration that will be rejected by any compliant nameserver:
foobar.example.com. CNAME <some name>
foobar.example.com. TXT <some text>
I have bought a vps plan on godaddy and I want to configure my domain settings.
I followed the instructions mentioned here:
https://www.youtube.com/watch?v=B4xNNyb5y7o
It is not my first time to do though, but after creating new account I get this:
This is a picture of the error I get when creating a new account
and when I try to edit my dns zone I get this:
the error I get when editing the dns zone
; cPanel first:11.72.0.4 (update_time):1530021773 11.72.0.4: Cpanel::ZoneFile::VERSION:1.3 hostname:s132-148-245-18.secureserver.net latest:11.72.0.4
; Zone file for el7p.com
$TTL 14400
# 86400 IN SOA ns1.secureserver.net. info.. ( near 'info..': empty label
2018062600 ; serial, todays date+todays
3600 ; refresh, seconds
7200 ; retry, seconds
1209600 ; expire, seconds
86400 ) ; minimum, seconds
el7p.com. 86400 IN NS ns1.secureserver.net.
el7p.com. 86400 IN NS ns2.secureserver.net.
el7p.com. IN A 132.148.245.18
el7p.com. IN MX 0 el7p.com.
mail IN CNAME el7p.com.
www IN CNAME el7p.com.
ftp IN A 132.148.245.18
el7p.com. IN TXT "v=spf1 +a +mx +ip4:10.193.90.225 ~all"
You have an error in your Zone file.
The line # 86400 IN SOA ns1.secureserver.net. info.. ( near 'info..': empty label contains the word 'info... ' and that's what's causing the problem for you.
It should read as; # 86400 IN SOA ns1.secureserver.net. hostmaster.el7p.com. ( Note the '(' should be there as its closed a few lines below and groups all the TTL settings together.
The hostmaster section should contain a valid email contact (without the #) for the domain.
Over at dmarc.org, it's suggested that IN TXT records of DNS could be written in a special form within the zone file to make them not overflow the lines in your text editor.
The DMARC policy record might look like this when retrieved using a
common command-line tool:
% dig +short TXT _dmarc.example.com.
"v=DMARC1\; p=none\; rua=mailto:dmarc-feedback#example.com"
To publish such a record, the DNS administrator for the Domain Owner
creates an entry like the following in the appropriate zone file
(following the conventional zone file format):
; DMARC record for the domain example.com
_dmarc IN TXT ( "v=DMARC1; p=none; "
"rua=mailto:dmarc-feedback#example.com" )
I've tried following the example in my actual zone file with NSD; however, when I then query the domain, I actually get the results wrapped up on multiple lines, too.
% dig +short TXT _dmarc.example.su
"v=DMARC1\; " "p=reject\; " "rua=mailto:rua-dmarc#example.su"
Is this expected? Is this likely to break some software that's supposed to parse these TXT records to get the DMARC / SPF / DKIM / etc?
The individual components of a TXT record may only contain up to 255 characters each, since they're transmitted on the wire in <length><data ...> format.
Any code that's potentially expecting to take more than 255 characters SHOULD be able to coalesce multiple components into a single character array.
In master file format the braces surrounding the strings indicate that multiple components are to be included in a single TXT record - without them this would have created two separate TXT records, and the relative order of the two records would be undefined and subject to change.
It's hard to tell since it will depend on the final implementation of the DMARC checker. However, even detailed in the DMARC document, a DMARC record is no such big that you could overflow your editor.
In my case, using the last opendmarc package on Ubuntu Trusty (14.04) along with Postfix, made the daemon crash when processing some weird/malformed DMARC DNS records (but not exactly the case you mention).
I would simply add the one-line approach and play it safe, not just because of a possible break of the checker software, but even worse would be getting your mail rejected because policy doesn't seem to be alligned when it actually is!
So I'd just add something like this:
_dmarc.example.su IN TXT "v=DMARC1; p=reject; rua=mailto:rua-dmarc#example.su"
I use following steps:
Query A records for host, some servers return NS records in authority section, so I extract them from that section, if any.
Query NS records, extract them from answer section.
The problem is with "subdomains" (CNAME), for example:
> dig www.microsoft.com A
;; ANSWER SECTION:
www.microsoft.com. 696 IN CNAME toggle.www.ms.akadns.net.
toggle.www.ms.akadns.net. 119 IN CNAME g.www.ms.akadns.net.
g.www.ms.akadns.net. 263 IN CNAME lb1.www.ms.akadns.net.
lb1.www.ms.akadns.net. 31 IN A 65.55.12.249
> dig www.microsoft.com NS
;; ANSWER SECTION:
www.microsoft.com. 619 IN CNAME toggle.www.ms.akadns.net.
toggle.www.ms.akadns.net. 42 IN CNAME g.www.ms.akadns.net.
g.www.ms.akadns.net. 186 IN CNAME lb1.www.ms.akadns.net.
;; AUTHORITY SECTION:
akadns.net. 174 IN SOA internal.akadns.net. hostmaster.akamai.com. 1304057105 90000 90000 90000 180
> dig lb1.www.ms.akadns.net A
;; ANSWER SECTION:
lb1.www.ms.akadns.net. 79 IN A 65.55.12.249
> dig lb1.www.ms.akadns.net NS
;; AUTHORITY SECTION:
akadns.net. 176 IN SOA internal.akadns.net. hostmaster.akamai.com. 1304057402 90000 90000 90000 180
As you can see, there are no NS records returned. How to overcome this problem?
Your algorithm is wrong. Here's the right one.
For each successively shorter superdomain S of the target domain name T, starting with T itself:
Perform an NS lookup on S. If the answer is not a non-empty resource record set, go to step 3. Otherwise you have a set of intermediate domain names D[].
Perform A and AAAA lookups on each name in D[]. This will give you a set of IP addresses. You have your answer. END.
Optionally perform a SOA lookup on S. If the answer is a non-empty resource record set, you are about to cross an administrative boundary having found no non-empty NS resource record set thus far. You may choose, according to exactly what you are trying to find out, to ABEND.
Remember that you have to make queries to your own resolving proxy DNS server, not to the external content DNS servers, so that you get a complete answer rather than a partial one. Also remember that you have to follow CNAME chains when inspecting responses. The response to your dig www.microsoft.com. NS query above, for example, is a CNAME chain leading to an empty NS resource record set for lb1.www.ms.akadns.net..