coredns

How to forward request to next resolver if name not resolved


I have multiple upstream resolvers in my coredns config, e.g.:

foo.com {
  forward . XX.XX.XX.XX YY.YY.YY.YY ZZ.ZZ.ZZ.ZZ
}

I want to forward the request to those servers, but only one knows how to resolve a specific query. (e.g.: only ZZ knows how to resolve a.foo.com)

How can I forward the request to the next upstream if the first one doesn't know how to resolve the query?


Solution

  • Unfortunatelly forward alone does not offer fallthrough mechanism, so in this situation you would have to use something else. One such solution would be using the alternate plugin (https://coredns.io/explugins/alternate). It is maintained by the own coredns team.

    By using the plugin, your configuration:

    foo.com {
        forward . XX.XX.XX.XX YY.YY.YY.YY ZZ.ZZ.ZZ.ZZ
    }
    

    Would turn into something like:

    foo.com {
        forward . XX.XX.XX.XX
        alternate NXDOMAIN,SERVFAIL,REFUSED . YY.YY.YY.YY
        alternate NXDOMAIN,SERVFAIL,REFUSED . ZZ.ZZ.ZZ.ZZ
    }
    

    Beware of the fact that the order will be always followed, so the first node would have more pressure than the others. If you don't want that then you would probably need to write your own plugin.

    To use the this plugin or don't forget to recompile coredns with the plugin included in plugin.cfg - before forward.

    If you are having trouble building it from source, I wrote a script:

    git clone https://github.com/coredns/coredns
    cd coredns/plugin
    git clone https://github.com/coredns/alternate
    cd ..
    sed -i "s/^require/replace github.com\/coredns\/coredns\/plugin\/alternate \=\> ${PWD//\//\\\/}\/plugin\/alternate\n\nrequire/" go.mod
    sed -i s/forward:forward/alternate:alternate\\nforward:forward/ plugin.cfg
    make
    cd ..
    

    Basically it downloads coredns and then alternate to one of its subfolders. The first sed is the necessary step to tell coredns to include this plugin in the build and the second sed instructs go to use your local folder that you just downloaded alternate instead of looking in github. Before running make I recommend taking out from plugin.cfg other plugins you know you won't be using, like etcd, kubernetes, etc.