Ubuntu 16.04虚拟网络设备tun安装

时间:2022-06-01 08:21:18

Ubuntu 16.04虚拟网络设备tun安装

最近编写网络程序,需要用到tun模块,但是官方给的发行版中压根就没有这个模块.

不信的话,你可以测试一下:

root@ubuntu:~# modinfo tun
modinfo: ERROR: Module tun not found.

当然,如果你测试的结果是这样的:

root@ubuntu:~# modinfo tun
filename:       /lib/modules/4.8.17/kernel/drivers/net/tun.ko
alias:          devname:net/tun
alias:          char-major-10-200
license:        GPL
author:         (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
description:    Universal TUN/TAP device driver
srcversion:     7CDF0549396A7B788E3753B
depends:
intree:         Y
vermagic:       4.8.17 SMP mod_unload modversions

只能说明你可能已经安装了,但是还要进一步测试,运行下面两条命令,如果得到类似下面的结果,那么这篇文章后面的东西你就不用看了,如果没有任何输出,那么你估计要重新安装一下tun模块了.

root@ubuntu:~# modprobe tun
root@ubuntu:~# lsmod | grep tun # 列出所有的模块,在其中寻找tun
tun                    28672  0

接下来我会详细记录一下我解决这个东西时遇到的一些问题,也是为了方便以后的查看吧.

如果你懒得查看下面的内容,其实有一个更好的办法,那就是更换一个已经包含了tun模块的linux发行版.这里我强烈推荐deepin,真正适合不折腾的人.对于国人来说,这个发行版比ubuntu更加舒服和漂亮.

1. 下载源码

lishuhuakai@ubuntu:~$ sudo apt-get install linux-source
linux-source         linux-source-4.10.0  linux-source-4.4.0   linux-source-4.8.0

使用apt-get命令安装linux源代码,一般你按tab键的时候,会有很多的选择,比如说上面,我就有4.4.0, 4.8.0, 4.10.0这几个版本可供选择,到底选择哪一个呢?这个看你个人的爱好了,但是有一点需要注意,尽量不要选择比自己内核版本低,或者比当前内核版本高太多的版本,高太多的话,linux内核高版本对低版本并没有保持非常好的兼容性,所以你要是一下子版本跨越太大,可能内核升级之后,系统都跑不起来.

因为我们并不需要升级内核,所以应该选择一份和自己内核版本号相近的源码.

可以用uname -a来查看当前内核版本号:

lishuhuakai@ubuntu:~$ uname -a
Linux ubuntu 4.8.17 #1 SMP Thu Apr 20 04:16:43 PDT 2017 x86_64 x86_64 x86_64 GNU/Linux

可以看到,我当前的内核版本是4.8.17,所以我选择一个4.8.0的版本即可.源码一般会被安装到/usr/src/linux-source-x.x.x/目录下,x.x.x是版本号,拿我的机子做个示例:

lishuhuakai@ubuntu:~$ cd /usr/src/linux-source-4.8.0/
lishuhuakai@ubuntu:/usr/src/linux-source-4.8.0$ ls
debian  debian.hwe  linux-source-4.8.0.tar.bz2

可以看得到,在这个目录下有一个压缩文件linux-source-4.8.0.tar.bz2,这就是源码的压缩文件,当然,对应到你的机器上,版本号可能会有所不同.

2. 解压缩文件

如果你使用虚拟机的话,请保证空间一定要足够大,因为后面的压缩以及编译都需要不少的空间.

lishuhuakai@ubuntu:~$ tar xvjf linux-source-4.8.0.tar.bz2

进入解压好的目录,为了方便操作,接下来的操作都切换到root账户下,所以我们干脆就不显示root了:

cd linux-source-4.8.0/

3.配置选项

为了后面编译不出错,我们先安装libncurses5-dev,执行命令:

apt-get install libncurses5-dev

即可.

然后配置需要编译的模块:

make menuconfig

然后你大概就能够看到这样一副图像,找到Device Drivers -->,回车选择:

Ubuntu 16.04虚拟网络设备tun安装

继续找到Network Device Support -->,回车选择:

Ubuntu 16.04虚拟网络设备tun安装

找到Universal TUN/TAP device driver support,看到前面是<*>,键盘输入M,变成<M>,退出并保存,回到终端:

Ubuntu 16.04虚拟网络设备tun安装

注:[*],<*>表示编译进内核,<M>表示编译成模块,如果不知道某选项为何时,且有模块可选时,那么就可以直接选择为模块,如果有疑惑,可以去翻鸟哥的linux私房菜基础篇这本书.

4. 编译模块

开始执行命令:

make modules

事实上,上面的编译速度太慢,如果你要加快编译速度的话,可以使用-jn选项,n是一个数字,表示用n个线程并行编译.比如说我这台电脑的话,就是这么干的:

make -j4 modules

使用4个线程,因为我的电脑是双核四线程的cpu,编译的时候cpu使用率可以达到100%,当然,我可以设置-j8或者更高,但是没有意义,当然,如果你的电脑是8线程,那么推荐用-j8,16线程推荐用-j16,能快一点最好不过了.

5. 复制加载模块

编译完成后,可以想内核中加载模块了:

cp /usr/src/linux-source-4.8.0/linux-source-4.8.0/drivers/net/tun.ko  /lib/modules/4.8.0-36-generic/kernel/net/tun.ko

上面的命令是在我的机器上的做法,你的机器可能由于版本号的不同会有所差异.总之要干的事情就是将编译过后的tun.ko复制到/lib/modules/xxx/kernel/net/目录下去,xxx是一个和你当前内核版本号相关的目录,一般而言,这个目录下也就xxx这么一个目录.

接下来是分析可载入模块的相互依赖性:

depmod

6. 验证和加载

和文章最开始的套路是一样的,如果得到类似下面的输出,基本上你的安装就成功了.

root@ubuntu:~# modinfo tun
filename:       /lib/modules/4.8.17/kernel/drivers/net/tun.ko
alias:          devname:net/tun
alias:          char-major-10-200
license:        GPL
author:         (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
description:    Universal TUN/TAP device driver
srcversion:     7CDF0549396A7B788E3753B
depends:
intree:         Y
vermagic:       4.8.17 SMP mod_unload modversions
root@ubuntu:~# modprobe tun
root@ubuntu:~# lsmod | grep tun
tun                    28672  0

当然,也有可能会失败,事实上,我编译了几次都失败了,每次验证的时候,执行到modprobe tun的时候,都会输出类似与下面的错误信息:

modprobe: ERROR: could not insert 'tun': Exec format error

事实上你可以用dmesg查看错误的原因,下面是用该命令输出的最后一行:

[   51.803686] tun: no symbol version for module_layout

网上查看了一下别人的资料,我觉得可能的一个原因是内核的版本不匹配,因为我之前使用的内核版本和我编译的内核版本版本存在差异,网上有解决方案,但是不适合我,如果你想节约时间的话,可以查看这里:http://www.snooda.com/read/329

既然上面的步骤都不行,我干脆重新编译一下内核好了:

7. 最后的选择,重新编译内核

事先说明一句,我的操作都在虚拟机上完成,如果你在真机上测试的话,可能不太妥当,所以如果你使用真机,强烈建议你别人的博文中看一下别人是如何编译内核的.

回到之前源文件解压的目录,首先要配置config文件, 可以直接复制旧版本的:

cp /boot/config-3.19.0-81-generic ./.config 

接下来执行:

make oldconfig

注:复制的是当前版本的config,所以执行这条命令会让你选择新版本多出来的选项,按回车键用默认的新设置.

也可以直接用以下命令进入图形化的设置界面,也就是我们前面所使用的命令:

make menuconfig

这里需要按照前面的步骤,选择Universal TUN/TAP device driver support,设置好后保存退出即可.

接下来就可以编译了:

make -j4  # 开启4个线程并行编译

事先说明一句,编译需要占用大量的空间,我给虚拟机分配了20GB的空间,但是依旧被填满了,所以,如果你也使用虚拟机的话,我个人建议你分配30GB或者更大的空间来编译内核.至于如何给虚拟机添加空间,就不是这篇文章的事情了.

编译的过程中可能会出现两个错误,第一个错误是fatal error: openssl/opensslv.h: No such file or directory,

这是因为没有安装openssl的,需要先安装openssl

apt-get install libssl-dev

第二个错误是bc: not found,需要安装bc:

apt-get install bc

编译可能会花费1~2个小时.完成之后,先安装modules:

make modules_install

接下来安装内核:

make install

一切完成之后,重新启动电脑,一切就都完成了.接下来你就可以用上面的办法来检测了.