Skip to content

Commit

Permalink
Merge pull request runfalk#71 from Matige/DSM7.0
Browse files Browse the repository at this point in the history
Add support for DSM 7.0
  • Loading branch information
runfalk authored Aug 25, 2021
2 parents 9d622de + 79699ea commit 70c2683
Show file tree
Hide file tree
Showing 20 changed files with 337 additions and 122 deletions.
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
APPLY_MEMNEQ_PATCH ?= 0
APPLY_SPINLOCK_PATCH ?= 0

LIBMNL_TAR := libmnl-$(LIBMNL_VERSION).tar.bz2
LIBMNL_DIR := libmnl-$(LIBMNL_VERSION)
Expand Down Expand Up @@ -40,12 +41,19 @@ $(WIREGUARD_TAR):
$(WIREGUARD_TOOLS_TAR):
wget https://git.zx2c4.com/wireguard-tools/snapshot/$(WIREGUARD_TOOLS_TAR)

# Unpack WireGuard source tarball and patch the compatibility layer to always
# use memneq implementation if required.
# Unpack WireGuard source tarball. Patch the wireguard interface verification
# due to the unavailability of rtnl_link_ops structure in the network device on DSM 7.0.
# If required, patch the compatibility layer to always use memneq implementation
# and patch the spinlock implementation.
$(WIREGUARD_DIR)/src/Makefile: $(WIREGUARD_TAR)
tar -xf $(WIREGUARD_TAR)
patch $(WIREGUARD_DIR)/src/netlink.c $(ROOT_DIR)/patch/netlink.patch
patch $(WIREGUARD_DIR)/src/peerlookup.c $(ROOT_DIR)/patch/peerlookup.patch
ifeq ($(APPLY_MEMNEQ_PATCH), 1)
patch $(WIREGUARD_DIR)/src/compat/Kbuild.include $(ROOT_DIR)/memneq.patch
patch $(WIREGUARD_DIR)/src/compat/Kbuild.include $(ROOT_DIR)/patch/memneq.patch
endif
ifeq ($(APPLY_SPINLOCK_PATCH), 1)
patch $(WIREGUARD_DIR)/src/ratelimiter.c $(ROOT_DIR)/patch/spinlock.patch
endif

$(WIREGUARD_TOOLS_DIR)/src/Makefile: $(WIREGUARD_TOOLS_TAR)
Expand All @@ -68,6 +76,7 @@ install: all
install $(WG_TARGET) $(DESTDIR)/wireguard/
install $(WG_QUICK_TARGET) $(DESTDIR)/wireguard/
install $(WG_MODULE_TARGET) $(DESTDIR)/wireguard/
install $(ROOT_DIR)/wireguard/wg-autostart $(DESTDIR)/wireguard/

clean:
rm -rf $(LIBMNL_TAR) $(LIBMNL_DIR) $(WIREGUARD_TAR) $(WIREGUARD_DIR) $(WIREGUARD_TOOLS_TAR) $(WIREGUARD_TOOLS_DIR)
132 changes: 72 additions & 60 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,41 @@ All models marked *Is working* have been confirmed by users to work. If your
model has the same platform as one of the working ones, chances are it will
work for you too.

========= ========== =========== ===========================
Model Platform DSM Version Is working?
--------- ---------- ----------- ---------------------------
DS1019+ apollolake 6.2 Yes
DS114 armada370 *N/A* No (Kernel version too old)
DS115j armada370 *N/A* No (Kernel version too old)
DS116 armada38x 6.2 Yes
DS1511+ x64 6.2 Yes
DS1618+ denverton 6.2 Yes
DS1817+ avoton 6.2 Yes
DS1815+ avoton 6.2 Yes
DS213j armada370 *N/A* No (Kernel version too old)
DS213j armada370 *N/A* No (Kernel version too old)
DS214play armada370 *N/A* No (Kernel version too old)
DS214se armada370 *N/A* No (Kernel version too old)
DS216+II braswell 6.2 Yes
DS216se armada370 *N/A* No (Kernel version too old)
DS216Play monaco 6.2 Yes
DS218 rtd1296 6.2 Yes
DS218+ apollolake 6.2 Yes
DS218j armada38x 6.2 Yes
DS220+ geminilake 6.2 Yes
DS3617xs broadwell 6.2 Yes
DS414slim armada370 *N/A* No (Kernel version too old)
DS415+ avoton 6.2 Yes
DS418play apollolake 6.2 Yes
DS713+ cedarview 6.2 Yes
DS716+II braswell 6.2 Yes
DS718+ apollolake 6.2 Yes
DS916+ braswell 6.2 Yes
DS918+ apollolake 6.2 Yes
RS214 armada370 *N/A* No (Kernel version too old)
RS816 armada38x 6.2 Yes
========= ========== =========== ===========================
=========== ========== =========== ===========================
Model Platform DSM Version Is working?
----------- ---------- ----------- ---------------------------
DS1019+ apollolake 6.2 Yes
DS114 armada370 *N/A* No (Kernel version too old)
DS115j armada370 *N/A* No (Kernel version too old)
DS116 armada38x 6.2 Yes
DS1511+ x64 6.2 Yes
DS1618+ denverton 6.2 Yes
DS1817+ avoton 6.2 Yes
DS1815+ avoton 6.2 Yes
DS213j armada370 *N/A* No (Kernel version too old)
DS213j armada370 *N/A* No (Kernel version too old)
DS214play armada370 *N/A* No (Kernel version too old)
DS214se armada370 *N/A* No (Kernel version too old)
DS216+II braswell 6.2 Yes
DS216se armada370 *N/A* No (Kernel version too old)
DS216Play monaco 6.2 Yes
DS218 rtd1296 6.2 Yes
DS218+ apollolake 6.2 Yes
DS218j armada38x 6.2 Yes
DS220+ geminilake 6.2/7.0 Yes
DS3617xs broadwell 6.2 Yes
DS414slim armada370 *N/A* No (Kernel version too old)
DS415+ avoton 6.2 Yes
DS418play apollolake 6.2 Yes
DS713+ cedarview 6.2 Yes
DS716+II braswell 6.2 Yes
DS718+ apollolake 6.2 Yes
DS916+ braswell 6.2 Yes
DS918+ apollolake 6.2 Yes
RS214 armada370 *N/A* No (Kernel version too old)
RS816 armada38x 6.2 Yes
Virtual DSM kvmx64 6.2/7.0 Yes
=========== ========== =========== ===========================

The minimum required kernel version is 3.10. If you have a kernel version lower
than that, WireGuard will not work. You can check your kernel version by
Expand All @@ -92,37 +93,27 @@ HP54NL DS3615xs bromolow 6.2 Yes

Installation
------------
Check the `releases <https://github.com/runfalk/synology-wireguard/releases>`_
page for SPKs for your platform. If there is no SPK you have to compile it
yourself using the instructions below.
1. Check the `releases <https://github.com/runfalk/synology-wireguard/releases>`_
page for SPKs for your platform and DSM version. If there is no SPK you have to compile it
yourself using the instruction below.

1. In the Synology DSM web admin UI, open the Package Center and press the
*Settings* button.
2. Set the trust level to *Any publisher* and press *OK* to confirm.
3. Press the *Manual install* button and provide the SPK file. Follow the
instructions until done.
2. (*Not applicable for DSM from 7.0*)
In the Synology DSM web admin UI, open the Package Center and press the Settings button.
Set the trust level to Any publisher and press OK to confirm.

Now you just need to figure out how to configure WireGuard. There are lots of
good guides on how to do that.
3. In the Package Center, press the *Manual install* button and provide the SPK file. Follow the instructions until done.

To put my WireGuard configuration on the NAS, I used SSH and created a
``wg-quick`` configuration in ``/etc/wireguard/wg0.conf``. Then I opened the
*Control panel*, opened the *Task scheduler* and created *Triggered task* that
runs ``wg-quick up wg0`` on startup.
4. (*Only for DSM from 7.0*)
From DSM 7.0, an additional step is required for the WireGuard package to start.
This is related to `preventing packages not signed by Synology from running with root privileges <https://www.synology.com/en-us/knowledgebase/DSM/tutorial/Third_Party/supported_third_party_packages_beta>`_.
When installing the package, uncheck the ``run after installation`` option. After installing the package, `connect to the NAS via SSH <https://www.synology.com/en-us/knowledgebase/DSMUC/help/DSMUC/AdminCenter/system_terminal>`_ and run the ``sudo /var/packages/WireGuard/scripts/start`` command.

When running ``iptables`` in the ``PostUp`` and ``PostDown`` rules I needed to
toggle the interface to make it work. My full startup task looks like this:

.. code-block:: bash

sleep 60
wg-quick up wg0
sleep 5
wg-quick down wg0
sleep 5
wg-quick up wg0
Now you just need to figure out how to configure WireGuard. There are lots of
good guides on how to do that.

My ``/etc/wireguard/wg0.conf`` looks like this:
To put my WireGuard configuration on the NAS, I used SSH and created a
``wg-quick`` configuration in ``/etc/wireguard/wg0.conf``. My configuration looks like this:

.. code-block::
Expand All @@ -142,6 +133,27 @@ Note that you need to modify the rules if your network interface is not
SSH session.


Adding WireGuard to autostart
-----------------------------
DSM since version 7.0 comes with `systemd unit <https://www.freedesktop.org/software/systemd/man/systemd.unit.html>`_ support, while for previous versions you can use the built-in `upstart <http://upstart.ubuntu.com/>`_.
To standardize the process of adding the WireGuard interface to the autostart, a simple ``wg-autostart`` script has been developed.

**Important note:** before adding the interface to the autostart, start it manually by ``sudo wg-quick up wg0`` ensure that it does not cause the system to crash and that you can still access your NAS properly. Otherwise, you may not be able to start the NAS or you may not be able to access the device after a reboot.

To add the ``wg0`` interface to the autostart, run the command:

.. code-block::
sudo wg-autostart enable wg0
To remove the ``wg0`` interface from the autostart, run the command:

.. code-block::
sudo wg-autostart disable wg0
Compiling
---------
I've used docker to compile everything, as ``pkgscripts-ng`` clutters the file
Expand Down Expand Up @@ -177,7 +189,7 @@ contains your SPK files.


Avoiding timeouts when downloading build files
----------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It can take a long time to pull development files from SourceForge, including
occasional timeouts. To get around this, create a folder locally and map it to
the `/toolkit_tarballs` Docker volume using the following command:
Expand Down
2 changes: 0 additions & 2 deletions SynoBuildConf/depends

This file was deleted.

5 changes: 5 additions & 0 deletions SynoBuildConf/install
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ create_package_tgz() {

create_spk(){
local scripts_dir=$PKG_DIR/scripts
local conf_dir=$PKG_DIR/conf

### Copy package center scripts to PKG_DIR
mkdir -p $scripts_dir
cp -av scripts/* $scripts_dir

### Copy package conf to PKG_DIR
mkdir -p $conf_dir
cp -av conf/* $conf_dir

### Copy package icon
cp -av PACKAGE_ICON*.PNG $PKG_DIR

Expand Down
52 changes: 38 additions & 14 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,46 @@ echo

# Fetch Synology toolchain
if [[ ! -d /pkgscripts-ng ]] || [ -z "$(ls -A /pkgscripts-ng)" ]; then
git clone https://github.com/SynologyOpenSource/pkgscripts-ng
clone_args=""
# If the DSM version is 7.0, use the DSM7.0 branch of pkgscripts-ng
if [[ "$DSM_VER" =~ ^7\.[0-9]+$ ]]; then
clone_args="-b DSM7.0"
export PRODUCT="DSM"
fi
git clone ${clone_args} https://github.com/SynologyOpenSource/pkgscripts-ng
else
echo "Existing pkgscripts-ng repo found. Pulling latest from origin."
cd /pkgscripts-ng
git pull origin
cd /
fi

# Temporary workaround for some architectures that are not part properly set as
# 64 bit: https://github.com/SynologyOpenSource/pkgscripts-ng/pull/26/
# NOTE: This fix breaks your workflow if you save the pkgscripts-ng repo state
# across runs
if [[ "$PACKAGE_ARCH" =~ ^geminilake|purley|v1000$ ]]; then
sed -i 's/\(local all64BitPlatforms\)=".*"/\1="PURLEY V1000 GEMINILAKE"/' /pkgscripts-ng/include/platforms
# Configure the package according to the DSM version
if [[ "$DSM_VER" =~ ^7\.[0-9]+$ ]]; then
os_min_ver="7.0-40000"
pkgscripts_args=""

# Synology has added a strict requirement on DSM 7.0 to prevent packages
# not signed by Synology from running with root privileges.
# Change the permission to run the package to lower in order
# to successfully install the package.
run_as="package"

# For Virtual DSM 7.0 (vkmx64) the wireguard kernel module
# requires a spinlock implementation patch
if [[ "$PACKAGE_ARCH" =~ ^(kvmx64)$ ]]; then
export APPLY_SPINLOCK_PATCH=1
fi
else
os_min_ver="6.0-5941"
run_as="root"
pkgscripts_args="-S"
fi

# Temporary add support for 7.0 (until the official repo is updated)
grep -q '^AvailablePlatform_7_0=' /pkgscripts-ng/include/toolkit.config || \
echo '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"' >> /pkgscripts-ng/include/toolkit.config
package_dir=`dirname $0`
cp -p "$package_dir/template/INFO.sh" "$package_dir/INFO.sh" && sed -i "s/OS_MIN_VER/$os_min_ver/" "$package_dir/INFO.sh"
cp -p "$package_dir/template/conf/privilege" "$package_dir/conf/privilege" && sed -i "s/RUN_AS/$run_as/" "$package_dir/conf/privilege"
cp -p "$package_dir/template/SynoBuildConf/depends" "$package_dir/SynoBuildConf/depends" && sed -i "s/DSM_VER/$DSM_VER/" "$package_dir/SynoBuildConf/depends"

# Install the toolchain for the given package arch and DSM version
build_env="/build_env/ds.$PACKAGE_ARCH-$DSM_VER"
Expand All @@ -68,9 +89,6 @@ if [ ! -d "$build_env" ]; then
cp /etc/ssl/certs/ca-certificates.crt "$build_env/etc/ssl/certs/"
fi

# Disable quit if errors to allow printing of logfiles
set +e

# Patch WireGuard to use its own included memneq implementation if architecture
# does not have built in memneq support.
if [ -z ${APPLY_MEMNEQ_PATCH+x} ]; then
Expand All @@ -88,6 +106,9 @@ if [ -z ${APPLY_MEMNEQ_PATCH+x} ]; then
fi
fi

# Disable quit if errors to allow printing of logfiles
set +e

# Build packages
# -p package arch
# -v DSM version
Expand All @@ -98,7 +119,7 @@ fi
pkgscripts-ng/PkgCreate.py \
-p $PACKAGE_ARCH \
-v $DSM_VER \
-S \
${pkgscripts_args} \
--build-opt=-J \
--print-log \
-c WireGuard
Expand All @@ -107,6 +128,9 @@ pkgscripts-ng/PkgCreate.py \
# a non-zero exit code on errors.
pkg_status=$?

# Clean up the build environment
rm "$package_dir/INFO.sh" "$package_dir/conf/privilege" "$package_dir/SynoBuildConf/depends"

echo "Build log"
echo "========="
cat "$build_env/logs.build"
Expand Down
5 changes: 5 additions & 0 deletions conf/resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"usr-local-linker": {
"bin": ["wireguard/wg", "wireguard/wg-quick", "wireguard/wg-autostart"]
}
}
20 changes: 20 additions & 0 deletions conf/systemd/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[Unit]
Description=WireGuard via wg-quick(8) for %I
After=pkgctl-WireGuard.service
Wants=pkgctl-WireGuard.service
Documentation=https://github.com/runfalk/synology-wireguard
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
Documentation=https://www.wireguard.com/
Documentation=https://www.wireguard.com/quickstart/

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/wg-quick up %i
ExecStop=/usr/local/bin/wg-quick down %i
ExecReload=/bin/bash -c 'exec /usr/local/bin/wg syncconf %i <(exec /usr/local/bin/wg-quick strip %i)'
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity

[Install]
WantedBy=syno-low-priority-packages.target
File renamed without changes.
13 changes: 13 additions & 0 deletions patch/netlink.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- netlink.c 2021-01-09 19:18:42.109012366 +0100
+++ netlink.c 2021-01-09 16:08:05.098280000 +0100
@@ -62,8 +62,8 @@
nla_data(attrs[WGDEVICE_A_IFNAME]));
if (!dev)
return ERR_PTR(-ENODEV);
- if (!dev->rtnl_link_ops || !dev->rtnl_link_ops->kind ||
- strcmp(dev->rtnl_link_ops->kind, KBUILD_MODNAME)) {
+ if (!dev->dev.type || !dev->dev.type->name ||
+ strcmp(dev->dev.type->name, KBUILD_MODNAME)) {
dev_put(dev);
return ERR_PTR(-EOPNOTSUPP);
}
12 changes: 12 additions & 0 deletions patch/peerlookup.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- peerlookup.c 2021-01-19 01:34:52.624027083 +0100
+++ peerlookup.c 2021-01-19 01:40:12.063429383 +0100
@@ -7,6 +7,9 @@
#include "peer.h"
#include "noise.h"

+#define spin_lock_bh(lock) __raw_spin_lock_bh(&(lock)->rlock)
+#define spin_unlock_bh(lock) __raw_spin_unlock_bh(&(lock)->rlock)
+
static struct hlist_head *pubkey_bucket(struct pubkey_hashtable *table,
const u8 pubkey[NOISE_PUBLIC_KEY_LEN])
{
12 changes: 12 additions & 0 deletions patch/spinlock.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- ratelimiter.c 2021-01-19 01:34:52.624027083 +0100
+++ ratelimiter.c 2021-01-19 01:38:32.474371582 +0100
@@ -21,6 +21,9 @@
#include <linux/slab.h>
#include <net/ip.h>

+#define spin_lock(lock) __raw_spin_lock(&(lock)->rlock)
+#define spin_unlock(lock) __raw_spin_unlock(&(lock)->rlock)
+
static struct kmem_cache *entry_cache;
static hsiphash_key_t key;
static spinlock_t table_lock = __SPIN_LOCK_UNLOCKED("ratelimiter_table_lock");
Loading

0 comments on commit 70c2683

Please sign in to comment.