1{ config, pkgs, lib, ... }: 2 3let 4 5 inherit (lib) mkOption mkIf singleton; 6 inherit (pkgs) ddclient; 7 8 stateDir = "/var/spool/ddclient"; 9 ddclientUser = "ddclient"; 10 ddclientFlags = "-foreground -verbose -noquiet -file ${ddclientCfg}"; 11 ddclientPIDFile = "${stateDir}/ddclient.pid"; 12 ddclientCfg = pkgs.writeText "ddclient.conf" '' 13 daemon=600 14 cache=${stateDir}/ddclient.cache 15 pid=${ddclientPIDFile} 16 use=${config.services.ddclient.use} 17 login=${config.services.ddclient.username} 18 password=${config.services.ddclient.password} 19 protocol=${config.services.ddclient.protocol} 20 server=${config.services.ddclient.server} 21 ssl=${if config.services.ddclient.ssl then "yes" else "no"} 22 wildcard=YES 23 ${config.services.ddclient.domain} 24 ${config.services.ddclient.extraConfig} 25 ''; 26 27in 28 29{ 30 31 ###### interface 32 33 options = { 34 35 services.ddclient = with lib.types; { 36 37 enable = mkOption { 38 default = false; 39 type = bool; 40 description = '' 41 Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org). 42 ''; 43 }; 44 45 domain = mkOption { 46 default = ""; 47 type = str; 48 description = '' 49 Domain name to synchronize. 50 ''; 51 }; 52 53 username = mkOption { 54 default = ""; 55 type = str; 56 description = '' 57 Username. 58 ''; 59 }; 60 61 password = mkOption { 62 default = ""; 63 type = str; 64 description = '' 65 Password. 66 ''; 67 }; 68 69 protocol = mkOption { 70 default = "dyndns2"; 71 type = str; 72 description = '' 73 Protocol to use with dynamic DNS provider (see http://sourceforge.net/apps/trac/ddclient/wiki/Protocols). 74 ''; 75 }; 76 77 server = mkOption { 78 default = ""; 79 type = str; 80 description = '' 81 Server address. 82 ''; 83 }; 84 85 ssl = mkOption { 86 default = true; 87 type = bool; 88 description = '' 89 Whether to use to use SSL/TLS to connect to dynamic DNS provider. 90 ''; 91 }; 92 93 extraConfig = mkOption { 94 default = ""; 95 type = str; 96 description = '' 97 Extra configuration. Contents will be added verbatim to the configuration file. 98 ''; 99 }; 100 101 use = mkOption { 102 default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '"; 103 type = str; 104 description = '' 105 Method to determine the IP address to send to the dymanic DNS provider. 106 ''; 107 }; 108 }; 109 }; 110 111 112 ###### implementation 113 114 config = mkIf config.services.ddclient.enable { 115 116 environment.systemPackages = [ ddclient ]; 117 118 users.extraUsers = singleton { 119 name = ddclientUser; 120 uid = config.ids.uids.ddclient; 121 description = "ddclient daemon user"; 122 home = stateDir; 123 }; 124 125 systemd.services.ddclient = { 126 description = "Dynamic DNS Client"; 127 wantedBy = [ "multi-user.target" ]; 128 after = [ "network.target" ]; 129 130 serviceConfig = { 131 # Uncomment this if too many problems occur: 132 # Type = "forking"; 133 User = ddclientUser; 134 Group = "nogroup"; #TODO get this to work 135 PermissionsStartOnly = "true"; 136 PIDFile = ddclientPIDFile; 137 ExecStartPre = '' 138 ${pkgs.stdenv.shell} -c "${pkgs.coreutils}/bin/mkdir -m 0755 -p ${stateDir} && ${pkgs.coreutils}/bin/chown ${ddclientUser} ${stateDir}" 139 ''; 140 ExecStart = "${ddclient}/bin/ddclient ${ddclientFlags}"; 141 #ExecStartPost = "${pkgs.coreutils}/bin/rm -r ${stateDir}"; # Should we have this? 142 }; 143 }; 144 }; 145}