群晖编译内核模块启用iptables额外功能

/ mess

群晖系统的内核经过了高度的定制,很多内核模块都没有,导致iptables的一些功能也缺失。
本文就是通过群晖的源码来编译内核模块和iptables用户插件来启用额外功能。

我自己的是群晖918+ DSM 7.2.2-72806 Update 3,下面都以这个来进行操作。

准备

源码

上面的源码,编译工具和iptables版本都注意要和自己的群晖系统对应。

编译环境

将上面的源码都解压到 ~/dev 下:

1
2
3
iptables-1.8.3
linux-4.4.x
x86_64-pc-linux-gnu

环境变量配置:

1
2
3
4
5
6
7
8
export PATH=~/dev/x86_64-pc-linux-gnu/bin:$PATH
export CROSS=x86_64-pc-linux-gnu
export CC=${CROSS}-gcc
export LD=${CROSS}-ld
export AS=${CROSS}-as
export CXX=${CROSS}-g++
export CROSS_COMPILE=~/dev/x86_64-pc-linux-gnu/bin/x86_64-pc-linux-gnu-
export ARCH=x86_64

检查 x86_64-pc-linux-gnu-gcc -v 看是否配置好了编译环境。

编译可以在群晖上,也可以在其他机器上。这里演示是在一台 Debian 12.11 的 x86 虚拟机上。

编译

复制配置文件

进入 linux-4.4.x 文件夹,将918+的配置复制出来:

1
cp synoconfigs/apollolake .config

synoconfigs 下有其他群晖型号的配置,找到自己的复制出来即可。

配置内核模块

内核模块可以通过菜单选择,也可以通过 scripts/config 来配置,也能直接编辑 .config 文件。

推荐通过菜单选择,不然有些模块间的依赖如果没配置好容易编译失败。

通过 make menuconfig 进入菜单,选择自己需要的模块。菜单界面是可以通过 / 来进行搜索的。

!!!特别注意!!!

就算选择对应的源码,在内核版本配置上也需要通过菜单 General setup -> Local version - append to kernel release 配置额外的版本后缀,
或者通过 .config -> CONFIG_LOCALVERSION 来配置。否则编译好的内核是无法加载到系统中的。

群晖918+的实际系统内核版本号是 4.4.302+ 多了个 + ,所以上面的配置需要加上个 +

如果通过 scripts/config 配置内核,之后需要执行 make oldconfig 来写入配置。

编译内核模块

这里是以编译 net/netfilter 模块为例:

1
2
3
cd linux-4.4.x
make prepare
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE M=net/netfilter -j 4

编译成功的内核模块就在 net/netfilter 下。

编译iptables扩展

1
2
3
cd iptables-1.8.3
./configure --host=$CROSS --prefix="~/dev/iptables-1.8.3" --disable-nftables
make

编译好的扩展位于 iptables-1.8.3/extensions 下。大部分iptables扩展都需要对应的内核模块。

优化

执行 x86_64-pc-linux-gnu-strip --strip-unneeded xx.ko(xx.so) 来去掉调试信息,减少文件大小。

安装

将内核模块复制到群晖 /lib/modules/ ,iptables扩展复制到 /usr/lib/iptables/

执行 sudo insmod /lib/modules/xxx.ko 加载内核模块,如果此时内核版本没有对应上或者编译工具不一致就会导致模块无法正确加载,
iptables扩展复制过去就能生效,不用额外操作。

总结

需要注意的点:

  1. 内核版本后缀;
  2. 编译工具正确配置;
  3. 内核模块间的依赖,没有正确配置可能导致相应的模块不会编译,也不会报错;

参考文档: syno-iptables

上面仓库能下载到常用的iptables内核模块和扩展,如果没有就需要自己编译了。