Skip to content
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

innernet-server deb should depend on and modprobe wireguard #5

Closed
mrdomino opened this issue Mar 30, 2021 · 11 comments
Closed

innernet-server deb should depend on and modprobe wireguard #5

mrdomino opened this issue Mar 30, 2021 · 11 comments

Comments

@mrdomino
Copy link

I needed to modprobe wireguard (and apt install wireguard) in order for innernet-server serve to work.

Not sure what the most morally correct way is to do this persistently. I wound up doing echo wireguard > /etc/modules-load.d/wireguard.conf.

@mcginty
Copy link
Collaborator

mcginty commented Mar 30, 2021

Ah right - this is an issue for anyone with Linux kernels < 5.6.

I'm also not sure of the canonical way packages solve this - I'll have to look for other examples out there. If other packages just add a file /etc/modules-load.d/ I'm more than happy to do that too.

@mrdomino
Copy link
Author

Sounds reasonable. Congrats on the launch, btw.

@mcginty
Copy link
Collaborator

mcginty commented Mar 30, 2021

Thanks, and thanks so much for trying it out and testing it! I appreciate you opening the issue.

@Nemo157
Copy link

Nemo157 commented Mar 30, 2021

Appears to be an issue on 5.11 too, /sys/module/wireguard didn't exist until I did modprobe wireguard to load it

Linux 5.11.10-arch1-1 #1 SMP PREEMPT Fri, 26 Mar 2021 00:11:29 +0000 x86_64 GNU/Linux

@Nemo157
Copy link

Nemo157 commented Mar 30, 2021

Dropping in a modules-load.d seems to be done by at least a couple of packages on arch:

> pacman -Fx '^etc/modules-load\.d/.+'
etc/modules-load.d/i2c_dev.conf is owned by community/deepin-daemon 5.12.52-1
etc/modules-load.d/deepin-screen-recorder.conf is owned by community/deepin-screen-recorder 5.8.1-1
etc/modules-load.d/zfs.conf is owned by archzfs/zfs-utils 2.0.4-1
etc/modules-load.d/zfs.conf is owned by archzfs/zfs-utils-git 2021.03.26.r6649.g38280c352-1
etc/modules-load.d/zfs.conf is owned by archzfs/zfs-utils-rc 2.0.0_rc7-1

@mcginty
Copy link
Collaborator

mcginty commented Apr 8, 2021

I've opted for calling /sbin/modprobe wireguard in wgctrl-rs for now to divorce us from needing package managers to make the kernel module load properly.

I'm going to re-open this though since I'd like for innernet to be able to run without root and just use CAP_NET_ADMIN, at which point loading modules from the binary wouldn't work (and rightly so 🙂).

If the current solution is problematic in some other way I'm unaware of, please let me know.

@mcginty mcginty reopened this Apr 8, 2021
@mcginty mcginty removed this from the 1.1 milestone Apr 9, 2021
@mk-fg
Copy link

mk-fg commented May 10, 2021

I'm going to re-open this though since I'd like for innernet to be able to run without root and just use CAP_NET_ADMIN, at which point loading modules from the binary wouldn't work (and rightly so slightly_smiling_face).
If the current solution is problematic in some other way I'm unaware of, please let me know.

It doesn't work in containers with kernel wg implementation.
WireGuard can be used in these just fine, but there's no kernel or its modules there, and at least with systemd-nspawn, there's no /sys/module/wireguard path either.

This makes it impossible to start innernet in containers with kernel wireguard implementation because of this exists() check, as both operations it does are guaranteed to fail there, even though e.g. ip link add wg type wireguard will work without issues and kernel module is perfectly usable - just a problem with this check.

Bypassing it completely with something like:

pub fn exists() -> bool {
    return true;

...allows both server and client to work without issues.

I'd suggest adding e.g --backend=kernel option which would allow to bypass modprobe and auto-detection checks, to avoid falling back to userspace implementation (and getting additional confusing errors from there), or potentially the opposite - ignore kernel implementation and the need for uid=root and go straight for wireguard-go.

@mcginty
Copy link
Collaborator

mcginty commented May 11, 2021

Thanks @mk-fg, that modprobe is very much duct tape that needs to be peeled off - I had also planned on removing it as part of the rootless change work 🙂.

I like the idea of forcing a backend via a CLI flag. Is there any reliable way within containers to detect the existence of a kernel module in the host?

@mk-fg
Copy link

mk-fg commented May 11, 2021

Is there any reliable way within containers to detect the existence of a kernel module in the host?

Aside from the obvious "try creating wg interface", I'm afraid I don't know - /sys/modules would be the way, but it's not there, and while /proc/modules is present, it's definitely not reliable, as built-in modules won't show up there.

I think such details might not be exposed by design though, as pretty much main purpose of containers is reproducible setup, and if you auto-flip various behaviors depending on what system container runs on top of, then you negate that completely - container will run in one mode on one system, and will work differently with diff quirks, bugs and whatever behavior on another.
Hence the switch suggestion - with it specified (possibly by container user, but deliberately either way), if kernel module is not loaded, container will fail, and that's how it's supposed to work if something in the environment is missing for it to run, I believe.

@mcginty
Copy link
Collaborator

mcginty commented May 17, 2021

I'm going to implement this option, I like the idea of having a --backend flag.

Will also look into what the iproute2 tool is doing in the background when adding a WireGuard interface.a

mcginty pushed a commit that referenced this issue May 19, 2021
…#85)

Based on the conversation from #5 (comment) - this changes innernet's behavior on Linux from automatically falling back to the userspace, instead requiring --backend userspace to be specified.

This should help people avoid weird situations in environments like Docker.
@mcginty
Copy link
Collaborator

mcginty commented May 19, 2021

The latest innernet neither runs modprobe internally nor does it do existence checks for the kernel module since it's too unreliable across different environments. Instead, you can manually specify --backend userspace on Linux to force the userspace backend, otherwise it assumes the kernel module exists.

This behavior feels more similar to how WireGuard itself supports the userspace implementation on Linux - it's not recommended and only advanced users should be relying on it (this applies in the context of a container, too, for example).

@mcginty mcginty closed this as completed May 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants