Mask Syntax
2005-04-01 08:55:10
At 10:57 PM 3/31/2005 -0500, Radu wrote:
David MacQuigg wrote:
Records that are already compiled to a simple one-query list will be
processed normally. Records that require multiple queries will not be
evaluated at all and will result in a temporary reject. Adding the m=
syntax allows us to reach a conclusion in *most* of those multi-query
cases, even without the additional queries. In a DoS storm, this could
be *almost all* cases.
Actually... 99.98% of records that require multiple queries will be
correctly after only 1 query, since in a DNS storm the email comes from
everywhere but the few places that the mask specifies. So the incoming
MTAs don't need to change behaviour, as they will only do the 2nd query
for those 0.02% of emails that actually come from the neighbourhood of the
mask.
0.02% may be a bit optimistic. :>) I think attackers will search the
planet for domains that have their authorized senders scattered widely
among a bunch of dynamic IP blocks they can hijack. We may still need an
ability to block even the initial SYN floods from those blocks. This is
outside the scope of SPF, however.
For most reputable domains, however, I think you are right. The vast
majority will do like rr.com and cluster their servers in small,
well-protected IP blocks.
This makes a mask-enabled SPF record extremely resilient to DoS attacks,
while maintaining full function of the SPF record.
So don't worry, if you have the mask, your email will not be bounced even
at the high of a DoS storm. (unless the storm is coming from you ... LOL).
--- Mask Syntax ---
Here is an example of what we could do with a huge domain like rr.com:
m=~24(181ecb,181cc8,181ccc,181eda,185d2f,181909,
411805,185ea6,181d6d,424ba2,181802,412005) ... -all
Existing checkers ignore the m= and process the ... with all the usual
redirects and includes. Upgraded checkers will be able to take advantage
of the new syntax. The ~ means the mask result is ANDed with the
remaining ... result. If it fails to match, you are done.
Not quite so. the -all and m=~ are in conflict. The mask result will be
the same as the "all" prefix.
Also, the mask is evaluated before the first redirect=, no sooner. So the
IP4:'s in the first record are checked against the sender's IP *WITHOUT
LOOKING AT THE MASK*. This is because the mask refers *ONLY* to IP4:
mechanisms which are not in the current record. It would be a waste of
space for the mask to also cover the mechanisms which are clearly visible
in the first record.
Also, I would prefer to sticking to a mask representation that is easily
human readable, so you can look at a record *set* and be able to easily
tell if the mask is right or wrong, just by visual inspection and some
simple arithmetic. If you can't easily tell, the trust in the mask is
undermined (by humans). So when there are problems with the record, the
first thing they do is disable mask generation.
Here are some suggestions on mask syntax. I think we should separate the
goals of readability and versatility in the source record from compactness
and efficiency in the compiled record. This will allow better optimization
on both ends. If we really don't want users messing with the compiled
record, we should not tempt them by making it easily editable. If you need
to see what's in a compiled record, view it in the wizard.
Another goal should be to facilitate later migration to a syntax that needs
nothing but a mask. Currently, we must make masks ignorable, but when I
think of the final standard authentication method that may emerge from a
Grand Unification by the IETF, I think of everything needed for
authentication in one DNS packet. This would most likely include an IP
mask for quick screening at the earliest opportunity, a public key for
final validation at the destination, and links to any other authentication
records that may be necessary. Compactness of the mask will be an issue,
unless they upgrade DNS to use larger UDP packets.
Here is a sequence of compactions for the SPF record of a typical large
domain, starting with the source record. The ... is the current SPF
syntax, and is necessary as long as there are legacy SPF checkers that
ignore masks. The operator after the m= could be any visible
character. In my hypothetical syntax, ~ means this is a supplemental mask,
the original syntax is in ...
+ means this mask is the whole enchilada, you don't even need a -all.
v=spf1 ip4:24.30.203.0/24 ip4:24.28.200.0/24 ip4:24.28.204.0/24
ip4:24.30.218.0/24 ip4:24.93.47.0/24 ip4:24.25.9.0/24
ip4:65.24.5.0/24 ip4:24.94.166.0/24 ip4:24.29.109.0/24
ip4:66.75.162.0/24 ip4:24.24.2.0/24 ip4:65.32.5.0/24 ... -all
v=spf1 m=~24.30.203/24,24.28.200/24,24.28.204/24,24.30.218/24,
24.93.47/24,24.25.9/24,65.24.5/24,24.94.166/24,24.29.109/24,
66.75.162/24,24.24.2/24,65.32.5/24 ... -all
v=spf1 m=~24(24.30.203,24.28.200,24.28.204,24.30.218,24.93.47,
24.25.9,65.24.5,24.94.166,24.29.109,66.75.162,24.24.2,65.32.5)
... -all
v=spf1 m=+24(181ecb,181cc8,181ccc,181eda,185d2f,181909,411805,
185ea6,181d6d,424ba2,181802,412005)
v=spf1 m=+24(Kapi2RPMcR1CxEJdXOkLCFECMQDTO0fzuShRvL8q0m5sitIH)
v=spf1 m=+24,12,a2 |< --- 36 bytes --- >|
This last record indicates there are 12 masks, 24 bits each, and the binary
data for those masks starts at offset a2 within the 512 byte record. The
binary data occupies 36 bytes ( 12 masks, 3 bytes each).
We don't need to specify all this now. Just make sure there is plenty of
flexibility in whatever we deploy early, so we don't have to deprecate
stuff later. I think the m=<operator>... general pattern should work for
anything I can anticipate.
-- Dave
************************************************************ *
* David MacQuigg, PhD email: dmquigg-spf at yahoo.com * *
* IC Design Engineer phone: USA 520-721-4583 * * *
* Analog Design Methodologies * * *
* 9320 East Mikelyn Lane * * *
* VRS Consulting, P.C. Tucson, Arizona 85710 *
************************************************************ *
<Prev in Thread] |
Current Thread |
[Next in Thread>
|
- Mask Syntax,
David MacQuigg <=
|
|
|