-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include caller arguments and introduce new query
type
#366
Comments
This isn't possible with the current implementation unfortunately. It's mostly a limitation of the configuration language chosen (TOML). This requires a rewrite of significant parts to support a more flexible way to configure it, possibly using a higher-level language for config. I've been considering doing that but not sure I'll have time for it in the foreseeable future. |
These are mostly gimmicks so it's understandable that it's not a priority. Anyway, I have another example (for people that can't disable their routers' DNS rebind protection): [routers.router]
routes = [
{ resolver = "dns-rebind-emulator", type = "A", name = '\.rebind\.$' },
{ resolver = "myresolver" }
]
[groups.dns-rebind-emulator]
type = "replace"
resolvers = [ "dns-rebind-emulator-helper" ]
replace = [
{ from = '^(\d+)-(\d+)-(\d+)-(\d+)\.rebind\.$', to = '${1}.${2}.${3}.${4}.' }
]
[groups.dns-rebind-emulator-helper]
type = "static-responder"
answer = [ "IN A $1" ] Regarding the 2nd suggestion, do you think that's possible with current tools? |
If I understand it correctly you need a responder that can build a response based on the query name, right? This should be possible, and in fact there's a lot of potential here. Let's just make this even more generic. What if we had an element that would allow some simple scripting language to be defined, that could eval the input and either build the output or forward to another group? That'd be extremely powerful and could probably even do what you were asking in part 1 and more. Just a mockup, but perhaps it could look like [groups.my-script]
type = "script-modifier"
resolvers = [ "resolver1", "resolver2" ]
script = '
<some script language that can take the input, then either produce a response or forward to any resolver>
' Would have to find a script interpreter that integrates well, perhaps https://github.com/Shopify/go-lua or https://github.com/yuin/gopher-lua (not used either one yet). |
What does the resolver do in this example? The group takes an input, gives it to the script, the script returns something and that gets forwarded to the resolver? I don't think that's gonna be too useful. I guess preparing something for another group could be useful, but we already got replace and routers, what else could one want? If scripting were to be introduced (which I don't think is a good idea anyway), I would make it a resolver. So emulating [resolvers.myscript]
type = "script"
address = "script.sh"
[routers.router]
routes = [
{ resolver = "myscript", type = "ANY" },
{ resolver = "myresolver" }
] #!/bin/bash
for t in A AAAA CAA HTTPS MX NS SOA TXT; do
dig +noall +answer $2 $t
done But then again, I feel like this could almost be done exclusively with the tools already provided. |
Maybe some of this can be done similar as with |
It's definitely possible to implement something like that, a group that takes the query-name, applies a regex, and generates the response IP for it. It's just that this would be very specific to one use-case with a lot of limitations:
With the scripting element I was thinking it'd add a low-level way to do custom modifications. It wouldn't be a shell script of course, but some other language that can inspect and modify queries and responses. In the example above the "resolvers" would be optional. The script would receive a query and could then decide to either answer it directly, or forward to one of the defined resolvers. It'd allow implementing custom routing, load-balancing, etc. Not sure how complex that'd be to implement yet. Perhaps a basic "derive-answer-from-query-name" element would be the right approach for now. |
It's just that scripting is a can of worms. Or rather executing any external file is. Maybe inline scripting is enough, possible in a language that can't do much damage (e.g. Lua)? Generally speaking, I think a query merger makes sense: Send your query to multiple resolvers (e.g. Cloudflare and Google), collect the answers, remove duplicates and return. That would be the first (technically last) step to emulate |
It'd definitely be inline Lua with a small set of pre-defined functions to manipulate DNS queries and responses, no sub-processes or shell access. With that one could then implement pretty much any behavior that may be missing from the standard elements (though a little slower). Implementing this requires a bit more time than I can currently spend. In the mean time, perhaps I could implement what you asked like so: [routers.router]
routes = [
{ resolver = "dns-rebind-emulator", type = "A", name = '\.rebind\.$' },
{ resolver = "myresolver" }
]
[groups.dns-rebind-emulator-helper]
type = "static-responder"
query-name-regex = '^(\d+)-(\d+)-(\d+)-(\d+)\.rebind\.$'
answer = [ "IN A ${1}.${2}.${3}.${4}." ] This would allow you to use the content of the query name to build a static response. It should solve the original ask. Not a fan of that there being some dynamic behavior in a group named "static-responder" but it's not too bad. This is relatively easy to add. Any thoughts on doing this? |
Doesn't win the beauty contest, but works. :-) I think for the cases mentioned it should be fine and should be sufficient. |
Looks okay but I don't really like [groups.blocklist-resolver]
type = "static-responder"
question = "^(.+)\.$"
answer = [ "IN A 0.0.0.0" ]
edns0-ede = { code = 15, text = "IP ${1} is in the blocklist" } |
Would you be able to try out the [groups.static]
type = "static-responder"
question = '^(\d+)-(\d+)-(\d+)-(\d+)\.rebind\.$'
answer = ["IN A $1.$2.$3.$4"] [groups.static]
type = "static-responder"
question = '^(.+)\.$'
answer = [ "IN A 0.0.0.0" ]
edns0-ede = { code = 15, text = "IP $1 is in the blocklist" } |
#373 lets you specify an extended error message from the blocklist. And it lets you customize the whole message. Would you be able to try that out? |
#378 adds a new I think this solution is better than using regexes, and it should be more powerful as it allows customizing all response records, not just the answers. |
The base case works but it breaks when |
Not sure I understand what exactly fails. Do you have an example config I can try? |
[groups.blocklist-resolver]
type = "static-responder"
answer = [ "IN A 0.0.0.0" ]
[groups.blocklist]
type = "blocklist-v2"
resolvers = [ "cloudflare" ]
#blocklist-resolver = "blocklist-resolver"
blocklist-format = "domain"
blocklist = [ "evil.com" ]
edns0-ede = { code = 15, text = "{{ .Question }}" } This example will have |
Yes, that is actually correct/expected. |
Ok so the first (block reason in EDE text) and third (rebind emulation) suggestions are possible now. Do you think the second (ANY emulation) is something that's worth implementing? I think that it sounds interesting (mostly for getting |
When a group calls another group it would be great to have access to the arguments, e.g.
And I would also like to propose the idea of a new
query
group which allows you to construct your own query (this also needs support for arguments). Could be useful for changing the query type or question, e.g.The text was updated successfully, but these errors were encountered: