红联Linux门户
Linux帮助

Ubuntu 16.04虚拟网络设备tun安装

发布时间:2017-04-21 10:05:36来源:linux网站作者:lishuhuakai
最近编写网络程序,需要用到tun模块,但是官方给的发行版中压根就没有这个模块.
不信的话,你可以测试一下:
root@ubuntu:~# modinfo tun
modinfo: ERROR: Module tun not found.
当然,如果你测试的结果是这样的:
Ubuntu 16.04虚拟网络设备tun安装
只能说明你可能已经安装了,但是还要进一步测试,运行下面两条命令,如果得到类似下面的结果,那么这篇文章后面的东西你就不用看了,如果没有任何输出,那么你估计要重新安装一下tun模块了.
root@ubuntu:~# modprobe tun
root@ubuntu:~# lsmod | grep tun      # 列出所有的模块,在其中寻找tun
tun                    28672  0
接下来我会详细记录一下我解决这个东西时遇到的一些问题,也是为了方便以后的查看吧.
 
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.验证和加载
和文章最开始的套路是一样的,如果得到类似下面的输出,基本上你的安装就成功了.
Ubuntu 16.04虚拟网络设备tun安装
当然,也有可能会失败,事实上,我编译了几次都失败了,每次验证的时候,执行到modprobe tun的时候,都会输出类似与下面的错误信息:
modprobe: ERROR: could not insert 'tun': Exec format error
事实上你可以用dmesg查看错误的原因,下面是用该命令输出的最后一行:
[   51.803686] tun: no symbol version for module_layout
网上查看了一下别人的资料,我觉得可能的一个原因是内核的版本不匹配,因为我之前使用的内核版本和我编译的内核版本版本存在差异,网上有解决方案,但是不适合我,如果你想节约时间的话,可以查看:
Ubuntu 16.04虚拟网络设备tun安装
既然上面的步骤都不行,我干脆重新编译一下内核好了.
 
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
一切完成之后,重新启动电脑,一切就都完成了.接下来你就可以用上面的办法来检测了.
 
本文永久更新地址:http://www.linuxdiyf.com/linux/30181.html