diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6734929b9d4..afa9d9cc801 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -706,6 +706,7 @@
./services/networking/shorewall6.nix
./services/networking/shout.nix
./services/networking/sniproxy.nix
+ ./services/networking/smartdns.nix
./services/networking/smokeping.nix
./services/networking/softether.nix
./services/networking/spacecookie.nix
diff --git a/nixos/modules/services/networking/smartdns.nix b/nixos/modules/services/networking/smartdns.nix
new file mode 100644
index 00000000000..f1888af7041
--- /dev/null
+++ b/nixos/modules/services/networking/smartdns.nix
@@ -0,0 +1,61 @@
+{ lib, pkgs, config, ... }:
+
+with lib;
+
+let
+ inherit (lib.types) attrsOf coercedTo listOf oneOf str int bool;
+ cfg = config.services.smartdns;
+
+ confFile = pkgs.writeText "smartdns.conf" (with generators;
+ toKeyValue {
+ mkKeyValue = mkKeyValueDefault {
+ mkValueString = v:
+ if isBool v then
+ if v then "yes" else "no"
+ else
+ mkValueStringDefault { } v;
+ } " ";
+ listsAsDuplicateKeys =
+ true; # Allowing duplications because we need to deal with multiple entries with the same key.
+ } cfg.settings);
+in {
+ options.services.smartdns = {
+ enable = mkEnableOption "SmartDNS DNS server";
+
+ bindPort = mkOption {
+ type = types.port;
+ default = 53;
+ description = "DNS listening port number.";
+ };
+
+ settings = mkOption {
+ type =
+ let atom = oneOf [ str int bool ];
+ in attrsOf (coercedTo atom toList (listOf atom));
+ example = literalExample ''
+ {
+ bind = ":5353 -no-rule -group example";
+ cache-size = 4096;
+ server-tls = [ "8.8.8.8:853" "1.1.1.1:853" ];
+ server-https = "https://cloudflare-dns.com/dns-query -exclude-default-group";
+ prefetch-domain = true;
+ speed-check-mode = "ping,tcp:80";
+ };
+ '';
+ description = ''
+ A set that will be generated into configuration file, see the SmartDNS README for details of configuration parameters.
+ You could override the options here like by writing settings.bind = ":5353 -no-rule -group example";.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.smartdns.settings.bind = mkDefault ":${toString cfg.bindPort}";
+
+ systemd.packages = [ pkgs.smartdns ];
+ systemd.services.smartdns.wantedBy = [ "multi-user.target" ];
+ environment.etc."smartdns/smartdns.conf".source = confFile;
+ environment.etc."default/smartdns".source =
+ "${pkgs.smartdns}/etc/default/smartdns";
+ };
+}