随笔-88  评论-224  文章-23  trackbacks-0
描述
   原始套接字具有广泛的用途,特别是用于自定义协议(标准协议TCP、UDP和ICMP等外)的数据收发。在Linux下拦截套接字IO的一般方法是拦截对应的套接字系统调用,对于发送为sendmsg和sendto,对于接收为recvmsg和recvfrom。这种方法虽然也能拦截原始套接字IO,但要先判断套接字的类型,如果为SOCK_RAW(原始套接字类型),那么进行拦截处理,这样一来由于每次IO都要判断套接字类型,性能就比较低了。因此为了直接针对原始套接字来拦截,提高性能,发明了本方法。
   本方法可用于防火墙或主机防护系统中,丢弃接收和发送的攻击或病毒数据包。

特点
   运行在内核态,直接拦截所有进程的原始套接字IO,支持IPv4和IPv6。


实现
   原理
      在Linux内核网络子系统中,struct proto_ops结构提供了协议无关的套接字层到协议相关的传输层的转接,而IPv4协议族中内置的inet_sockraw_ops为它的一个实例,对应着原始套接字。因此先找到inet_sockraw_ops,再替换它的成员函数指针recvmsg和sendmsg,就可以实现拦截了。下面以IPv4为例(IPv6同理),说明几个流程。

   搜索inet_sockraw_ops
      该流程在挂钩IO前进行。由于inet_sockraw_ops为Linux内核未导出的内部符号,因此需要通过特别的方法找到它,该特别的方法基于这样的一个事实:
       所有原始套接字接口均存放在以SOCK_RAW为索引的双向循环链表中,而inet_sockraw_ops就在该链表的末尾。
       内核提供了注册套接字接口的API inet_register_protosw,对于原始套接字类型,该API将输入的套接字接口插入到链表头后面。
      算法如下
      
      注册p前或注销p后,链表如下
      注册p后,链表如下

   挂钩IO
      该流程在内核模块启动时进行。

   卸钩IO
      该流程在内核模块退出时进行。


运行部署

   该方法实现在Linux内核模块中,为了防止其它内核模块可能也注册了原始套接字接口,因此需要在操作系统启动时优先加载。  
posted on 2016-07-14 10:27 春秋十二月 阅读(1099) 评论(3)  编辑 收藏 引用 所属分类: Network

评论:
# re: 一种拦截Linux原始套接字IO的方法[未登录] 2016-07-14 12:34 | chipset
工作是做网络安全?  回复  更多评论
  
# re: 一种拦截Linux原始套接字IO的方法[未登录] 2016-07-14 12:53 | 春秋十二月
@chipset
是的  回复  更多评论
  
# re: 一种拦截Linux原始套接字IO的方法[未登录] 2016-07-14 12:56 | chipset
很有前途和很有钱途啊。  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理