[dns-operations] First experiments with DNS dampening to fight amplification attacks

Lutz Donnerhacke lutz at iks-jena.de
Mon Oct 15 23:00:04 UTC 2012

* Lutz Donnerhacke wrote:
> The defaults are not optimal yet.

If they are optimal or not is still an open question. But the patch is
useable now. Far from perfect or finished, but used in practice.

Unfortunly I do have a serious problem: The attack volume decreased that
drastically on my servers, that I can't test the patch in real
environments anymore. I do have one or two amplification attackes per hour
left ... #firstworldproblems

So if anybody is willing to try it out: Please do. Please report to me.

Minimal configuration is "dampening {};" in "options" or "view". I do
recommend at least "dampening { exempt-clients { local_AS; resolvers; };};".

If you want to help, please add "report-interval <secs>;". The number of
seconds should be less than the overrun of a 32bit counter under your query
rate. Reports can be found in the "dampening" category.

There are two implemtations activated in the patch: The (old) heap and a
(new) hash/queue. I do not know which of them performs better so I run both
in parallel to gather information. If you do not like such a play, please
remove the approbiate init function from "implementations" in dampening.c.
Personally I do think, the heap implementation is more stable to variable
load, but I do not have hard evidence for it yet.

Please let me thank the developers of the RRL patch, which point me to the
right files. I'm still unsure, if the RRL patch and my idea came to the same
results at the current type of attacks. I'm still wonder, if the patch
really survives a higher query rate than those I have access to.

-------------------- Cut from the changed ARM --------------------
    Spoofed UDP queries are a major security threat especially when
    reflected and possibly amplified by DNS servers. Dampening is a
    dynamically adapting method for dealing with such kinds of misuse.
    So dampening a about spoofing, hence TCP connections are not
    affected at all.
    Every piece of a query and its response is associated with
    specific penalty points. Those points aggregate over all queries
    from netblocks defined by |IPv6-prefix-length| and
    |IPv4-prefix-length|. Over the time, the penalty
    decreases exponentially (determined by |halflife|).
    So each netblock gains a penalty over time characteristics.
    In order to allow local clients, which should be protected by
    anti-spoof techniques at the edge of the operated network, to
    send any amount of queries without fear the risks of being blocked,
    push them into a seperate view with other or no dampening rules or
    add them to |exempt-clients|.
    If the penalty exeeds |limit-enable-dampening|, the netblock gets
    dampened. No further query processing will occur.
    Every further query is dropped silently before inspecting the
    content of the query itself. So the penalty value can decrease
    slowly, if the sender collect not quickly enough further
    |score-per-query| points. Please note, that
    penalty values can't exceed |limit-maximum|.
    If the penalty drops below |limit-disable-dampening|,
    query processing for the netblock switchs back to normal. If
    the penalty drops as low as |limit-irrelevant|,
    the netblock is removed ..from the statistics. The next query
    gains |score-first-query| for this netblock
    and reenteres the collection.
    Comment current attacks gain a huge amplification from ANY query
    to DNSSEC signed zones. So each ANY query is charged with
    additional |score-qtype-any| points. Furthermore
    current attackers repeat the same packet over and over again, so
    keeping the same id in each query. Such repetitions are recognised
    and give |score-duplicates| points times the
    repetition of this id.

    Amplification attacks aims to huge answers, so the next penalty
    comes from the response size. The penalty increased lineary from
    zero for responses up to |minimum-score-size|
    bytes. The maximum penalty of |score-size| is
    reached when the response reaches or exceeds
    |maximum-score-size| bytes.
    In order to minimize expensive calulations for each query, the
    penalty decay is delayed by at least
    |update-delay| seconds. The statistics table
    has space for |min-table-size| elements but
    might increase to |max-table-size| elements if
    In order to compare various storage models, which are activated
    at compile time, regular statistics can by extracted by setting
    |report-interval| to the seconds between reports.
    Those statistic lines contain the numerical index of the
    implementation |Stats for #...|, the number of
    queries processed, dampened, and exempted |queries ././.|,
    and aggregated time spend in the various functions.
-------------------- End of Cut --------------------

More information about the dns-operations mailing list