aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/networking/ncdns.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking/ncdns.nix')
-rw-r--r--nixpkgs/nixos/modules/services/networking/ncdns.nix278
1 files changed, 278 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/ncdns.nix b/nixpkgs/nixos/modules/services/networking/ncdns.nix
new file mode 100644
index 00000000000..c1832ad1752
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/ncdns.nix
@@ -0,0 +1,278 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfgs = config.services;
+ cfg = cfgs.ncdns;
+
+ dataDir = "/var/lib/ncdns";
+ username = "ncdns";
+
+ valueType = with types; oneOf [ int str bool path ]
+ // { description = "setting type (integer, string, bool or path)"; };
+
+ configType = with types; attrsOf (nullOr (either valueType configType))
+ // { description = ''
+ ncdns.conf configuration type. The format consists of an
+ attribute set of settings. Each setting can be either `null`,
+ a value or an attribute set. The allowed values are integers,
+ strings, booleans or paths.
+ '';
+ };
+
+ configFile = pkgs.runCommand "ncdns.conf"
+ { json = builtins.toJSON cfg.settings;
+ passAsFile = [ "json" ];
+ }
+ "${pkgs.remarshal}/bin/json2toml < $jsonPath > $out";
+
+ defaultFiles = {
+ public = "${dataDir}/bit.key";
+ private = "${dataDir}/bit.private";
+ zonePublic = "${dataDir}/bit-zone.key";
+ zonePrivate = "${dataDir}/bit-zone.private";
+ };
+
+ # if all keys are the default value
+ needsKeygen = all id (flip mapAttrsToList cfg.dnssec.keys
+ (n: v: v == getAttr n defaultFiles));
+
+ mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.ncdns = {
+
+ enable = mkEnableOption ''
+ ncdns, a Go daemon to bridge Namecoin to DNS.
+ To resolve .bit domains set <literal>services.namecoind.enable = true;</literal>
+ and an RPC username/password
+ '';
+
+ address = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ The IP address the ncdns resolver will bind to. Leave this unchanged
+ if you do not wish to directly expose the resolver.
+ '';
+ };
+
+ port = mkOption {
+ type = types.port;
+ default = 5333;
+ description = ''
+ The port the ncdns resolver will bind to.
+ '';
+ };
+
+ identity.hostname = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ example = "example.com";
+ description = ''
+ The hostname of this ncdns instance, which defaults to the machine
+ hostname. If specified, ncdns lists the hostname as an NS record at
+ the zone apex:
+ <programlisting>
+ bit. IN NS ns1.example.com.
+ </programlisting>
+ If unset ncdns will generate an internal psuedo-hostname under the
+ zone, which will resolve to the value of
+ <option>services.ncdns.identity.address</option>.
+ If you are only using ncdns locally you can ignore this.
+ '';
+ };
+
+ identity.hostmaster = mkOption {
+ type = types.str;
+ default = "";
+ example = "root@example.com";
+ description = ''
+ An email address for the SOA record at the bit zone.
+ If you are only using ncdns locally you can ignore this.
+ '';
+ };
+
+ identity.address = mkOption {
+ type = types.str;
+ default = "127.127.127.127";
+ description = ''
+ The IP address the hostname specified in
+ <option>services.ncdns.identity.hostname</option> should resolve to.
+ If you are only using ncdns locally you can ignore this.
+ '';
+ };
+
+ dnssec.enable = mkEnableOption ''
+ DNSSEC support in ncdns. This will generate KSK and ZSK keypairs
+ (unless provided via the options
+ <option>services.ncdns.dnssec.publicKey</option>,
+ <option>services.ncdns.dnssec.privateKey</option> etc.) and add a trust
+ anchor to recursive resolvers
+ '';
+
+ dnssec.keys.public = mkOption {
+ type = types.path;
+ default = defaultFiles.public;
+ description = ''
+ Path to the file containing the KSK public key.
+ The key can be generated using the <literal>dnssec-keygen</literal>
+ command, provided by the package <package>bind</package> as follows:
+ <programlisting>
+ $ dnssec-keygen -a RSASHA256 -3 -b 2048 -f KSK bit
+ </programlisting>
+ '';
+ };
+
+ dnssec.keys.private = mkOption {
+ type = types.path;
+ default = defaultFiles.private;
+ description = ''
+ Path to the file containing the KSK private key.
+ '';
+ };
+
+ dnssec.keys.zonePublic = mkOption {
+ type = types.path;
+ default = defaultFiles.zonePublic;
+ description = ''
+ Path to the file containing the ZSK public key.
+ The key can be generated using the <literal>dnssec-keygen</literal>
+ command, provided by the package <package>bind</package> as follows:
+ <programlisting>
+ $ dnssec-keygen -a RSASHA256 -3 -b 2048 bit
+ </programlisting>
+ '';
+ };
+
+ dnssec.keys.zonePrivate = mkOption {
+ type = types.path;
+ default = defaultFiles.zonePrivate;
+ description = ''
+ Path to the file containing the ZSK private key.
+ '';
+ };
+
+ settings = mkOption {
+ type = configType;
+ default = { };
+ example = literalExample ''
+ { # enable webserver
+ ncdns.httplistenaddr = ":8202";
+
+ # synchronize TLS certs
+ certstore.nss = true;
+ # note: all paths are relative to the config file
+ certstore.nsscertdir = "../../var/lib/ncdns";
+ certstore.nssdbdir = "../../home/alice/.pki/nssdb";
+ }
+ '';
+ description = ''
+ ncdns settings. Use this option to configure ncds
+ settings not exposed in a NixOS option or to bypass one.
+ See the example ncdns.conf file at <link xlink:href="
+ https://git.io/JfX7g"/> for the available options.
+ '';
+ };
+
+ };
+
+ services.pdns-recursor.resolveNamecoin = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Resolve <literal>.bit</literal> top-level domains using ncdns and namecoin.
+ '';
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveNamecoin {
+ forwardZonesRecurse.bit = "127.0.0.1:${toString cfg.port}";
+ luaConfig =
+ if cfg.dnssec.enable
+ then ''readTrustAnchorsFromFile("${cfg.dnssec.keys.public}")''
+ else ''addNTA("bit", "namecoin DNSSEC disabled")'';
+ };
+
+ # Avoid pdns-recursor not finding the DNSSEC keys
+ systemd.services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveNamecoin {
+ after = [ "ncdns.service" ];
+ wants = [ "ncdns.service" ];
+ };
+
+ services.ncdns.settings = mkDefaultAttrs {
+ ncdns =
+ { # Namecoin RPC
+ namecoinrpcaddress =
+ "${cfgs.namecoind.rpc.address}:${toString cfgs.namecoind.rpc.port}";
+ namecoinrpcusername = cfgs.namecoind.rpc.user;
+ namecoinrpcpassword = cfgs.namecoind.rpc.password;
+
+ # Identity
+ selfname = cfg.identity.hostname;
+ hostmaster = cfg.identity.hostmaster;
+ selfip = cfg.identity.address;
+
+ # Other
+ bind = "${cfg.address}:${toString cfg.port}";
+ }
+ // optionalAttrs cfg.dnssec.enable
+ { # DNSSEC
+ publickey = "../.." + cfg.dnssec.keys.public;
+ privatekey = "../.." + cfg.dnssec.keys.private;
+ zonepublickey = "../.." + cfg.dnssec.keys.zonePublic;
+ zoneprivatekey = "../.." + cfg.dnssec.keys.zonePrivate;
+ };
+
+ # Daemon
+ service.daemon = true;
+ xlog.journal = true;
+ };
+
+ users.users.ncdns =
+ { description = "ncdns daemon user"; };
+
+ systemd.services.ncdns = {
+ description = "ncdns daemon";
+ after = [ "namecoind.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ User = "ncdns";
+ StateDirectory = "ncdns";
+ Restart = "on-failure";
+ ExecStart = "${pkgs.ncdns}/bin/ncdns -conf=${configFile}";
+ };
+
+ preStart = optionalString (cfg.dnssec.enable && needsKeygen) ''
+ cd ${dataDir}
+ if [ ! -e bit.key ]; then
+ ${pkgs.bind}/bin/dnssec-keygen -a RSASHA256 -3 -b 2048 bit
+ mv Kbit.*.key bit-zone.key
+ mv Kbit.*.private bit-zone.private
+ ${pkgs.bind}/bin/dnssec-keygen -a RSASHA256 -3 -b 2048 -f KSK bit
+ mv Kbit.*.key bit.key
+ mv Kbit.*.private bit.private
+ fi
+ '';
+ };
+
+ };
+
+ meta.maintainers = with lib.maintainers; [ rnhmjoj ];
+
+}