这个情人节,工程师用阿里云来试着表达不一样的爱意

年轻的时候谈的恋爱就像TCP链接,恋爱时三次握手即可,可分手时却分了四次。而常常久久的爱情,更像是icmp协议,无论对方身在何处,无论是否是可靠连接,无论你何时去ping她/他,她/他都默默地响应你。这篇文章就是说说,如何在内核中增加几行代码,让你的女神/男神当ping你(的服务器)的时候,来传达表达你的爱。效果如下(左边为ping的结果,需要破解ascii码转换为对应字符,右边为使用tcpdump抓包直接读取的信息):

    对于UNIX_LIKE系统来说,如果ping的发送内容与接收内容不同,会显示不同的部分,那么就让你的女神或者男神,慢慢将ASCII码解析成你想告诉她/他的话吧。或者告诉她/他,使用tcpdump来直接抓包隐藏在ping中的悄悄话。(对于windows来说本人没有充分测试,只是知道不会像unix_like系统一样直接显示出请求消息和回显消息的不同,所以需要大家抓包认真提取信息)

一、ICMP协议这些你需要了解:

    学过计算机网络的一定知道,一个网络包的封装主要由多个属于不同网络协议层的报文头和用户数据共同组成:链路层报文头+网络层IP报文头+传输层报文头+携带的内容+帧尾。而ICMP报文在整个以太帧位于如下位置:      

    上图显示的是一个未分片ICMP报文或者是一个较长ICMP报文的第一个IP分片的报文(被分片的报文中不会带有ICMP报头)。RFC792(https://tools.ietf.org/html/rfc792)中定义了11种ICMP报文类型,通过ICMP报头8bit"类型"字段进行区分。并且每种"类型“会和其”代码"字段以及报文头的最后4字节,共同表达每种报文类型所表示的信息。这些ICMP报文类型被主要分为差错报文和查询报文:

  • 查询报文主要包括:回送请求(TYPE8),回送应答(TYPE0),地址掩码或时间戳的请求/应答等
  • 差错报文主要包括:目标主机不可达(TYPE3),超时,源抑制,路由重定向等

    ping作为ICMP协议最为典型的运用,主要和回送请求,和回送应答这两个类型相关,这也是本文主要关心的两个类型。当然,当主机不可达或者网络路由不可达出现的时候,ping会收到路由器传来的TYPE为3的目标主机不可达的报文(我们可以通过tcpdump抓包获取)。对于其他的类型,有兴趣的同学可以自行学习,如icmp重定向攻击,洪水攻击都是利用了ICMP协议进行的网络攻击。

二、动手写一个简单的ping,了解Linux ping

     作为本文的主角之一ping,有必要动手写一个简单的ping,帮助我们更好的理解整个请求应答的过程。我本人的测试机器centos 7中使用的是iputils这个工具进行ping操作,所以我们可以从iputils源码入手学习如何写一个简单的ping。

    学习过c网络编程的一定都了解socket套接字这个概念。对于ping来说发送请求和接受应答也同样是通过套接字来完成。只不过,ICMP协议虽然在内核中和TCP、UDP相似属于L4层协议,但是本质是附属于IP协议的网络层协议,所以需要使用原始套接字(SOCK_RAW)构建套接字,而非TCP或UDP使用的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM)。SOCK_RAW的用途在于用户可以自定义填充IP报文头,并且对于ICMP报文自定义填充ICMP报文头。下面一张图,展示了代码中整个ping的逻辑发送以及处理应答的逻辑。

   

具体代码可以参考这个:https://github.com/xiaobaidemu/myping/blob/master/ping.c 整个流程非常简单,需要说明的是,对于ping 127.0.0.1来说,程序极有可能先收到type为0的回显请求报文,再收到type为8的回显应答报文。这是因为icmp报文可以同时被内核接收处理,也会被原始套接字接收处理,如下为Understanding Linux Network Internals书中所述。

三、添加内核代码前,你只需要知道一个结构体和icmp.c

    理解了ping的整个过程,接下来就是需要修改内核来传达你想说的话。但是最重要的是,需要分析出修改的位置,即回显应答可能发送的字节在内核代码中的位置。这里有一个非常重要的结构体——struct sk_buff,其定义位于<include/linux/skbuff.h>。

    内核中sk_buff结构体做到了可以不使用拷贝或删除的方式,使得数据在各层协议之间传输——即移动指针头的方式,具体为在处理不同的协议头时,代表协议头的指针,指向的是不同数据区域(如从L2到L4层协议,分别指向二层mac头,三层IP头,四层传输头)。以下是几个比较重要和混淆的字段说明,结合示意图说明:

指针head/end从head指针到end指针区域指向的数据块为真实存储以太帧数据区域(包括了链路成之上的各层协议协议头和数据报文,且一直不变)
指针data/taildata指针和tail指针表示当前正在处理的协议层的开始和结束为止(其随着处理协议的向高层/低层推进而变化)head<=data<=tail<=end
len

data_len和len比较抽象。len表示skbuff中由head到tail指向的数据块的大小+分片fragment(即skb_shared_info结构体中)非线性数据大小,其大小会随着在内核各层中移动而变化(去掉或者增加了各层协议头)

data_len

data_len仅为分片中非线性数据大小。

   上图简单说明了四个指针和指向区域之间的关系。另外对于data_len和len的关系,如果假设icmp报文比较小,ip层不会对其分片,那么data_len即为0,而len即为当前协议头长度+数据报文长度。关于data_len和len之间的关系涉及到skb_shared_info这个结构体的相关内容,因为和文章中心关系不大,有兴趣的同学可以自行查阅一下文章来学习

  • http://blog.51cto.com/weiguozhihui/1586777
  • https://0x657573.wordpress.com/2010/11/22/the-relation-between-skb-len-and-skb-data_len-and-what-they-represent/
  • https://blog.csdn.net/farmwang/article/details/54233975

    上述内容中data指针和表征协议层数据长度的len,和后文中修改的sk_buff指向的数据直接相关。另外sk_buff关联了众多其他结构体,这里只简要的讲解部分重要的字段含义,更为具体详细的说明可以参考Understanding Linux Network Internal第二章或者https://blog.csdn.net/YuZhiHui_No1/article/details/38666589系列文章进行更深入学习。

    了解了sk_buff结构体,之后需要定位处理icmp协议的文件在哪里。icmp.c位于内核目录中net/ipv4/icmp.c中,且ICMP协议通常是静态编译至内核中,而非通过模块配置的。这里我从Understanding Linux Network Internal这本书中抠出来一张Big Picture,来简要说明一下对于ping发出的回显请求,sk_buff结构体对象是如何在icmp中众多函数中传递。

    首先ip_local_deliver_finish会传递ICMP消息到icmp_rcv, icmp_rcv会解析icmp报头中类型字段,对于属于查询报文的类型(如type8)会传递给icmp_reply, 而对于差错报文会传递给icmp_send处理,并且ICMP协议也会和其他诸如TCP/UDP协议进行交互传递信息。对于ping进程发出的请求,会先传递给icmp_echo函数进行处理。而icmp_echo正是处理ping请求很重要的一步,内核会把请求中附带的数据报文部分原封不动的拷贝并发送回源主机。因此我们可以在icmp_echo函数中,添加进我们"爱的语句"。

static bool icmp_echo(struct sk_buff *skb)
{struct net *net;net = dev_net(skb_dst(skb)->dev);if (!net->ipv4.sysctl_icmp_echo_ignore_all) {struct icmp_bxm icmp_param;icmp_param.data.icmph      = *icmp_hdr(skb);icmp_param.data.icmph.type = ICMP_ECHOREPLY;icmp_param.skb             = skb;//-----------添加开始-----------char sentence1[] = "I LOVE U, xxxx.";char sentence2[] = "I MISS U, xxxx.";char sentence3[] = "Happy Valentine's Day!";int sentence_len_list[] = {sizeof(sentence1), sizeof(sentence2), sizeof(sentence3)};char* sentence_list[] = {sentence1, sentence2, sentence3};int sentence_index = icmp_param.data.icmph.un.echo.sequence % 3;if(skb->len >= 16 + sentence_len_list[sentence_index]){char* tmp = (char*)(skb->data+16);char* target_sentence = sentence_list[sentence_index];int i=0;for(;i<sentence_len_list[sentence_index];++i){tmp[i] = target_sentence[i];}for(;i < skb->len-16;++i){tmp[i] = 0;}}//-----------添加结束------------icmp_param.offset          = 0;icmp_param.data_len        = skb->len;icmp_param.head_len        = sizeof(struct icmphdr);icmp_reply(&icmp_param, skb);}/* should there be an ICMP stat for ignored echos? */return true;
}

    上述代码中icmp_bxm结构体包含了在后续icmp消息传递过程中的所有需要的信息,包括icmp报文头,sk_buff对象,icmp 报文payload大小等。需要注意的是,由于icmp_rcv已经解析过sk_buff中属于icmp协议的报文头部分,所以参数中skb->data指向的是icmp数据部分,即不包含报文头,而skb->len也只有icmp数据部分的长度。假设ping请求中所带的数据部分为56字节,则此时skb->len大小为56。由于ping数据部分的前16字节为携带的是发送是struct timeval对象——发送时的时间,所以在真实替换时,从data指向的数据部分的第16个字节开始,用memcpy复制到对应区域,或者如上例子傻傻的循环赋值即可。上面代码所表示的就是根据echo请求中seq_id循环回复上述三句话。当然有创意的小伙伴可以增加更多表达难度。

四、创建一个阿里云ECS服务器,十分钟完成所有修改

    分析完了整个icmp处理流程,和修改方法,我们只需要创建一个阿里云ECS,并简单编译修改后的内核即可。具体流程如下:

  1. 阿里云创建任意规格服务器(大规格可以加快内核编译速度,此处创建一个4vcpu服务器),使用centos作为os
  2. 下载linux内核代码,并解压放置到/usr/src/kernels目录下,本文使用的是4.20.6内核版本。
  3. 编译前基于原centos系统中/boot目录下的config文件,生成编译配置项,根据此编译项来定制内核。拷贝原配置文件至内核文件目录 sudo cp /boot/config-3.10.0-693.el7.x86_64 ./.config;执行make oldconfig,生成新的.config文件
  4. 编译源码:make -j 4 ,可能编译过程中缺少某些库,此时yum安装缺少的库,如openssl-devel, elfutils-libelf-devel
  5. 安装内核模块:make modules_install -j 4
  6. 拷贝内核和配置文件至/boot目录,并生成System.map文件:make install -j 4
  7. 更新引导:grub2-mkconfig -o /boot/grub2/grub.cfg
  8. 修改默认默认启动引导内核:修改/etc/default/grub文件,将GRUB_DEFAULT设为0,0表示第一个启动项,即为最新编译的内核。
  9. 重启服务器:reboot

    至此告诉你的女神/男神,你想说的话都在ping中。

 


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云+X案例展 | 金融类:金山云为新网银行重塑金融服务提供云计算动力

本案例由金山云投递并参与评选&#xff0c;CSDN云计算独家全网首发&#xff1b;更多关于【云X 案例征集】的相关信息&#xff0c;点击了解详情丨挖掘展现更多优秀案例&#xff0c;为不同行业领域带来启迪&#xff0c;进而推动整个“云行业”的健康发展。作为国内第三家、中西部…

对于AES和RSA算法的结合使用以及MD5加盐注册登录时的密码加密

RSA和AES结合使用 接上篇的RSA和AES算法加密之后&#xff0c;AES对称算法对数据量大的加密比较快&#xff0c;而RSA公私钥加密的话会影响加密效率&#xff0c;但是AES的加密与解密的密钥是一致的&#xff0c;导致密钥不能外泄&#xff0c;密钥在网络传输过程中&#xff0c;很有…

Unity人物移动的几种方法

Unity人物移动的几种方法 方法一&#xff1a;transform.Translate世界坐标系移动自身移动的案例 方法二&#xff1a;CharacterController.Move&#xff08;vector dir&#xff09;按照世界坐标轴移动按照自身坐标轴移动 方法三&#xff1a;CharacterController.SimpleMove&…

可应用于实际的14个NLP突破性研究成果(四)

可应用于实际的14个NLP突破性研究成果&#xff08;一&#xff09; 可应用于实际的14个NLP突破性研究成果&#xff08;二&#xff09; 可应用于实际的14个NLP突破性研究成果&#xff08;三&#xff09; 11.对序列建模的通用卷积和递归网络的实证评估作者&#xff1a;SHAOJIE …

量子通信,到底是什么工作原理?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 小枣君责编 | 阿秃今天&#xff0c;小枣君要和大家聊的是“量子通信”。最开始计划写这个专题的时候&#xff0c;小枣君的内心是很纠结的。鲜枣课堂的目的&#xff0c;就是传递“普通人都能听懂”的知识。每一个知识点专题&a…

图(关系网络)数据分析及阿里应用

2019年1月18日&#xff0c;由阿里巴巴MaxCompute开发者社区和阿里云栖社区联合主办的“阿里云栖开发者沙龙大数据技术专场”走近北京联合大学&#xff0c;本次技术沙龙上&#xff0c;阿里巴巴资深技术专家钱正平为大家分享了大数据技术背景下图数据的应用前景&#xff0c;以及阿…

架构的“一小步”,业务的一大步

前言&#xff1a; 谈到“架构”这两个字&#xff0c;会有好多的名词闪现&#xff0c;比如:分层架构、事件驱动架构、DDD、CQRS等。亦或者一堆的软件设计原则&#xff0c;如&#xff1a;KISS原则&#xff08;Keep it Simple and Stupid&#xff09;、SOLID原则(单一责任原则、开…

牵手大企,关于图形计算、HPC与AI,NVIDIA言有尽而意无穷!

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 晶少出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在黄仁勋看来&#xff0c;随着摩尔定律消亡&#xff0c;GPU加速才是撬动未来高性能计算发展的有力杠杆。有数据显示&#xff0c;目前NVIDIA已经销售了…

如何合理的规划jvm性能调优

JVM性能调优涉及到方方面面的取舍&#xff0c;往往是牵一发而动全身&#xff0c;需要全盘考虑各方面的影响。但也有一些基础的理论和原则&#xff0c;理解这些理论并遵循这些原则会让你的性能调优任务将会更加轻松。为了更好的理解本篇所介绍的内容。你需要已经了解和遵循以下内…

如何衡量研发效能?阿里资深技术专家提出了5组指标

阿里妹导读&#xff1a;新的一年&#xff0c;相信很多产品技术团队把研发效能提升列为重要的目标&#xff0c;甚至还有团队为此专门成立了项目组。然而&#xff0c;到底什么是好的研发效能&#xff0c;却很少有人能够表达清楚。标准不清晰&#xff0c;又何谈提升&#xff1f; …

官宣!2020年,这5类程序员要过苦日子!网友:明年咋活?!

2020年就要来了&#xff0c;有人说&#xff1a;经历了2019年的“市场变革”后&#xff0c;未来这一年将会至关重要&#xff0c;是决定各自命运的定型年。那么对于程序员来说&#xff0c;明年的风向标是如何&#xff1f;哪些编程语言会持续大热&#xff0c;哪些要做好被“淘汰”…

Perseus-BERT——业内性能极致优化的BERT训练方案【阿里云弹性人工智能】

一&#xff0c;背景——横空出世的BERT全面超越人类 2018年在自然语言处理&#xff08;NLP&#xff09;领域最具爆炸性的一朵“蘑菇云”莫过于Google Research提出的BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;模型。作为一种新型的…

Kubernetes的共享GPU集群调度

问题背景 全球主要的容器集群服务厂商的Kubernetes服务都提供了Nvidia GPU容器调度能力&#xff0c;但是通常都是将一个GPU卡分配给一个容器。这可以实现比较好的隔离性&#xff0c;确保使用GPU的应用不会被其他应用影响&#xff1b;对于深度学习模型训练的场景非常适合&#…

华为云WeLink正式发布,这是更懂企业的智能工作平台一枚!

今日&#xff0c;华为云在京发布智能工作平台WeLink。 对此&#xff0c;华为云副总裁、联接与协同业务总裁薛浩表示&#xff1a;“华为云WeLink源自华为数字化转型实践&#xff0c;是更懂企业的智能工作平台&#xff0c;具备智能高效、安全可靠、开放共赢三大核心优势&#xff…

一致性协议浅析:从逻辑时钟到Raft

前言 春节在家闲着没事看了几篇论文&#xff0c;把一致性协议的几篇论文都过了一遍。在看这些论文之前&#xff0c;我一直有一些疑惑&#xff0c;比如同样是有Leader和两阶段提交&#xff0c;Zookeeper的ZAB协议和Raft有什么不同&#xff0c;Paxos协议到底要怎样才能用在实际工…

PMP 随堂笔记

CPi挣值管理 临界比值 不属于挣值管理 临界比值 1为分界点 党校与1时&#xff0c;差 大于1时为好 成本激励由有3种场景&#xff1a; 第一种场景&#xff1a;超出目标费用 目标10w 利润1w 分摊比例70/30 实际成本12w 也就是多花了(12w-10w(目标费用)2w 甲方罚乙方利润费用&…

Objective-C中的associated object释放时机问题

如果对象A持有对象B&#xff0c;B作为A的associated object&#xff0c;并且表面上B没有其他被强引用的地方&#xff0c;那么对象A被释放时&#xff0c;对象B一定会同时释放吗&#xff1f;大部分情况下是&#xff0c;但真有不是的时候。最近实现代码的时候不小心就碰到了这样的…

开放共赢,华为云WeLink生态联盟正式成立!

今日&#xff0c;华为在京发布了“更懂企业”的智能工作平台华为云WeLink&#xff0c;并携手合作伙伴成立华为云WeLink生态联盟。其中首批加入华为云WeLink生态联盟的伙伴主要包括&#xff08;排名不分先后&#xff09;&#xff1a;金山办公、中软国际、致远互联、罗技、华为商…

指明方向与趋势!2019开发者技能报告出炉!!!

近日国外开发者平台 HankerRank 发布了 2019 年开发者技能调查报告&#xff0c;该报告根据对71,281开发者的调查得出。 2018 年最受欢迎的开发语言 &#xfffc; 经过调查&#xff0c;2018年的所有开发语言中&#xff0c;JavaScript是最受欢迎的语言&#xff0c;2017年最受欢…

阿里研究院入选中国企业智库系统影响力榜

2019年2月1日&#xff0c;上海社会科学院智库研究中心发布《2018年中国智库影响力评价与排名》。阿里研究院入围三项排名榜单&#xff0c;位居企业智库系统影响力榜单第2位&#xff0c;中国智库社会影响力榜单第13位&#xff0c;中国智库综合影响力排名榜单第42位。 阿里研究院…