New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/iwd: add networks
and interfaces
option
#75800
Conversation
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review-may-2019/3032/99 |
8dc95de
to
287febb
Compare
As discussed with @fpletz, we should ensure that |
description = '' | ||
List of interfaces to use. | ||
''; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the interfaces change be done separately?
It's not needed for the network changes at all AFAICT so it's easily separated.
The reason is iwd and interface handling, especially naming, might need some careful work.
- Interface strings: interaction and reliance on use of
usePredictableInterfaceNames
- Implications re:iwd's
UseDefaultInterface
(and the shipped.link
file). - (Is there some existing interface abstraction we should be tying to?)
- The service, I think?, if used with particular interfaces maybe should:
wants
,requires
sys-subsystem-net-devices-${ifacename-escaped-for-systemd}
(not sure) - iwd's help doesn't tell you, but my reading of the code in
src/manager.c
suggests the interface list is comma-separated not space-separated, FWIW
All said, what's the use for specifying interfaces explicitly anyway? Just curious :).
And the rest is exciting and I think close to merge-ready, hence the suggestion for splitting off the interface-related bits.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All said, what's the use for specifying interfaces explicitly anyway? Just curious :).
It might be possible that I'm missing something, but iwd constantly tried to use wlan0 by default which doesn't even exist on my system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dtzWill any updates here?
else "string which must have at least ${toString min} and at most ${toString max} chars."; | ||
inherit (types.str) merge; | ||
check = x: isString x && stringLength x >= min && stringLength x <= max; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wishlist: some sort of test to ensure this all works as expected--at least to catch complete breakage. Are these details re:knownnetworks population something likely to stay the same? I suspect so, but interested if anyone has better information on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a good suggestion how to test wireless stuff in a VM test? Otherwise I'm currently not sure how to implement this :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dtzWill do you have an idea how to integration-test wifi connectivity? Or would it be sufficient from your PoV to check if the known-networks
cmd detects the declaratively specified networks?
(the full integration-test may be helpful to test my additional patch btw since this testing it against new iwd
versions always takes some time).
pkgs/os-specific/linux/iwd/0001-agent-network_connect_psk-check-if-the-config-file-f.patch
Outdated
Show resolved
Hide resolved
287febb
to
b3db8d6
Compare
networks
and interfaces
optionnetworks
and interfaces
option
As I didn't find a way to mark an already reviewed PR back as draft, I added a |
b3db8d6
to
e5196a5
Compare
Seems to be fine again with iwd 1.6 :) |
networks
and interfaces
optionnetworks
and interfaces
option
I've also been using this as my daily, for what it's worth. It works well and good :) |
Good to know. I'm using that as well, however I occasionally have some weird config issues I need to debug before considering this mergable. |
e5196a5
to
90544ba
Compare
pkgs/os-specific/linux/iwd/0001-agent-network_connect_psk-check-if-the-config-file-f.patch
Show resolved
Hide resolved
Hey, what is the best way to test this PR in a running NixOS installation on Linux? |
It's unfortunately quite hacky: {
disabledModules = [ "services/networking/iwd.nix" ];
imports = [ /path/to/git/checkout/of/this/branch/nixos/modules/services/networking/iwd.nix ];
} |
Checkout the repo. Install hub. Than do:
You can also cherry pick it to master or a release branch (not sure if it applies cleanly though)
To install it:
|
This does not apply |
Didn't test it, but why actually? |
@Mic92: Thank you this worked for me! I tried configuring it like this:
Which results in different files and it doesn't seem iwd is still able to autoconnect:
The format inside the both profiles looks right but the essid name above looks strange. Unfortunately autoconnect does not work out of the box. I have to manually connect to the network again :( Further I really would love to see 802.1x support, otherwise some networks would be missing in my configuration. In terms of security, I usually store sensitive variables, like passphrases or private keys encrypted in a seperate .nix-file. |
As described in the PR, big 👎. I consider 802.1x credentials to be extremely sensitive so they must not be in a world-readable store.
Good catch! Spaces are indeed alloewd in the filenames. Will fix this. |
90544ba
to
878847c
Compare
@onny fixed the issue for you. Also modified the |
878847c
to
109af77
Compare
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
cc @infinisil as you are fairly experienced with our module-system, would you mind taking a look at this in case you have time to? :) |
allowedChars = stringToCharacters "01234556789abcdefghijklmnopqrstuvwxyz-_ "; | ||
skipEncoding = all (char: elem (toLower char) allowedChars) (stringToCharacters file); | ||
in | ||
"/var/lib/iwd/${if skipEncoding then file else "$(${encodeFileName} \"${file}\")"}.${ext}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since nothing actually needs these values at eval time, you can instead do this check during runtime in preStart
directly.
# Cannot use the SSID here: the hex-encode is done at build-time, not eval time | ||
# and several special chars in a file name would break `writeText`. | ||
file = pkgs.writeText "ssid" (generators.toINI {} ({ | ||
Settings.AutoConnect = cfg.autoConnect; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also do this at runtime by dropping the use of generators.toINI
and manually constructing the INI file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I'm not sure whether we should do this: I check if a file in /var/lib/iwd
is a store-path and if that's the case, IWD now refuses to modify/remove/whatever this network configuration. This wouldn't be possible anymore with runtime-construction and thus leading to eventual consistency as iwd
can simply modify the network's configuration and therefore breaking the immutability-goal of NixOS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still possible to do this, which imo is even nicer since it doesn't rely on checking for Nix store symlinks: Write the list of files that were deployed declaratively to /var/lib/iwd/.declarative-nixos-networks
after linking them. Then in the next preStart
, remove all the files given in that list first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea and will give it a try soon :)
''; | ||
}; | ||
|
||
passphrase = mkOption { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And manually constructing the INI file during runtime has the benefit that you can convert the psk
and passphrase
options to pskFile
and passphraseFile
respectively, which then won't force the user into putting their password in the Nix store. When constructing the INI file in preStart
you can read these file paths to get the secret values.
Note that if people don't care about this, they can still do psk = pkgs.writeFile "foo-psk" "the-psk"
, which still puts the secret in the store.
Furthermore, 802.1x support can be added similarly, as requested by @onny.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relevant issue: #24288
This change adds support for declarative networks with `iwd(8)`, similar to `networking.wireless.networks` and an `interfaces` option which tells the service which to use (by default, the interfaces will be found automatically). In contrast to the `wpa_supplicant` module it's still possible to add additional networks imperatively using `iwctl(1)` since all networks are stored as separated files in `/var/lib/iwd`. Please note that this change doesn't add support for 802.1x networks[1] as this would currently mean that we'd have to store sensitive secrets for those networks world-readably in the Nix-store. It's recommended to add those networks imperatively. This module supports open networks and networks with a WPA PSK or a raw passphrase. If a SSID doesn't contain alphanumeric chars and `-_` only, the network-configuration will be stored as `=<hex-encoded-version>.<ext>` in `/var/lib/iwd`. [1] https://iwd.wiki.kernel.org/networkconfigurationsettings#x_wpawpa2_enterprise_settings
109af77
to
861bc57
Compare
New type which can be used to define an option that expects a `str` with a declarable length. This originates from the `iwd`-module where this was used to validate the length of a wireless network's PSK. It can be used like this: # Option expecting a string that must have at least 5 chars and # at most 10 chars. mkOption { /* ... */ type = types.lengthCheckedString 5 10; } If a string can only have a single specified length, it can be declared like this: # Option expecting a string that must have exactly 23 chars. mkOption { /* ... */ type = types.fixedLengthString 23; }
861bc57
to
517b290
Compare
@infinisil thanks a lot for the detailedreview. I fixed most of your notes and left a comment re |
After giving this a lot of thought, I decided to close this now. In fact, I started an attempt to implement the new suggestions this week and spent a lot of time & energy with my colleague @lheckemann last night to patch the C code of First of all, let me explain why I'm stopping this effort now: unfortunately Apart from that I'm losing the interest in this change as I'm currently re-evaluating However, if someone wants to continue working on this, that's perfectly fine. The current diff on my Last but not least, @infinisil & @bqv thanks for the review. I'll check if your ideas are somehow applicable for |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/iwd-declarative-wifi-configs-networks-credentials/11267/2 |
Motivation for this change
This change adds support for declarative networks with
iwd(8)
, similarto
networking.wireless.networks
and aninterfaces
option which tellsthe service which to use (by default, the interfaces will be found
automatically).
In contrast to the
wpa_supplicant
module it's still possible toadd additional networks imperatively using
iwctl(1)
since all networksare stored as separated files in
/var/lib/iwd
.Please note that this change doesn't add support for 802.1x networks[1]
as this would currently mean that we'd have to store sensitive secrets
for those networks world-readably in the Nix-store. It's recommended to
add those networks imperatively.
This module supports open networks and networks with a WPA PSK or a raw
passphrase. If a SSID doesn't contain alphanumeric chars and
-_
only,the network-configuration will be stored as
=<hex-encoded-version>.<ext>
in
/var/lib/iwd
.[1] https://iwd.wiki.kernel.org/networkconfigurationsettings#x_wpawpa2_enterprise_settings
Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nix-review --run "nix-review wip"
./result/bin/
)nix path-info -S
before and after)Notify maintainers
cc @