1# /etc files related to networking, such as /etc/services. 2 3{ config, lib, pkgs, ... }: 4 5with lib; 6 7let 8 9 cfg = config.networking; 10 dnsmasqResolve = config.services.dnsmasq.enable && 11 config.services.dnsmasq.resolveLocalQueries; 12 hasLocalResolver = config.services.bind.enable || dnsmasqResolve; 13 14in 15 16{ 17 18 options = { 19 20 networking.extraHosts = lib.mkOption { 21 type = types.lines; 22 default = ""; 23 example = "192.168.0.1 lanlocalhost"; 24 description = '' 25 Additional entries to be appended to <filename>/etc/hosts</filename>. 26 ''; 27 }; 28 29 networking.dnsSingleRequest = lib.mkOption { 30 type = types.bool; 31 default = false; 32 description = '' 33 Recent versions of glibc will issue both ipv4 (A) and ipv6 (AAAA) 34 address queries at the same time, from the same port. Sometimes upstream 35 routers will systemically drop the ipv4 queries. The symptom of this problem is 36 that 'getent hosts example.com' only returns ipv6 (or perhaps only ipv4) addresses. The 37 workaround for this is to specify the option 'single-request' in 38 /etc/resolv.conf. This option enables that. 39 ''; 40 }; 41 42 networking.dnsExtensionMechanism = lib.mkOption { 43 type = types.bool; 44 default = false; 45 description = '' 46 Enable the <code>edns0</code> option in <filename>resolv.conf</filename>. With 47 that option set, <code>glibc</code> supports use of the extension mechanisms for 48 DNS (EDNS) specified in RFC 2671. The most popular user of that feature is DNSSEC, 49 which does not work without it. 50 ''; 51 }; 52 53 networking.extraResolvconfConf = lib.mkOption { 54 type = types.lines; 55 default = ""; 56 example = "libc=NO"; 57 description = '' 58 Extra configuration to append to <filename>resolvconf.conf</filename>. 59 ''; 60 }; 61 62 63 networking.proxy = { 64 65 default = lib.mkOption { 66 type = types.nullOr types.str; 67 default = null; 68 description = '' 69 This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy. 70 ''; 71 example = "http://127.0.0.1:3128"; 72 }; 73 74 httpProxy = lib.mkOption { 75 type = types.nullOr types.str; 76 default = cfg.proxy.default; 77 description = '' 78 This option specifies the http_proxy environment variable. 79 ''; 80 example = "http://127.0.0.1:3128"; 81 }; 82 83 httpsProxy = lib.mkOption { 84 type = types.nullOr types.str; 85 default = cfg.proxy.default; 86 description = '' 87 This option specifies the https_proxy environment variable. 88 ''; 89 example = "http://127.0.0.1:3128"; 90 }; 91 92 ftpProxy = lib.mkOption { 93 type = types.nullOr types.str; 94 default = cfg.proxy.default; 95 description = '' 96 This option specifies the ftp_proxy environment variable. 97 ''; 98 example = "http://127.0.0.1:3128"; 99 }; 100 101 rsyncProxy = lib.mkOption { 102 type = types.nullOr types.str; 103 default = cfg.proxy.default; 104 description = '' 105 This option specifies the rsync_proxy environment variable. 106 ''; 107 example = "http://127.0.0.1:3128"; 108 }; 109 110 allProxy = lib.mkOption { 111 type = types.nullOr types.str; 112 default = cfg.proxy.default; 113 description = '' 114 This option specifies the all_proxy environment variable. 115 ''; 116 example = "http://127.0.0.1:3128"; 117 }; 118 119 noProxy = lib.mkOption { 120 type = types.nullOr types.str; 121 default = null; 122 description = '' 123 This option specifies the no_proxy environment variable. 124 If a default proxy is used and noProxy is null, 125 then noProxy will be set to 127.0.0.1,localhost. 126 ''; 127 example = "127.0.0.1,localhost,.localdomain"; 128 }; 129 130 envVars = lib.mkOption { 131 type = types.attrs; 132 internal = true; 133 default = {}; 134 description = '' 135 Environment variables used for the network proxy. 136 ''; 137 }; 138 }; 139 }; 140 141 config = { 142 143 environment.etc = 144 { # /etc/services: TCP/UDP port assignments. 145 "services".source = pkgs.iana_etc + "/etc/services"; 146 147 # /etc/protocols: IP protocol numbers. 148 "protocols".source = pkgs.iana_etc + "/etc/protocols"; 149 150 # /etc/rpc: RPC program numbers. 151 "rpc".source = pkgs.glibc + "/etc/rpc"; 152 153 # /etc/hosts: Hostname-to-IP mappings. 154 "hosts".text = 155 '' 156 127.0.0.1 localhost 157 ${optionalString cfg.enableIPv6 '' 158 ::1 localhost 159 ''} 160 ${cfg.extraHosts} 161 ''; 162 163 # /etc/resolvconf.conf: Configuration for openresolv. 164 "resolvconf.conf".text = 165 '' 166 # This is the default, but we must set it here to prevent 167 # a collision with an apparently unrelated environment 168 # variable with the same name exported by dhcpcd. 169 interface_order='lo lo[0-9]*' 170 '' + optionalString config.services.nscd.enable '' 171 # Invalidate the nscd cache whenever resolv.conf is 172 # regenerated. 173 libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service 2> /dev/null' 174 '' + optionalString cfg.dnsSingleRequest '' 175 # only send one DNS request at a time 176 resolv_conf_options+=' single-request' 177 '' + optionalString cfg.dnsExtensionMechanism '' 178 # enable extension mechanisms for DNS 179 resolv_conf_options+=' edns0' 180 '' + optionalString hasLocalResolver '' 181 # This hosts runs a full-blown DNS resolver. 182 name_servers='127.0.0.1' 183 '' + optionalString dnsmasqResolve '' 184 dnsmasq_conf=/etc/dnsmasq-conf.conf 185 dnsmasq_resolv=/etc/dnsmasq-resolv.conf 186 '' + cfg.extraResolvconfConf + '' 187 ''; 188 189 } // (optionalAttrs config.services.resolved.enable ( 190 if dnsmasqResolve then { 191 "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf"; 192 } else { 193 "resolv.conf".source = "/run/systemd/resolve/resolv.conf"; 194 } 195 )); 196 197 networking.proxy.envVars = 198 optionalAttrs (cfg.proxy.default != null) { 199 # other options already fallback to proxy.default 200 no_proxy = "127.0.0.1,localhost"; 201 } // optionalAttrs (cfg.proxy.httpProxy != null) { 202 http_proxy = cfg.proxy.httpProxy; 203 } // optionalAttrs (cfg.proxy.httpsProxy != null) { 204 https_proxy = cfg.proxy.httpsProxy; 205 } // optionalAttrs (cfg.proxy.rsyncProxy != null) { 206 rsync_proxy = cfg.proxy.rsyncProxy; 207 } // optionalAttrs (cfg.proxy.ftpProxy != null) { 208 ftp_proxy = cfg.proxy.ftpProxy; 209 } // optionalAttrs (cfg.proxy.allProxy != null) { 210 all_proxy = cfg.proxy.allProxy; 211 } // optionalAttrs (cfg.proxy.noProxy != null) { 212 no_proxy = cfg.proxy.noProxy; 213 }; 214 215 # Install the proxy environment variables 216 environment.sessionVariables = cfg.proxy.envVars; 217 218 # The ‘ip-up’ target is started when we have IP connectivity. So 219 # services that depend on IP connectivity (like ntpd) should be 220 # pulled in by this target. 221 systemd.targets.ip-up.description = "Services Requiring IP Connectivity"; 222 223 # This is needed when /etc/resolv.conf is being overriden by networkd 224 # and other configurations. If the file is destroyed by an environment 225 # activation then it must be rebuilt so that applications which interface 226 # with /etc/resolv.conf directly don't break. 227 system.activationScripts.resolvconf = stringAfter [ "etc" "tmpfs" "var" ] 228 '' 229 # Systemd resolved controls its own resolv.conf 230 rm -f /run/resolvconf/interfaces/systemd 231 ${optionalString config.services.resolved.enable '' 232 rm -rf /run/resolvconf/interfaces 233 mkdir -p /run/resolvconf/interfaces 234 ln -s /run/systemd/resolve/resolv.conf /run/resolvconf/interfaces/systemd 235 ''} 236 237 # Make sure resolv.conf is up to date if not managed by systemd 238 ${optionalString (!config.services.resolved.enable) '' 239 ${pkgs.openresolv}/bin/resolvconf -u 240 ''} 241 ''; 242 243 }; 244 245 }