runfalk / synology-wireguard

WireGuard support for some Synology NAS drives
MIT License
953 stars 134 forks source link

DSM 7 support? #66

Open Kopernikus1979 opened 3 years ago

Kopernikus1979 commented 3 years ago

Hi,

Did anyone tried to compile the spk for DSM7 ?

https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/7.0/enu/DSM_Developer_Guide_7_0_Beta.pdf

runfalk commented 3 years ago

I just tested it and it doesn't seem to work yet with the official repository. There is no official support for the new version: https://github.com/SynologyOpenSource/pkgscripts-ng/blob/master/include/toolkit.config.

It does build if I manually modify toolkit.config and add the line:

AvailablePlatform_7_0="6281 alpine alpine4k apollolake armada370 armada375 armada37xx armada38x armadaxp avoton braswell broadwell broadwellnk bromolow cedarview comcerto2k denverton dockerx64 evansport geminilake grantley hi3535 kvmx64 monaco purley qoriq rtd1296 v1000 x64"

Since DSM 7 is still preview I haven't tried the package myself. I added a workaround to build.sh to add that line if it doesn't exist. I can however not vouch for whether it works or not. There may be more changes required.

Kopernikus1979 commented 3 years ago

Can you build a geminilake version for me so I can do some testing?

runfalk commented 3 years ago

I have compiled an SPK for you. The usual caveats apply:

You use everything here at your own risk. I am not responsible if this breaks your NAS. Realistically it should not result in data loss, but it could render your NAS inaccessible if something goes wrong.

If you are not comfortable with removing your drives from the NAS and manually recover the data, this might not be for you.

You need to unzip it first (since GitHub doesn't accept SPKs in issues).

WireGuard-geminilake-1.0.20201221.zip

matige commented 3 years ago

I'm not sure if the package built this way will work on DSM 7.0. pkgscripts-ng has a separate branch for DSM 7.0 with a message: "This toolkit is only for DSM7.0. If you need toolkit before 7.0, please checkout to other branches." In "Release for DSM7.0" commit you can see that a large part of the code has been changed. In the "Breaking Changes in 7.0" section of the Developer Guide we see information about the downgrading of the package's privilage. Each packages should provide conf/privilege with package in run-as explicitly (as in this example). We must first check how these and other changes affect the correct functioning of the synology-wireguard package. I think the best place to test is a virtual machine with DSM 7.0 running on Synology NAS (Virtual DSM).

runfalk commented 3 years ago

Thanks for joining in @Matige.

Yeah, this is basically a hack (though it definitely builds using the new SDK). Like you say the privilege change may be the biggest problem.

We likely need to add a conf/privilege file with:

{
    "defaults": { "run-as": "root" }
}

Since we need to run insmod and set iptables rules.

It also seems like there are a few other interesting things like the "/usr/local linker worker" and "Systemd User Unit worker".

For now, this is where my efforts stop. I plan to eventually make it work on DSM 7, but that'll have to wait until DSM 7 and its SDK is officially released. I don't personally own a Synology NAS, I'm simply using the one at my parents' place for backups. So whenever I need to test something new like this it's a bit of a project. I'm happy to take PRs though if anyone wants to have a go.

matige commented 3 years ago

It seems to me that the run-as root method will not work. At synology.com we can read (source):

Synology has added a strict requirement on DSM 7.0 to prevent packages not signed by Synology from running with root privileges. This is because packages with root privileges can execute commands as root users and compromise system security.

More information can be found here.

Kopernikus1979 commented 3 years ago

Tried it and indeed it doesn't work, but thx anyway for the efforts. I'll keep on using my Virtual machine for now and improving my Linux skills as a bonus

runfalk commented 3 years ago

I've sent an inquiry to Synology to see if they can make an exception or if they are interested in bundling the kernel module with DSM itself. Fingers crossed that they are helpful.

runfalk commented 3 years ago

@Kopernikus1979 it might be possible for you to extract the file in the spk and copy them by hand. You should probably be able to run insmod on the kernel module as root (if you can get a root shell in DSM 7?) and then check if it works by using the wg command.

matige commented 3 years ago

Today I made an attempt to run WireGuard on DSM 7.0 (Virtual DSM). For compilation I used pkgscripts-ng from the DSM7.0 branch. I made some changes in the code (e.g. PkgCreate.py no longer has the -S argument), I added privilege and used /usr/local linker. I managed to bypass the limitation of running an unauthorized package as root in a fairly simple way. Unfortunately, at this point, problems started to appear.

It looks like the new kernel was compiled without CONFIG_UNINLINE_SPIN_UNLOCK. When trying to load the wireguars.ko module, an error is returned:

insmod: ERROR: could not insert module target/wireguard/wireguard.ko: Unknown symbol in module

dmesg return:

wireguard: Unknown symbol _raw_spin_unlock (err 0)

For DSM 6.2:

$ cat /proc/kallsyms | grep "_raw_spin_unlock"
ffffffff81567a70 T _raw_spin_unlock
ffffffff81567a90 T _raw_spin_unlock_irqrestore
ffffffff81567ab0 T _raw_spin_unlock_irq
ffffffff81567b50 T _raw_spin_unlock_bh

For DSM 7.0:

$ cat /proc/kallsyms | grep "_raw_spin_unlock"
ffffffff8105be20 t __raw_spin_unlock_irq
ffffffff813d5a10 t __raw_spin_unlock_irq
ffffffff81530770 T _raw_spin_unlock_irqrestore
ffffffff81530860 T _raw_spin_unlock_bh

So I wrote a simple module that exports symbol _raw_spin_unlock from linux/spinlock.h and managed to load the wireguard.ko module correctly. Unfortunately, when you run the wg-quick up wg0, you lose connection to the server. I have looked into this problem and the loss of connection occurs when the interface is created: ip link add wg0 type wireguard. At the moment I have not managed to run WireGuard on DSM 7.0.

runfalk commented 3 years ago

@Matige It doesn't work because the actual spin unlock implementation is required I assume? We could probably vendor that implementation if necessary. (https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/include/linux/spinlock_api_smp.h#L148) I think this may be it. It's a bit hacky but at least the kernel version doesn't seem to change a lot.

I also have a reply from Synology regarding the possibility of kernel modules in DSM 7:

Thanks for contacting Synology.

I'm sorry to inform you that due to internal policy, we're not allowed to disclose the kernel module for DSM for 3rd-party packages.

If you have any suggestions, feel free to contact us at any time.

Sincerely,

Synology Inquiry Team

Which basically means that I can no longer distribute an SPK. If they haven't completely locked down the OS I guess we can distribute a script that installs it manually instead (as long as you can get a root shell).

matige commented 3 years ago

After a few hours of trying I managed to solve the problem of DSM suspension. After exporting _raw_spin_unlock, the declaration was still incorrect. This resulted in blocking the VM while the module was loading. After defining the macro for the spin_unlock function in ratelimiter.c I managed to get a working wireguard.ko module. This way I managed to run WireGuard on DSM 7.0 in a virtual machine (Virtual DSM). Connection to the network using wg-quick is done without any problems.

After this success I decided to update the DSM on my DS220+ from 6.2 to 7.0. I discovered that on my platform spin_unlock fix is not required and the module loads without error. It seemed that everything was already working properly, but during the configuration of the interface there is an error:

$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
Unable to modify interface: Operation not supported
Unable to access interface: Operation not supported
[#] ip link delete dev wg0

At this point, I was able to determine that the error occurs in the kernel_set_device function in the ipc-linux.h file from wireguard-tools. However, I am neither fluent in C nor programming for linux, so I don't know if I can solve this problem. Maybe someone with more experience will have to deal with it.

@runfalk I understand Synology's answer is that due to internal policy they cannot include the WireGuard module in the DSM kernel. There is nothing to prevent you from continuing to distribute the WireGuard package with the module. DSM 7.0 is currently in beta version, so you should not expect many changes in its functioning. Access to the shell is still available, as is the ability to install external packages and load kernel modules. At this point, after installing a package built for DSM 7.0 (I will create a pull request after solving the problem described above) only one additional step should be taken to make the package work with higher privileges and load the module correctly.

runfalk commented 3 years ago

That problem looks odd, I wonder what could have failed there. It's probably something to ask about on IRC (#wireguard@freenode.net).

Thank you for investigating this! Maybe I've misundertood what the root privilege actually means for this package? I understand that the SPK can provide the files but can it run insmod to load the kernel module or will the user have to manually set that up using a terminal?

Regarding Synology's reply. I didn't give the full conversation (and my understanding is that they will not allow run as root at all). Full conversation with greetings stripped out:

I'm the author of Synology-WireGuard (https://github.com/runfalk/synology-wireguard/). The package is reasonably popular (300 stars) and it has come to my attention that running packages as root will no longer be supported as of DSM 7. My package relies on a kernel module (running insmod and changing iptables rules).

It would be a shame if I could no longer distribute this to other users. Would it be possible to make an exception for my package? Alternatively if you could consider bundling the Wireguard kernel module as part of DSM? -- Me

Please lower your package permission from root to package user. Most of our major packages has made the changes to be compatible with DSM7, and for now, we don't allow exceptions to assure the stablity and security of DSM7.

If you would like to discuss about the capabilities that run as root, which is used by WireGuard, please contact us, and we can disucss how to do so. -- Synology

The reason I'm contacting you exactly is because WireGuard requires a kernel module. That kernel module must be loaded using the insmod command, which requires root permissions.

Is there a way forward here? -- Me

I'm sorry to inform you that due to internal policy, we're not allowed to disclose the kernel module for DSM for 3rd-party packages.

If you have any suggestions, feel free to contact us at any time. -- Synology

As I understand it they are neither interested in adding the kernel module nor in making an exception for this package. I'm happy if someone can make a more hopeful interpretation though.

Kopernikus1979 commented 3 years ago

I already asked them many times to update the Linux kernel wich integrates Wireguard and also updating Docker wich is awfully outdated (as a result many new containers can't run anymore), their are even threads on the official forum on this, but they never answer or if they answer it's always something as we have send the suggestion to our developers. For the moment I have Debian running in a VM on the NAS who suits my needs but ofcourse I can't expect much performance, I'm even considering building my own server and migrate to Unraid or Debian/Ubuntu server.

matige commented 3 years ago

Only yesterday I discovered Synogear - Synology Diagnosis Tool. Diagnosing the problem has become a bit easier. strace showed that the error is returned in the netlink response. In this case the bug appears somewhere in the kernel module. I have now come to the conclusion that after creating a new wireguard device it does not retain the rtnl_link_ops properties. For this reason, an error is returned in the kernel module. On Virtual DSM rtnl_link_ops contains the correct structure for this device. I must admit that during these few hours of debugging I learned a little about the linux - functioning of the user space and the kernel, so this is not time wasted.

@runfalk To install a package on DSM 7.0 the run-as value in the conf/privilege file must be set to the package. This causes the scripts to run with user privileges. Running the package will fail because the user has no permission to load kernel modules. I found a simple workaround to this problem. During package installation you should uncheck the option to run after installation. Then just change the value in the conf/privilege file to root from the terminal (root privileges are required for this) and the package can already be started normally from the DSM and will start automatically with the system start.

sudo sed -i 's/package/root/g' /var/packages/WireGuard/conf/privilege

@Kopernikus1979 I see that your device is DS920+. It is the same platform as my DS220+. Maybe you would like to try my WireGuard compilation for DSM 7.0? I am trying to solve the problem described above, but maybe on your device WireGuard will work properly.

matige commented 3 years ago

I was able to develop a fully working version of the WireGuard package for DSM 7.0. It has been running on my DS220+ for over 2 weeks with no problems, so I created a pull request #71.

Pasternak8 commented 3 years ago

Hi Matige, Runfulk,, I worked well with the DSM6 .2and a 220+ Station. Now I updated to DSM7.0 and must see, that the old wireguard package is working no more. But I found this thread! Thanks at first.

But I'm not able to build the package in a short time. If I had to do it myself, I would need a step-by-step instructions on how to do it. Do this exist?

Of course, it would be much nicer if one of you could publish the compiled geminilake package for the DS220+ with DSM7 here ....

Would that be possible? Thanks in advance!!!

Pasternak8 commented 3 years ago

Ok - I got it at a nother issues (https://github.com/runfalk/synology-wireguard/issues/88) and it works fine. Good work. Thanks to all!

MartinPaulEve commented 3 years ago

Just to confirm that I got this to work on a DS1819+ on DSM 7 using the DSM7 branch. Here's my Denverton build.

I had to install and load the service via the command line:

sudo synopkg install WireGuard-denverton-1.0.20210606.spk sudo /var/packages/WireGuard/scripts/start

denverton.zip

landcraft commented 3 years ago

Just to confirm that I got this to work on a DS1819+ on DSM 7 using the DSM7 branch. Here's my Denverton build.

I had to install and load the service via the command line:

sudo synopkg install WireGuard-denverton-1.0.20210606.spk sudo /var/packages/WireGuard/scripts/start

denverton.zip

Thanks a million — your CLI commands got me over the line! 🙇🏾‍♂️

wimg commented 3 years ago

Any ideas why it won't create the artifacts ?

~/synology-wireguard# sudo docker run --rm --privileged --env PACKAGE_ARCH=denverton --env DSM_VER=7.0 -v $(pwd)/artifacts:/result_spk synobuild docker: Error response from daemon: Bind mount failed: '/root/synology-wireguard/artifacts' does not exists.

MartinPaulEve commented 3 years ago

What's your docker version?

I was using Docker version 20.10.8, build 3967b7d.

wimg commented 3 years ago

docker -v shows : Docker version 20.10.3, build b455053 Not a huge difference. I can try to update it of course.

ben-ba commented 3 years ago

@wimg: create the dir manually; mkdir /root/synology-wireguard/artifacts

If you only search a working DSM 7.0 package, see here; https://github.com/runfalk/synology-wireguard/issues/93#issuecomment-922057387

morvy commented 3 years ago

not sure what the problem is here, but I get this error:

/bin/sh: 1: exec: /source/WireGuard/build.sh: not found

Dockerfile contains COPY which should include build.sh as it's not excluded in .dockerignore but still it can't find the build script

runfalk commented 2 years ago

Closing this since DSM 7.0 support is merged