Skip to content

Commit

Permalink
modules/environment/networking: implement /etc/hosts options
Browse files Browse the repository at this point in the history
  • Loading branch information
kurnevsky committed Jul 27, 2023
1 parent 2301e01 commit 3739a44
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 6 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Alexander Sosedkin <[email protected]>
Tobias Happ <[email protected]>
Bruno Bigras <[email protected]>
Evgeny Kurnevsky <[email protected]>
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Release 23.11 (unreleased)

### New Options

* New options `networking.hosts`, `networking.hostFiles` and
`networking.extraHosts` for `/etc/hosts` configuration.

## Release 23.05

### New Options
Expand Down
80 changes: 74 additions & 6 deletions modules/environment/networking.nix
Original file line number Diff line number Diff line change
@@ -1,20 +1,91 @@
# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE.
# Copyright (c) 2019-2023, see AUTHORS. Licensed under MIT License, see LICENSE.

# Inspired by
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/config/networking.nix
# (Copyright (c) 2003-2023 Eelco Dolstra and the Nixpkgs/NixOS contributors,
# licensed under MIT License as well)

{ config, lib, pkgs, ... }:

with lib;

let
cfg = config.networking;

localhostMultiple = any (elem "localhost") (attrValues (removeAttrs cfg.hosts [ "127.0.0.1" "::1" ]));
in

{

###### interface

options = { };
options = {

networking.hosts = lib.mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
example = literalExpression ''
{
"127.0.0.1" = [ "foo.bar.baz" ];
"192.168.0.2" = [ "fileserver.local" "nameserver.local" ];
};
'';
description = lib.mdDoc ''
Locally defined maps of hostnames to IP addresses.
'';
};

networking.hostFiles = lib.mkOption {
type = types.listOf types.path;
defaultText = literalMD "Hosts from {option}`networking.hosts` and {option}`networking.extraHosts`";
example = literalExpression ''[ "''${pkgs.my-blocklist-package}/share/my-blocklist/hosts" ]'';
description = lib.mdDoc ''
Files that should be concatenated together to form {file}`/etc/hosts`.
'';
};

networking.extraHosts = lib.mkOption {
type = types.lines;
default = "";
example = "192.168.0.1 lanlocalhost";
description = lib.mdDoc ''
Additional verbatim entries to be appended to {file}`/etc/hosts`.
For adding hosts from derivation results, use {option}`networking.hostFiles` instead.
'';
};

};


###### implementation

config = {

assertions = [{
assertion = !localhostMultiple;
message = ''
`networking.hosts` maps "localhost" to something other than "127.0.0.1"
or "::1". This will break some applications. Please use
`networking.extraHosts` if you really want to add such a mapping.
'';
}];

networking.hostFiles =
let
localhostHosts = pkgs.writeText "localhost-hosts" ''
127.0.0.1 localhost
::1 localhost
'';
stringHosts =
let
oneToString = set: ip: ip + " " + concatStringsSep " " set.${ip} + "\n";
allToString = set: concatMapStrings (oneToString set) (attrNames set);
in
pkgs.writeText "string-hosts" (allToString (filterAttrs (_: v: v != [ ]) cfg.hosts));
extraHosts = pkgs.writeText "extra-hosts" cfg.extraHosts;
in
mkBefore [ localhostHosts stringHosts extraHosts ];

environment.etc = {
# /etc/services: TCP/UDP port assignments.
services.source = pkgs.iana-etc + "/etc/services";
Expand All @@ -23,10 +94,7 @@ with lib;
protocols.source = pkgs.iana-etc + "/etc/protocols";

# /etc/hosts: Hostname-to-IP mappings.
hosts.text = ''
127.0.0.1 localhost
::1 localhost
'';
hosts.source = pkgs.concatText "hosts" cfg.hostFiles;

"resolv.conf".text = ''
nameserver 1.1.1.1
Expand Down
7 changes: 7 additions & 0 deletions tests/on-device/config-flake-hosts-localhost.cfg.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{ pkgs, ... }:

{
system.stateVersion = "23.05";

networking.hosts."127.0.0.2" = [ "localhost" ];
}
37 changes: 37 additions & 0 deletions tests/on-device/config-flake-hosts.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (c) 2023, see AUTHORS. Licensed under MIT License, see LICENSE.

load lib

@test 'hosts can be configured' {
# set up / build / activate the configuration
cat "$ON_DEVICE_TESTS_DIR/config-flake-hosts.cfg.nix" \
> ~/.config/nixpkgs/nix-on-droid.nix
_sed "s|<<FLAKE_URL>>|$FLAKE_URL|g" \
"$ON_DEVICE_TESTS_DIR/config-flake.nix" \
> ~/.config/nixpkgs/flake.nix

nix-on-droid switch --flake ~/.config/nixpkgs#device

# check that /etc/hosts contains configured hosts
for entry in '::1 localhost' \
'127.0.0.1 localhost' \
'127.0.0.2 a b' \
'127.0.0.3 c' \
'127.0.0.4 d'
do
grep "$entry" /etc/hosts
done
}

@test 'hosts can not map localhost' {
# set up / build / activate the configuration
cat "$ON_DEVICE_TESTS_DIR/config-flake-hosts-localhost.cfg.nix" \
> ~/.config/nixpkgs/nix-on-droid.nix
_sed "s|<<FLAKE_URL>>|$FLAKE_URL|g" \
"$ON_DEVICE_TESTS_DIR/config-flake.nix" \
> ~/.config/nixpkgs/flake.nix

# check that networking.hosts can't map localhost
run nix-on-droid switch --flake ~/.config/nixpkgs#device
[ "$status" -eq 1 ]
}
19 changes: 19 additions & 0 deletions tests/on-device/config-flake-hosts.cfg.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{ pkgs, ... }:

{
system.stateVersion = "23.05";

networking = {
hosts."127.0.0.2" = [ "a" "b" ];

extraHosts = ''
127.0.0.3 c
'';

hostFiles = [
(pkgs.writeText "hosts" ''
127.0.0.4 d
'')
];
};
}

0 comments on commit 3739a44

Please sign in to comment.