Navigation Menu

Skip to content
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

services.tinydns: Extend module with typed DNS records #50891

Closed
wants to merge 1 commit into from

Conversation

spacefrogg
Copy link
Contributor

Improvements:

  • tinydns user with fixed UID
  • service is no longer stopped on configuration change but just its database is
    reloaded
  • Replace the untyped verbatim data option with a structured records option
  • Payloads for special DNS records, like URI or SRV, are properly encoded as
    256-byte short strings.
  • Timestamps can be supplied as seconds since Epoch and are converted to TAI64
Motivation for this change

More complicated record types, like URI or SRV records, need to be supplied as encoded strings to tinydns-data. This is hard to maintain, as it requires knowledge of the payload format as well as encoding integers in \000 octal notation. Additionally, timestamps are kept in TAI64 format and there is very little tooling available to tranform dates into TAI64 timestamps. The module is extended by a records option that provides types of DNS records which take various numbers of arguments and convert them into tinydns-data records.

Option format

The format of the DNS records is unusual as some have to be provided as functions, like this:

services.tinydns.records = [
  { data = ".example.com:1.2.3.4:a"; }
  { SRV = f: f "_some.service.example.com" 1 1 123 "server.example.com."; }
];

as opposed to a more conventional format like:

service.tinydns.records = [
  { type = "SRV"; service = "_some.service.example.com"; priority = 1; weight = 1;
    port = 123; target = "server.example.com."; }
];

The reason is simple: Even a medium site needs hundreds of records, which makes the first format, although harder to write at first, much easier to maintain and read in long lists of records.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

@nixos-discourse
Copy link

This pull request has been mentioned on Nix community. There might be relevant details there:

https://discourse.nixos.org/t/nixos-19-03-feature-freeze/1950/24

Copy link
Member

@aanderse aanderse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, any chance for a nixos test?

exec ./run
reload = ''
cd $ROOT
ln -sf ${pkgs.writeText "tinydns-data" configTxt} data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're linking to a build time text file which has already been linked. For what purpose? This file won't change during the life of a nixos generation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file data is merely the source input to the actual DNS database, which is constructed at the start of the service. The reason for this construction is threefold:

  1. High availability. If for some reason, nixos-rebuild on the DNS server is not working but the database requires a change, the user can turn data into a separate copy, alter its content and update the database without disrupting DNS service.
  2. Failover. If for some reason, the authoritative DNS server fails and a sub-ordinate DNS server (which would have received its database via some other means) is promoted, the user can turn data into a separate copy, etc.
  3. To ensure continous service, the user must be able to recreate database while the service is running. The protocol of the database compiler mandates that the source file is in the same directory as the result, making it necessary to (at least) provide a link in the database's final location.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah that all makes sense. Thanks for the answer.

@@ -32,23 +220,48 @@ with lib;
config = mkIf config.services.tinydns.enable {
environment.systemPackages = [ pkgs.djbdns ];

users.users.tinydns = {};
users.users.tinydns = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is tinydns generating runtime data which a normal system user needs to access? I've never used this software, but from simply looking at this change it appears as if you could use a DynamicUser instead of creating a new static user with static ids.

See: #11908 (comment) and #20186 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would not be necessary in this PR, but I have an extension in the pipeline (which only makes sense to introduce after this change has been approved) that would make use of a named user for sending authenticated DNS database updates to sub-ordinate tinydns instances.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK.

@spacefrogg
Copy link
Contributor Author

Also, any chance for a nixos test?

Do you have a relevant example I could peek from?

@aanderse
Copy link
Member

Also, any chance for a nixos test?

Do you have a relevant example I could peek from?

Nothing specifically in mind, just always good to have a test in nixos/tests for every module.

@spacefrogg
Copy link
Contributor Author

Updated. I added the test in the second commit and, while I was at it, added support for subordinate servers in the third commit (properly extending the test fixture).

@aanderse
Copy link
Member

Updated. I added the test in the second commit and, while I was at it, added support for subordinate servers in the third commit (properly extending the test fixture).

Glad to see a test. Looks like a new issue or two to work through, though.

@spacefrogg
Copy link
Contributor Author

Okay, I think, I satisfied the build bot.

@infinisil
Copy link
Member

services.tinydns.records = [
  { data = ".example.com:1.2.3.4:a"; }
  { SRV = f: f "_some.service.example.com" 1 1 123 "server.example.com."; }
];

I'm not a fan of this representation, because

  • What does it mean when an attribute set has a data and a SRV key?
  • Having to pass a function as config is in general discouraged as these aren't serializable. See also lib/types: add the selectorFunction type #44601 as well.
  • The function is really just used as a way to get a library function in scope without having to import the library, which is weird
  • The arguments of the function are hard to know what they are. In NixOS I especially like how all options have a proper name, this would eliminate that benefit.

So instead I propose this:

{ lib, ... }: {
  services.tinydns.records = with lib.dns; [
    (raw ".example.com:1.2.3.4:a")
    (srv "_some.service.example.com" 1 1 123 "server.example.com.")
  ];
}

Where these functions are defined somewhat like this in lib/dns.nix:

{
  raw = data: {
    type = "raw";
    value = data;
  };
  
  srv = service: priority: weight: port: target: {
    type = "srv";
    inherit service priority weight port target;
  };
  
  # ...
}

Namely, these functions should just capture the arguments, leaving the interpretation and encoding to tinydns. Therefore these functions should be compatible and usable by other dns servers as well. Like this, the user is still free to use full attribute names (which will also be in the docs).

@spacefrogg
Copy link
Contributor Author

  • What does it mean when an attribute set has a data and a SRV key?

It is an error, nix will tell you with a clear message that only one record type is allowed and yes, this is an oddity. I use it to have proper named NixOS options.

That is true in general and I am not proposing this format without proper thought. The reason I still chose functions was, that the data needs pre-computation (e.g. transformation of var-length strings to a list of fixed-length strings). This is a complexity level that cannot be easily hidden without hurting other properties badly.

  • The function is really just used as a way to get a library function in scope without having to import the library, which is weird

I'm sorry, but this is not the reason for it. This notation was the only way I found to feed nix an un-evaluated lambda function. If you look closely, you will notice that you are allowed to do the following:

{
  services.tinydns.records = [
    { SRV = f: f "_service.example.com" 1 1 23 "server.example.com"; }
    { SRV = f: f "_service.example.com" 1 1 23 "replacement-server.example.com" "" "future-timestamp"; }
  ];
}

With this construct, you can supply a variable amount of arguments to a lambda notation. I have not found another way to do this with nix.

Why all the effort? As I wrote in my initial PR, on a medium-sized DNS Server you have to maintain thousands of records. It is not these one or two records that might look weird in the beginning but screenfuls of it. Interspersing data with named arguments or supplying fake argument due to the lack of support for variable amount of arguments did not seem to cut it. Reducing line noise was a top priority.

  • The arguments of the function are hard to know what they are. In NixOS I especially like how all options have a proper name, this would eliminate that benefit.

I cannot follow your argument. When you look closely you see that the record type is distinguished by an attribute name on the left. This is, of course, implemented as a NixOS option and, thus, has proper documentation in the right place. Please have a look at the generated documentation to see if that fits together.

srv = service: priority: weight: port: target: {
type = "srv";
inherit service priority weight port target;
};

This would have the following drawbacks:

  • Function documentation separate from NixOS module documentation
  • No varargs to functions, i.e. a lot of fake args in the module.

Namely, these functions should just capture the arguments, leaving the interpretation and encoding to tinydns. Therefore these functions should be compatible and usable by other dns servers as well. Like this, the user is still free to use full attribute names (which will also be in the docs).

This can also be done in the current PR by using the data record type.

Having said all this: This is not my first PR to this project and I am very open to changes. Maintaining DNS records is a very special task that only hits very few users (but hits them hard). And I am proposing this non-obvious module with good reason and a lot of thought. So, if this does not find consent, I will gladly change it, but I beg to not ask for changes lightly or to just streamline it with the rest of the NixOS modules.

@vcunat
Copy link
Member

vcunat commented Feb 18, 2019

Well, personally I'm not convinced this representation of DNS RRs is a good approach. I believe the zonefile format is nice – to write by hand, easy to generate from whatever tools you like (including nix), and you can run a checker inside a derivation on it (e.g. load it into a server) – I see little motivation for such checks to be evaluation-time. Also it's been widely understood for decades.

EDIT: hmm, perhaps for some kinds of use cases, like overriding particular RRs 🤔

Still, I'm not tidnydns kind of person anyway, so I'll probably just leave the above comment here and not interfere anymore :-) I do DNS for job, though I'm on the resolver side.

@lheckemann
Copy link
Member

This still seems fairly contentious; I'm not very confident these issues will be resolved within the next week, so I'd suggest postponing this for 19.09. Unless of course everyone's happy with this by branch-off :)

@spacefrogg
Copy link
Contributor Author

Well, personally I'm not convinced this representation of DNS RRs is a good approach.

True, but this is not my position, here. I am convinced by the performance of the software and try to provide a reasonable means of configuring it via NixOS. I just take the input data format as a necessary thing this NixOS module has to provide. So, I am not making the rules, just reacting on them.

@spacefrogg
Copy link
Contributor Author

This still seems fairly contentious; I'm not very confident these issues will be resolved within the next week, so I'd suggest postponing this for 19.09. Unless of course everyone's happy with this by branch-off :)

What would be the procedure for progress? I worry that this PR is just forgotten for good in a month or so. (Given that it was initially open for 3 months without any action.)

@vcunat
Copy link
Member

vcunat commented Feb 18, 2019

NixPkgs merges over a thousand PRs per month, so it's quite common that "less interesting" things just fall through the cracks, unless e.g. the package has maintainers that react when you ping them, etc.

@lheckemann
Copy link
Member

I'd suggest (as an option which I can see leading to this getting merged before the 19.03 branch-off) reworking this to take out the controversial data generation and focus on the other improvements — enabling reload instead of restart and the high-availability mechanism. The data generation could be moved into its own module in NUR or similar.

@spacefrogg
Copy link
Contributor Author

Okay. I will rework this to just feature the pure (already encoded) data file and the rest of the improvements. I will add the data transformation functions to the library as @infinisil originally suggested.

@spacefrogg
Copy link
Contributor Author

@lheckemann, @infinisil I hope this is in acceptable form, now. Thanks for the review and hints!

@infinisil
Copy link
Member

Oh actually regarding the vararg thing, there is a slightly unorthodox way to get that:

nix-repl> f = { args = []; __functor = self: arg: self // { args = self.args ++ [ arg ]; }; }

nix-repl> (f 10 20 30).args
[ 10 20 30 ]

__functor is documented in the Nix manual so I think it's fine to use it, and this is a very good use case imo.

@spacefrogg spacefrogg force-pushed the tinydns-records branch 2 times, most recently from 825a124 to 57d1dea Compare November 13, 2019 17:23
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-in-distress/3604/18

@jonringer
Copy link
Contributor

please remove the merge commit, and use git pull -r origin master when updating a PR, this way the git history remains clean

@spacefrogg
Copy link
Contributor Author

Fixed.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-dns-a-nix-dsl-for-dns-zone-files/2466/4

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-dns-a-nix-dsl-for-dns-zone-files/2466/5

Copy link
Member

@aszlig aszlig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for your pull request. While I personally don't use djbdns (most of my deployments are either using knot or nsd), I decided to do a more detailed review prompting your comment on Discourse.

Since I wrote one of the other implementations of Nix DSLs mentioned on Discourse for DNS I'm biased, so I tried to not commented a whole lot on lib/tinydns.nix (plus others before me already did that). That said however, I don't think it's generic enough for this to be residing in lib/.

However - apart from the comments already made - the changes here are backwards-incompatible with the current module options with no changelog entry and no deprecation path.

Additionally the way you've implemented zone transfers is also highly subjective and opinionated, so I'd also leave that up to the user on deciding how to do zone transfers (if they're even needed at all, eg. if you're not deploying your DNS servers synchronously). Maybe even just allow to specify custom commands - but then again - this is already possible using systemd.services.foo.preStart &c.

So maybe @jerith666 (who did the initial implementation of the NixOS module and package), @flokli and @Mic92 can chime in here as well in order to have some more (possibly unbiased) input on this.

lib/tinydns.nix Outdated
# Capture the varargs parser and its varargs into a set containing all
# arguments as a list. Run the captured parser on the args when coercing the
# set to string.
captureParser = parser: { args = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this indented specially here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I messed up, fixed.

lib/tinydns.nix Outdated
inherit (builtins) attrNames genList head isFunction isString length
removeAttrs replaceStrings stringLength substring tail;

_lib = rec {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for not indenting the following lines by 4 spaces?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content looked too long to be bothered with correct indentation and rather take the real estate of the line length; in the image of all-packages.nix. Changed to correct indentation, as it doesn't matter much.

requested service, a priority (int), a weight (int), a port (int), and
a target.</para>

<para><literal>TXT</literal> has two mandatory arguments; the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need all these <para/> tags, since they're inserted automatically in text surrounded by two newlines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I didn't know. Changed.

type = types.bool;
description = "Whether to run the tinydns dns server";
};
services.tinydns = mkOption {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This essentially changes the option semantics in a non-backwards-compatible way, so this needs a changelog entry for users of the existing implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I already wondered how this must be handled. Didn't find documentation regarding this point. Who is responsible for this changelog entry?

}
'';
default = {};
type = with types; attrsOf (submodule (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider this to be pretty dangerous, since it essentially makes attributes in types over a very large scope, please consider doing this instead:

Suggested change
type = with types; attrsOf (submodule (
type = types.attrsOf (types.submodule (

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen this a lot but, sure. Changed it to explicit references.

# Expects tinydns data on standard input
tinydnsReceive = pkgs.writeScript "tinydns-receive" ''
#!${pkgs.stdenv.shell} -e
cd ${cfg.rootPath}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cd ${cfg.rootPath}
cd ${lib.escapeShellArg cfg.rootPath}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Changed.

serviceConfig = {
# Drops privileges and chroots to ROOT by itself
ExecStart = "${getBin pkgs.djbdns}/bin/tinydns";
LimitDATA = mkDefault "40000000";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for this default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tinydns, I know that this is a good working minimum. In case you do something funny with your zone transfers (run larger scripts or other sanity checking programs), you might need more memory.

# Drops privileges and chroots to ROOT by itself
ExecStart = "${getBin pkgs.djbdns}/bin/tinydns";
LimitDATA = mkDefault "40000000";
RestartSec = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is because of the one second sleep in the script of the receiving end of the zone transfer, so please add a comment here to make sure this is clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not. The default value was just needlessly slow and there's no point in losing 1000 requests just because your server sleeps for 5 seconds (I believe that's the default).

@@ -1,26 +1,71 @@
import ./make-test-python.nix ({ lib, ...} : {
import ./make-test.nix ({ pkgs, lib, ... }:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that Perl tests will be removed in NixOS 20.09.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll address that. Wasn't the case, when I first submitted this PR in Feb 2019. :)

StandardInput = "socket";
StandardError = "journal";
ExecStart = "${getBin pkgs.djbdns}/bin/axfrdns";
LimitDATA = mkDefault "15000000";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, why 15000000?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security, see above.

@spacefrogg
Copy link
Contributor Author

Since I wrote one of the other implementations of Nix DSLs mentioned on Discourse for DNS I'm biased, so I tried to not commented a whole lot on lib/tinydns.nix (plus others before me already did that). That said however, I don't think it's generic enough for this to be residing in lib/.

I would be gladly moving this out of lib/, but when I first made this PR there were no other entry points to make the functions available to the module user.

Additionally the way you've implemented zone transfers is also highly subjective and opinionated, so I'd also leave that up to the user on deciding how to do zone transfers (if they're even needed at all, eg. if you're not deploying your DNS servers synchronously). Maybe even just allow to specify custom commands - but then again - this is already possible using systemd.services.foo.preStart &c.

I do use synchronously deployed DNS servers. I implemented zone transfers as recommended by the author of tinydns. AXFR zone transfers have many known security issues, so while they are supported by tinydns, I didn't implement them. In fact, the only reason that the axfrdns is also running is to serve DNS records larger than 512kB and to accommodate certain clients that refuse to do UDP DNS queries.

@edolstra
Copy link
Member

edolstra commented Jun 30, 2020

IMHO this is waaay too complex and specialized to have in the nixpkgs repository. I think it would be better to have this kind of module in a separate repository (e.g. as a flake).

Also, reminder that Nix is not a general-purpose language and it's definitely not an appropriate language in which to write parsers. That sort of thing is likely to be very slow and memory-hungry. (BTW, lib is supposed to be generic. There should never be a file named lib/tinydns.nix.)

@spacefrogg
Copy link
Contributor Author

spacefrogg commented Jun 30, 2020

IMHO this is waaay too complex and specialized to have in the nixpkgs repository. I think it would be better to have this kind of module in a separate repository (e.g. as a flake).

I'll reduce this to take a list of entries, then, and put the lib/ code into a separate repository. Nix flakes wasn't an option back then and the only reason to have it in lib/ was that I did not find another way to make the functionality available to the user.

EDIT: The consequence of removing this functionality is, though, that the record database is practically forced to be monolithic. Every other nixos module would have to pull in the record-building functions from the outside, which would clearly not be compatible with upstream. No other nixos module could then supply DNS records. This is maybe acceptable, but I wanted to make that point known.

Also, reminder that Nix is not a general-purpose language and it's definitely not an appropriate language in which to write parsers. That sort of thing is likely to be very slow and memory-hungry. (BTW, lib is supposed to be generic. There should never be a file named lib/tinydns.nix.)

Just to be clear, I did not write a parser anywhere. It is just a generator that takes nix attributes and outputs the data formatted for tinydns. The tinydns database is never parsed or interpreted.

@flokli
Copy link
Contributor

flokli commented Jun 30, 2020

IMHO this is waaay too complex and specialized to have in the nixpkgs repository. I think it would be better to have this kind of module in a separate repository (e.g. as a flake).

I'll reduce this to take a list of entries, then, and put the lib/ code into a separate repository. Nix flakes wasn't an option back then and the only reason to have it in lib/ was that I did not find another way to make the functionality available to the user.

Referring to other flakes from inside nixpkgs probably isn't an option for quite some time.

Mainline nix doesn't support flakes yet, and minver.nix is still on 2.2 - so whatever code is added, it'd need to be compatible with Nix 2.2.

Adding config format generators to nixpkgs, not parsers, is probably fine, and has been done for many formats (see lib/generators.nix).

I agree the tinydns config format isn't generic enough to live in lib/generators.nix - but I wouldn't be opposed to having it in a nixos/modules/services/networking/tinydns/lib.nix, for example.

…records

 Module improvements:
 - Multiple instances:
   - Create one instance per listening IP address
 - Availability:
   - Generate database at startup and not at evaluation time. In case of a
     hazard, the database can be modified while tinydns is running
   - Service is no longer stopped on configuration change but just its database
     is reloaded
 - Add support to answer long queries via TCP using axfrdns
 - Add support for database propagation and secondary DNS servers:
   - Propagate DNS updates via SSH
 - Failover:
   - In case of a hazard a secondary DNS server can be momentarily promoted to
     primary maintaining uninterrupted service without the need for a working
     NixOS infrastructure

 Extend the nixos test; also tests database propagation via SSH and TCP queries.

 Add functions that generate DNS records suitable for tinydns-data(8), i.e.
 converting null-terminated strings to 256-byte short strings, octal encoding of
 typed data fields and special characters, TAI64 timestamp generation.
@spacefrogg
Copy link
Contributor Author

I could greatly simplify the approach without sacrificing functionality. Internally, the tinydns."xxx".data option is now a list of attribute sets.

The verbatim data record type, which contains opaque server-specific data:

{ type = "DATA"; data = "arbitrary verbatim output data"; }

Any other record type:

{ type = "record type"; ttl = "..."; ts = timestamp; location = split-horizon; <other record-specific attributes> };

e.g.

{ type = "TXT"; service = "_foo.service.domain"; txt = "text record content"; ttl = ""; ts = ""; location = ""; }

Records can be specified as strings (become DATA), lists with the record type as the first element (terse, by-order-of-arguments specification), or as attribute sets:

services.tinydns."0.0.0.0".data = [
''
  =a.b.c.d:10.0.0.1
  +e.b.c.d:10.0.0.1''
[ "TXT" "_kerberos.b.c.d" "B.C.D" ]
{ type = "SRV"; service = "_printers.b.c.d."; priority = 10; weight = 10; port = 631; target = "e.b.c.d."; }

Things, I'd like to point out:

  • The terse by-order-of-arguments format is still somewhat specific to tinydns. The last three elements of the list always denote ttl, ts and location. But this is not a global definition, other DNS servers could specify a different order of arguments.
  • The internal value of data is exclusively a list of attribute sets. So this should be easily convertible to arbitrary zone formats. (Except for DATA records, that obviously are server-specific).
  • The internal structure of the record attribute set should be agreed upon but is easily extensible, as each DNS server only draws from the attributes it knows about. Maybe this could be a good basis for a generic DNS data format.
  • Conversion of the internal data value to the output format is now done completely inside the module. There is no need for a library anymore.

@aszlig
Copy link
Member

aszlig commented Jun 30, 2020

@spacefrogg: Okay, this is going into a similar direction of Nix-dns now, except that you're using "list of X" versus "attribute set of X" and a few other semantic differences.

However, I'm not even sure if anyone would even want Nix-dns or even my implementation for that matter, so maybe I should have made it more clear earlier:

Please stop wasting your time going forward with this until at least one of the reviewers here thinks this is heading into the right direction.

I personally had lots of pull request going into the trash bin as well, even ones that were less controversial than this one, and if I parse the comments here correctly I think this is leading nowhere.

@Profpatsch
Copy link
Member

For reference, for opinionated packages/modules that are not general enough for nixpkgs/NixOS, we have the NUR, the Nix User Repository, to make those a bit easier to use.

@jerith666
Copy link
Contributor

So maybe @jerith666 (who did the initial implementation of the NixOS module and package) ... can chime in here as well in order to have some more (possibly unbiased) input on this.

Thanks for tagging me, I hadn't seen this yet.

I'm generally in favor of having a nix DSL for specifying DNS information. I think it'd be best if that DSL were server-agnostic, and let each server (nsd, tinydns, etc.) implement a translation layer to output its particular config file format.

I don't think I'm qualified to comment on much else here. My use case for tinydns is super simple, I just use it for SOA, NS, and A records for machines on my local network. I'm confident I could adapt to whatever others agree on! :)

@spacefrogg
Copy link
Contributor Author

Closing this as too opinionated and narrow scoped.

@spacefrogg spacefrogg closed this Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet