0%

在Linux系统中用USB无线网卡连接网络

我们公司有两个网络,一个用于访问内部网络资源,简称为内部网络,另一个网络用于访问外部互联网资源,简称外部网络。

平时大家工作中以内部网络为主,为了方便使用,内部网络也开放了外部互联网的资源访问。由于公司内几乎所有人日常工作都使用这个网络,所以网络策略限制了外部互联网下载速度到500KB左右。而外部网络则没有任何下载速度限制。

最近在做机器学习的实验时,遇到了令人头疼的网络下载速度问题。

做实验的机器是一台台式机,以有线的方式接入内部网络,被分配了固定的ip地址。机器访问内部资源倒是比较快,但是访问互联网就速度受限了。

由于机器学习数据集或者模型文件都很大,常常是好几十GB,用内部网络下载常常要好几个小时,严重影响了效率。

怎么办呢?在和公司IT人员沟通之后找到了一个简单的方案:买一个无线网卡插在台式机上面,让台式机支持双网络的访问。这样一来,平时可以与之前一样接入内部网络,一旦有大文件下载需求时,就切换到外网网络。

于是,我买了绿联的这个USB无线网卡。

USB product

根据产品说明,这个网卡可以支持Windows系统和Linux系统,可以满足我的台式机的Linux系统需求。

在收到网卡之后,怀着激动的心情,立即插在了机器上。然而,系统没有任何反应,居然并不能直接识别网卡!

接下来就是我一下午的在Linux系统中的无线网卡安装使用探索之旅。

在Linux系统中的无线网卡安装使用探索

根据官方文档安装驱动

首先,我通过产品介绍找到了绿联的使用文档:https://www.lulian.cn/download/60-cn.html

ugreen product page

文档中有明确说明,不像在Windows系统中可以免驱直接使用,在Linux下需要先安装网卡驱动才能使用。

网卡驱动可以从网页内容中下载。于是我下载了驱动,并开始安装。

驱动安装包解压之后有两个文件夹,一个Windows一个Linux。其中Linux文件夹下面还有很多关于Android的目录,看起来这个设备还可以支持Android系统。

driver folder

Linux目录中,有个名为install.sh的文件。运行之,可以发现系统开始基于源代码进行编译,编译之后,会开始安装。期间会要求输入用户密码,提升至root权限。

compile & install

源代码的依赖较少,编译安装倒是比较顺利。但是安装之后,还是没自动识别到网卡!这就头大了。

驱动问题分析

经过一番搜索,我发现几篇有用的中文内容(见后文链接部分)。虽然芯片型号不一样,但是安装方式是类似的。结合对install.sh源代码的分析,我发现:

  • 芯片驱动采用Linux内核模块实现
  • 编译驱动代码之后将生成8821cu.ko文件
  • 安装时,会将8821cu.ko拷贝到目录/lib/modules/4.15.0-200-generic/kernel/drivers/net/wireless/
  • 使用命令modprobe 8821cu.ko将驱动动态插入到系统内核
  • 安装完成之后,使用lsmod | grep 8821可以看到8821cu xxxx的结果,说明驱动已经在内核得到支持

上面的安装过程没有出错,结合这里的分析,看起来整个安装是没问题的。既然驱动已经正常安装并可以正常工作,那为什么系统还是无法识别此网卡呢?

发现异常,联系厂家支持

我快速分析了一下当前的情况,看看能不能识别到什么异常。

在经过一系列检查之后,我发现这个网卡使用了Realtek瑞昱的RTL8811cu芯片,但是从官网下载的驱动中,目录名居然是8821cu!这难道就是问题?绿联的文档驱动链接放错了?

suspicious chipset

接着,为了59块钱,我联系了京东客服,从京东客服辗转电话联系到了绿联的技术支持人员。我给绿联的技术人员热心的说明了我发现的问题,然后他们将新的驱动及安装视频发送到了我的邮箱。

driver from ugreen

绿联的安装视频比较简单,看不出来跟我上面的操作有什么区别。发给我的新驱动文件,却依然是8821cu打头的目录!

suspicious chipset again

这就头疼了,还是没解决问题!

接下来看来只能靠自己了。

开源社区的力量

根据我的理解,这款硬件主要功能应该来自于这款REALTEK芯片。就像手机上的芯片一样,它是整个设备最核心的东西。

现在的芯片集成度都非常高,比如,作为手机最重要的部件,手机芯片实际上完成了手机底层核心的大部分功能,如移动网络联网、wifi联网、蓝牙、CPU通用计算、GPU图形计算等等(类似电池、摄像头、屏幕、扬声器等是不涉及的,这些主要由手机厂商选择其他供应商的产品进行集成)。这款芯片应该也不例外。

绿联的位置,如同手机厂商一样,主要完成产品设计、集成工作。

如此一来,此芯片的驱动应该由REALTEK厂商提供才对。

于是,我尝试到REALTEK官方网站去找这款芯片的驱动。在找驱动的同时,也进行了一些搜索,还真有不少内容!

关键的内容来自这个开源项目。阅读其文档可以了解到:

  • REALTEK没有为这款流行的8811芯片公开Linux驱动
  • 8811驱动可以根据8821驱动做一些修改来适配
  • 有人已经做了适配了

到这里,我大概弄清楚了,绿联文档中的或者发我的驱动应该都没问题。这个驱动应该可以同时支持8821芯片和8811芯片。

那为什么还是不对呢?

还需要设置USB设备的工作模式

首先,系统有没有识别到这个设备?这可以通过插拔设备观察结果。使用lsusb命令可以看到当前的所有设备,在经过测试之后,我发现系统确实识别到了一个新设备:

lsusb

根据中文文档中的内容,如果正常,使用ifconfig -a应该能看到新的网络设备出现。但是现在还不行。

最后,在上面Github的文档中,我找到了一些新的线索。原来需要切换一下设备的模式!

按照文档说明,组织了一下命令sudo usb_modeswitch -KW -v xxxx -p xxxx,执行之后,成功切换了网卡模式。运行ifconfig -a终于可以看到网卡设备了!

ifconfig output

有了网卡,后续的系统配置应该就不是难事了。

在命令行中配置无线网络

我查找了一些文档,主要可以借助几个工具实现在命令行中管理无线连接。

  • 搜索无线网络: iwlist IF_ID scanning
  • 生成无线网络密码: wpa_passphrase NET_ID >> /etc/wpa_supplicant/wpa_supplicant.conf (需要提供wifi密码)
  • 根据密码配置连接无线网络: wpa_supplicant -i IF_ID -c /etc/wpa_supplicant/wpa_supplicant.conf -D wext -B
  • 验证是否连接成功: iwconfig (命令将显示连接到的网络ID,但是此时可能还没有分配到IP地址,无法上网)
  • 自动分配IP地址: dhclient -v -r IF_ID
  • 验证是否连接成功: ifconfig (命令将显示无线网络已经被分配了一个IP地址)

自动切换网络

到现在为止,我们有了两个可以访问互联网的网络连接了。如何切换两个网络呢?可以通过配置路由来实现。

我这里的场景比较简单,同一时间只需要一个接口工作就行,所以可以通过修改默认路由来实现。如果场景复杂一点,希望两个网络同时工作,可以类似的用route命令指定不同的IP地址路由到不同的网络接口来实现。

最后我写了几个脚本以便自动化的切换网络,给大家参考:

1
2
3
4
5
6
7
8
9
10
# connect-wifi
set -xe
IF_ID=YOUR_IF_ID
NET_ID=YOUR_NET_ID
IP_PREFIX=YOUR_NET_IP_PREFIX
sudo wpa_supplicant -i $IF_ID -c /etc/wpa_supplicant/wpa_supplicant.conf -D wext -B
while true; do iwconfig 3>&1 | grep $NET_ID && break; echo not connected yet, sleep 1s and retry; sleep 1; done;
sudo dhclient -v -r $IF_ID # refresh ip
sudo dhclient -v $IF_ID # configure ip
while true; do ifconfig $IF_ID | grep $IP_PREFIX && break; echo ip not assigned yet, sleep 1s and retry; sleep 1; done
1
2
# disconnect-wifi
ps aux | grep supp | grep -v grep | awk '{print $2}' | xargs sudo kill
1
2
3
4
5
# route-wired
ID=YOUR_WIRED_IF_ID
GW=YOUR_GW_FOR_WIRED_IF
sudo ip route delete default
sudo ip route add default via $GW dev $IF_ID
1
2
3
4
5
# route-wifi
IF_ID=YOUR_WIRED_IF_ID
GW=YOUR_GW_FOR_WIRELESS_IF
sudo ip route delete default
sudo ip route add default via $GW dev $IF_ID

大功告成

一起来看看最终的效果:

之前的网络下载速度:

slow

无线网络的下载速度:

fast

参考

欢迎关注我的其它发布渠道