dnschain service: overhaul option interface & implementation

Closes https://github.com/NixOS/nixpkgs/pull/22041

rnhmjoj f7d49037 07888892

Changed files
+116 -59
nixos
modules
services
networking
+116 -59
nixos/modules/services/networking/dnschain.nix
···
with lib;
let
-
cfg = config.services;
+
cfgs = config.services;
+
cfg = cfgs.dnschain;
+
+
dataDir = "/var/lib/dnschain";
+
username = "dnschain";
-
dnschainConf = pkgs.writeText "dnschain.conf" ''
+
configFile = pkgs.writeText "dnschain.conf" ''
[log]
-
level=info
+
level = info
[dns]
-
host = 127.0.0.1
-
port = 5333
+
host = ${cfg.dns.address}
+
port = ${toString cfg.dns.port}
oldDNSMethod = NO_OLD_DNS
-
# TODO: check what that address is acutally used for
-
externalIP = 127.0.0.1
+
externalIP = ${cfg.dns.address}
[http]
-
host = 127.0.0.1
-
port=8088
-
tlsPort=4443
+
host = ${cfg.api.hostname}
+
port = ${toString cfg.api.port}
+
tlsPort = ${toString cfg.api.tlsPort}
+
+
${cfg.extraConfig}
'';
in
···
services.dnschain = {
-
enable = mkOption {
-
type = types.bool;
-
default = false;
+
enable = mkEnableOption ''
+
DNSChain, a blockchain based DNS + HTTP server.
+
To resolve .bit domains set <literal>services.namecoind.enable = true;</literal>
+
and an RPC username/password.
+
'';
+
+
dns.address = mkOption {
+
type = types.str;
+
default = "127.0.0.1";
description = ''
-
Whether to run dnschain. That implies running
-
namecoind as well, so make sure to configure
-
it appropriately.
+
The IP address that will be used to reach this machine.
+
Leave this unchanged if you do not wish to directly expose the DNSChain resolver.
'';
};
-
};
+
dns.port = mkOption {
+
type = types.int;
+
default = 5333;
+
description = ''
+
The port the DNSChain resolver will bind to.
+
'';
+
};
-
services.dnsmasq = {
-
resolveDnschainQueries = mkOption {
-
type = types.bool;
-
default = false;
+
api.hostname = mkOption {
+
type = types.str;
+
default = "0.0.0.0";
description = ''
-
Resolve <literal>.bit</literal> top-level domains
-
with dnschain and namecoind.
+
The hostname (or IP address) the DNSChain API server will bind to.
+
'';
+
};
+
+
api.port = mkOption {
+
type = types.int;
+
default = 8080;
+
description = ''
+
The port the DNSChain API server (HTTP) will bind to.
+
'';
+
};
+
+
api.tlsPort = mkOption {
+
type = types.int;
+
default = 4433;
+
description = ''
+
The port the DNSChain API server (HTTPS) will bind to.
+
'';
+
};
+
+
extraConfig = mkOption {
+
type = types.lines;
+
default = "";
+
example = ''
+
[log]
+
level = debug
+
'';
+
description = ''
+
Additional options that will be appended to the configuration file.
'';
};
};
+
services.dnsmasq.resolveDNSChainQueries = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin.
+
'';
+
};
+
+
services.pdns-recursor.resolveDNSChainQueries = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin.
+
'';
+
};
+
};
###### implementation
-
config = mkIf cfg.dnschain.enable {
+
config = mkIf cfg.enable {
-
services.namecoind.enable = true;
-
-
services.dnsmasq.servers = optionals cfg.dnsmasq.resolveDnschainQueries [ "/.bit/127.0.0.1#5333" ];
+
services.dnsmasq.servers = optionals cfgs.dnsmasq.resolveDNSChainQueries
+
[ "/.bit/127.0.0.1#${toString cfg.dns.port}"
+
"/.dns/127.0.0.1#${toString cfg.dns.port}"
+
];
-
users.extraUsers = singleton
-
{ name = "dnschain";
-
uid = config.ids.uids.dnschain;
-
extraGroups = [ "namecoin" ];
-
description = "Dnschain daemon user";
-
home = "/var/lib/dnschain";
-
createHome = true;
+
services.pdns-recursor.forwardZones = mkIf cfgs.pdns-recursor.resolveDNSChainQueries
+
{ bit = "127.0.0.1:${toString cfg.dns.port}";
+
dns = "127.0.0.1:${toString cfg.dns.port}";
};
+
+
users.extraUsers = singleton {
+
name = username;
+
description = "DNSChain daemon user";
+
home = dataDir;
+
createHome = true;
+
uid = config.ids.uids.dnschain;
+
extraGroups = optional cfgs.namecoind.enable "namecoin";
+
};
systemd.services.dnschain = {
-
description = "Dnschain Daemon";
-
after = [ "namecoind.target" ];
-
wantedBy = [ "multi-user.target" ];
-
path = [ pkgs.openssl ];
-
preStart = ''
-
# Link configuration file into dnschain HOME directory
-
if [ "$(${pkgs.coreutils}/bin/realpath /var/lib/dnschain/.dnschain.conf)" != "${dnschainConf}" ]; then
-
rm -rf /var/lib/dnschain/.dnschain.conf
-
ln -s ${dnschainConf} /var/lib/dnschain/.dnschain.conf
-
fi
+
description = "DNSChain daemon";
+
after = optional cfgs.namecoind.enable "namecoind.target";
+
wantedBy = [ "multi-user.target" ];
-
# Create empty namecoin.conf so that dnschain is not
-
# searching for /etc/namecoin/namecoin.conf
-
if [ ! -e /var/lib/dnschain/.namecoin/namecoin.conf ]; then
-
mkdir -p /var/lib/dnschain/.namecoin
-
touch /var/lib/dnschain/.namecoin/namecoin.conf
-
fi
-
'';
-
serviceConfig = {
-
Type = "simple";
-
User = "dnschain";
-
EnvironmentFile = config.services.namecoind.userFile;
-
ExecStart = "${pkgs.dnschain}/bin/dnschain --rpcuser=\${USER} --rpcpassword=\${PASSWORD} --rpcport=8336";
-
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-
ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID";
-
};
+
serviceConfig = {
+
User = "dnschain";
+
Restart = "on-failure";
+
ExecStart = "${pkgs.dnschain}/bin/dnschain";
+
};
+
+
preStart = ''
+
# Link configuration file into dnschain home directory
+
configPath=${dataDir}/.dnschain/dnschain.conf
+
mkdir -p ${dataDir}/.dnschain
+
if [ "$(realpath $configPath)" != "${configFile}" ]; then
+
rm -f $configPath
+
ln -s ${configFile} $configPath
+
fi
+
'';
};
};