1# /etc files related to networking, such as /etc/services.
2{
3 config,
4 lib,
5 options,
6 pkgs,
7 ...
8}:
9let
10
11 cfg = config.networking;
12 opt = options.networking;
13
14 localhostMultiple = lib.any (lib.elem "localhost") (
15 lib.attrValues (
16 removeAttrs cfg.hosts [
17 "127.0.0.1"
18 "::1"
19 ]
20 )
21 );
22
23in
24
25{
26 imports = [
27 (lib.mkRemovedOptionModule [ "networking" "hostConf" ] "Use environment.etc.\"host.conf\" instead.")
28 ];
29
30 options = {
31
32 networking.hosts = lib.mkOption {
33 type = lib.types.attrsOf (lib.types.listOf lib.types.str);
34 example = lib.literalExpression ''
35 {
36 "127.0.0.1" = [ "foo.bar.baz" ];
37 "192.168.0.2" = [ "fileserver.local" "nameserver.local" ];
38 };
39 '';
40 description = ''
41 Locally defined maps of hostnames to IP addresses.
42 '';
43 };
44
45 networking.hostFiles = lib.mkOption {
46 type = lib.types.listOf lib.types.path;
47 defaultText = lib.literalMD "Hosts from {option}`networking.hosts` and {option}`networking.extraHosts`";
48 example = lib.literalExpression ''[ "''${pkgs.my-blocklist-package}/share/my-blocklist/hosts" ]'';
49 description = ''
50 Files that should be concatenated together to form {file}`/etc/hosts`.
51 '';
52 };
53
54 networking.extraHosts = lib.mkOption {
55 type = lib.types.lines;
56 default = "";
57 example = "192.168.0.1 lanlocalhost";
58 description = ''
59 Additional verbatim entries to be appended to {file}`/etc/hosts`.
60 For adding hosts from derivation results, use {option}`networking.hostFiles` instead.
61 '';
62 };
63
64 networking.timeServers = lib.mkOption {
65 default = [
66 "0.nixos.pool.ntp.org"
67 "1.nixos.pool.ntp.org"
68 "2.nixos.pool.ntp.org"
69 "3.nixos.pool.ntp.org"
70 ];
71 type = lib.types.listOf lib.types.str;
72 description = ''
73 The set of NTP servers from which to synchronise.
74 '';
75 };
76
77 networking.proxy = {
78
79 default = lib.mkOption {
80 type = lib.types.nullOr lib.types.str;
81 default = null;
82 description = ''
83 This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy.
84 '';
85 example = "http://127.0.0.1:3128";
86 };
87
88 httpProxy = lib.mkOption {
89 type = lib.types.nullOr lib.types.str;
90 default = cfg.proxy.default;
91 defaultText = lib.literalExpression "config.${opt.proxy.default}";
92 description = ''
93 This option specifies the http_proxy environment variable.
94 '';
95 example = "http://127.0.0.1:3128";
96 };
97
98 httpsProxy = lib.mkOption {
99 type = lib.types.nullOr lib.types.str;
100 default = cfg.proxy.default;
101 defaultText = lib.literalExpression "config.${opt.proxy.default}";
102 description = ''
103 This option specifies the https_proxy environment variable.
104 '';
105 example = "http://127.0.0.1:3128";
106 };
107
108 ftpProxy = lib.mkOption {
109 type = lib.types.nullOr lib.types.str;
110 default = cfg.proxy.default;
111 defaultText = lib.literalExpression "config.${opt.proxy.default}";
112 description = ''
113 This option specifies the ftp_proxy environment variable.
114 '';
115 example = "http://127.0.0.1:3128";
116 };
117
118 rsyncProxy = lib.mkOption {
119 type = lib.types.nullOr lib.types.str;
120 default = cfg.proxy.default;
121 defaultText = lib.literalExpression "config.${opt.proxy.default}";
122 description = ''
123 This option specifies the rsync_proxy environment variable.
124 '';
125 example = "http://127.0.0.1:3128";
126 };
127
128 allProxy = lib.mkOption {
129 type = lib.types.nullOr lib.types.str;
130 default = cfg.proxy.default;
131 defaultText = lib.literalExpression "config.${opt.proxy.default}";
132 description = ''
133 This option specifies the all_proxy environment variable.
134 '';
135 example = "http://127.0.0.1:3128";
136 };
137
138 noProxy = lib.mkOption {
139 type = lib.types.nullOr lib.types.str;
140 default = null;
141 description = ''
142 This option specifies the no_proxy environment variable.
143 If a default proxy is used and noProxy is null,
144 then noProxy will be set to 127.0.0.1,localhost.
145 '';
146 example = "127.0.0.1,localhost,.localdomain";
147 };
148
149 envVars = lib.mkOption {
150 type = lib.types.attrs;
151 internal = true;
152 default = { };
153 description = ''
154 Environment variables used for the network proxy.
155 '';
156 };
157 };
158 };
159
160 config = {
161
162 assertions = [
163 {
164 assertion = !localhostMultiple;
165 message = ''
166 `networking.hosts` maps "localhost" to something other than "127.0.0.1"
167 or "::1". This will break some applications. Please use
168 `networking.extraHosts` if you really want to add such a mapping.
169 '';
170 }
171 ];
172
173 # These entries are required for "hostname -f" and to resolve both the
174 # hostname and FQDN correctly:
175 networking.hosts =
176 let
177 hostnames = # Note: The FQDN (canonical hostname) has to come first:
178 lib.optional (cfg.hostName != "" && cfg.domain != null) "${cfg.hostName}.${cfg.domain}"
179 ++ lib.optional (cfg.hostName != "") cfg.hostName; # Then the hostname (without the domain)
180 in
181 {
182 "127.0.0.2" = hostnames;
183 };
184
185 networking.hostFiles =
186 let
187 # Note: localhostHosts has to appear first in /etc/hosts so that 127.0.0.1
188 # resolves back to "localhost" (as some applications assume) instead of
189 # the FQDN! By default "networking.hosts" also contains entries for the
190 # FQDN so that e.g. "hostname -f" works correctly.
191 localhostHosts = pkgs.writeText "localhost-hosts" ''
192 127.0.0.1 localhost
193 ${lib.optionalString cfg.enableIPv6 "::1 localhost"}
194 '';
195 stringHosts =
196 let
197 oneToString = set: ip: ip + " " + lib.concatStringsSep " " set.${ip} + "\n";
198 allToString = set: lib.concatMapStrings (oneToString set) (lib.attrNames set);
199 in
200 pkgs.writeText "string-hosts" (allToString (lib.filterAttrs (_: v: v != [ ]) cfg.hosts));
201 extraHosts = pkgs.writeText "extra-hosts" cfg.extraHosts;
202 in
203 lib.mkBefore [
204 localhostHosts
205 stringHosts
206 extraHosts
207 ];
208
209 environment.etc = {
210 # /etc/services: TCP/UDP port assignments.
211 services.source = pkgs.iana-etc + "/etc/services";
212
213 # /etc/protocols: IP protocol numbers.
214 protocols.source = pkgs.iana-etc + "/etc/protocols";
215
216 # /etc/hosts: Hostname-to-IP mappings.
217 hosts.source = pkgs.concatText "hosts" cfg.hostFiles;
218
219 # /etc/netgroup: Network-wide groups.
220 netgroup.text = lib.mkDefault "";
221
222 # /etc/host.conf: resolver configuration file
223 "host.conf".text = ''
224 multi on
225 '';
226
227 }
228 // lib.optionalAttrs (pkgs.stdenv.hostPlatform.libc == "glibc") {
229 # /etc/rpc: RPC program numbers.
230 rpc.source = pkgs.stdenv.cc.libc.out + "/etc/rpc";
231 };
232
233 networking.proxy.envVars =
234 lib.optionalAttrs (cfg.proxy.default != null) {
235 # other options already fallback to proxy.default
236 no_proxy = "127.0.0.1,localhost";
237 }
238 // lib.optionalAttrs (cfg.proxy.httpProxy != null) {
239 http_proxy = cfg.proxy.httpProxy;
240 }
241 // lib.optionalAttrs (cfg.proxy.httpsProxy != null) {
242 https_proxy = cfg.proxy.httpsProxy;
243 }
244 // lib.optionalAttrs (cfg.proxy.rsyncProxy != null) {
245 rsync_proxy = cfg.proxy.rsyncProxy;
246 }
247 // lib.optionalAttrs (cfg.proxy.ftpProxy != null) {
248 ftp_proxy = cfg.proxy.ftpProxy;
249 }
250 // lib.optionalAttrs (cfg.proxy.allProxy != null) {
251 all_proxy = cfg.proxy.allProxy;
252 }
253 // lib.optionalAttrs (cfg.proxy.noProxy != null) {
254 no_proxy = cfg.proxy.noProxy;
255 };
256
257 # Install the proxy environment variables
258 environment.sessionVariables = cfg.proxy.envVars;
259
260 };
261
262}