弱网络模拟工具实践

达芬奇密码2018-06-27 15:44

·1  背景

为便于项目团队发现移动端APP/Web页面在2/3G等弱网场景下的页面展现和体验问题,需要建设一个易用且符合公司网络安全要求的弱网络模拟工具。


·2  技术方案选择

1. 直接利用fildder、charles 等抓包工具的限速功能

优点:可直接利用公司现有网络设备和结构,无需新建热点。

缺点:没有个人用户界面,只能集中统一管理,不便于团队成员随意切换不同网络。

2. 搭建FB-ATC平台

优点:可实现不同用户使用不同的网络限制,有个人用户操作界面,用户连接和网络切换方便。

缺点:搭建部署较为复杂;需新建wifi热点,与公司网络安全策略有冲突;且wifi覆盖范围有限,不能覆盖到有需要的所有团队成员。

以上2中方案各有优缺点,如何融合2种方案的优点,并努力避免有严重缺陷,于是想出了第3种方案:

3. 搭建一个基于charles代理并利用TC规则实现网络限速的工具

优点:直接利用公司现有网络设备和结构,无需新建热点。可实现不同用户使用不同的网络限制,且用户自主切换和控制。

缺点:暂时基于jenkins的用户操作界面,无法自动获取Client IP,新增用户需要手工配置jenkins任务及分配端口。

尽管目前第三种方案的实现还存在缺点,但已能满足项目成员的基本使用需求。

 

·3  具体实践方案

3.1  如何引流到弱网控制服务端

利用手机等设备的WIFI网络HTTP代理功能,配置WIFI代理到弱网服务端,并在服务器上启动charles作为代理程序。(即利用以上第一种方案的优点:不新建热点,不更改网络结构)

3.2  如何控制不用用户的下载网络

利用linux自带的TC流量控制工具,建立队列、分类规则、过滤器,配合neteam的使用丰富网络参数的设置。可实现不同目标IP使用不同的网速限制。(与FB-ATC实现原理类似,ATC也是使用iptables+TC的方法来实现不同IP的限速)

3.3  如何控制不用用户的上传网络

由于使用HTTP代理引流到弱网服务器的charles代理程序,再经charles发出去的包被抹去了来源IP,无法根据来源IP进行TC规则的限速,即无法利用TC进行不同用户IP的上传限速。

经过数次尝试没能解决问题正打算放弃时,与辉哥讨论后得到思路指点:既然charles可以控制上传网速,何不利用它来实现不同用户的上传网络限制。

有了新的思路,于是立马做了验证,得出解决方法:可通过命令行后台启动charles,并在启动前利用shell脚本去修改charles启动时的配置文件中的 监听端口、上传带宽。使得不同用户启动不同端口的charles,最终实现不同用户使用/控制不同的上传带宽。

3.4  如何便于用户使用(即用户操作界面)

网速控制方法有了,脚本写好之后,如何便于使用,实现一个类似ATC的用户界面需要前、后端开发框架的学习使用,时间成本较高,于是想到利用jenkins作为用户操作界面,用户普遍都会使用,没有学习成本,且有丰富的动态参数插件,能达到自定义网络参数的目的。

·4  实现效果展示

jenkins用户操作界面

         

    (图1-1  2G网络)    

      

                                                                              

    (图1-2  自定义500kb下载)


限速设备实时网速

            

    (图2-1  2G场景 6.63KB/s                                                    图2-2  500kb场景  62.3KB/s


·5  实现细节描述

如读者有兴趣/有需要,可继续看一下实践的细节

5.1  TC的流量控制实现

1. 调度器 qdisc选用 HTB 模型,因为它可以分类,且流量控制的比较精确。 分类(class每个 class 对应不同的用户。过滤(filter)规则是用户的 IP 地址。不同 IP 用户的流量通过filter规则进入不同的分类从而进行流量控制。通过 htb 模型可以对流量进行限速,丢包、延迟、乱序、重包等网络参数则需要通过 netem 模块进行控制

2. 基于IP的HTB模型图

3. 实现的脚本示例:

# ens33 为网卡名标识
# 192.168.1.101 为限速的设备IP
# add root qdisc
sudo tc qdisc add dev ens33 root handle 1:0 htb default 2
# add primary class
sudo tc class add dev ens33 parent 1:0 classid 1:1 htb rate 100mbit ceil 100mbit
# add default class
sudo tc class add dev ens33 parent 1:1 classid 1:2 htb rate 100mbit ceil 100mbit
# add a class 1:1101 limit 10KB
sudo tc class add dev ens33 parent 1:1 classid 1:1101 htb rate 80kbit ceil 80kbit
sudo tc qdisc add dev ens33 parent 1:1101 netem delay 100ms loss 50%
# add a filter handle the ip 101 to class 1:1101
sudo tc filter add dev ens33 parent 1:0 protocol ip prio 0 u32 match ip dst 192.168.1.101 flowid 1:1101

5.2  charles的命令行启动流量控制实现

Charles启动时会加载默认的配置文件~/.charles.config,在该配置文件中设定了启动时的http代理端口、限速带宽等等配置项。因此,可先复制一份配置文件,并替换其中的端口port、上传带宽bandwidthUp,最后用这份修改后的配置文件启动charles,用户在设备上配置WiFi代理到服务器时也使用这个新的HTTP端口即可连入,具体脚本示例如下:

# 用户wifi 代理端口
userwifiport=10001
# 复制charles 配置文件
sudo cp -rf  ~/.charles.config ./charles_$userwifiport.config
# 替换端口  
sudo sed -i "s/.*<\/port>/10001<\/port>/g" charles_$userwifiport.config
# 替换上传限制
sudo sed -i "s/.*<\/bandwidthUp>/123<\/bandwidthUp>/g" charles_$userwifiport.config
DIR="$( cd "$( dirname "$0"  )" && pwd  )"
# 启动指定端口的charles
sudo /usr/lib/charles-proxy/jre/bin/java -Xmx1024M -Dcharles.config=$DIR/charles_$userwifiport.config -jar /usr/lib/charles-proxy/charles.jar >/dev/null 2>&1 &

5.3  不同用户的环境隔离

因使用指定端口的charles做上传网络限速,为避免不同用户同时使用的相互干扰,需要为每个用户分别指定一个不同端口,并配置在不同的jenkins任务中,所以需要对jenkins的job做权限控制,使得不同用户只能访问各自的job,正好jenkins有插件支持可达到目的。

  1. 安装jenkins插件 Role-based Authorization Strategy  后,在系统管理-->Configure Global Security 中启用安全,授权策略选择“项目矩阵授权策略”,并勾选 匿名用户的 Overall Read 权限:

    


   2. 在jenkins 系统管理-->管理用户 下新建一些用户:

    


   3. 在各job配置选择“启用项目安全”,并添加相应的用户:


·6  尚需改进的地方

   因依托于jenkins作为用户界面,虽省去了前后端框架的开发,便于快速实践,但也造成一些不足:

   1. 限速设备IP首次需要手动填写,虽做了记忆功能,但还存在手误填错的可能性,后续希望能改进为自动获取Client IP。

   2. 新增用户需要管理者手动创建一个job并分配好端口,这一步希望能自动完成。

   后续计划自己搭建前后端框架并开发实现一个简易的用户操作界面,用以解决上述存在的不足,更好的满足团队成员的使用需要。


本文来自网易实践者社区,经作者李琼授权发布。