和同事讨论UDP打洞技术,后做了一个简单的实验,由于Windows上设置NAT以及察看其原理太麻烦或者根本就不可能,于是还是使用Linux做了实验,发现基于Linux ip_conntrack这种对称NAT也能很简单的实现UDP穿越,实验很简单,并且这种UDP穿越还不需要公网服务器的协助(因为它们对于对称NAT或者基于连接的NAT根本帮不上什么忙),很实用。在展示实验之前,首先要明白以下的知识点。

1.Linux的NAT是基于ip_conntrack的

这一点说明仅仅针对五元组决定的一个连接的第一个数据包进行NAT规则的查找和匹配并存入ip_conntrack结构体,后续的包自动应用ip_conntrack结构体中的NAT信息进行NAT。
        由于五元组标示了一个连接,因此:
1).即使是同一个内网主机发起连接,最终很大程度上也不一定能被转换成同一个(IP地址,协议端口)对
2).目的地址不同,就不是同一个连接,因此绝不可能做到像cone NAT那样的偷梁换柱的效果

2.Linux目前还没有实现cone NAT的模块

Linux的NAT是处于Netfilter模块中的,标准协议栈中没有任何相关支持,那么只要Netfilter不支持cone NAT,Linux NAT就别指望能被常规方式打洞。

3.Linux的NAT尽力不改变连接的源端口

Linux的NAT是通过iptables工具配置的,对于隐藏内网主机这种类型的NAT是iptables的SNAT实现的,如果你man iptables将会发现:
--to-source [ipaddr[-ipaddr]][:port[-port]]
    which can specify a single new source IP address, an inclusive range of IP addresses, and optionally, a port range (which is only  valid  if  the  rule  also specifies  -p tcp or -p udp).  If no port range is specified, then source ports below 512 will be mapped to other ports below 512: those between 512 and 1023 inclusive will be mapped to ports below 1024, and other ports will be mapped to 1024 or above. Where possible, no port alteration will occur.
注意最后一句,Linux尽力不改变连接的源端口,除非和另一个tuple相冲突,我们知道一个tuple就是一个五元组。
        这一点正是给了我们一点启示,那就是可以通过尝试不同端口,直到找到没有被改变源端口的那次连接。而印证这一点也很容易,那就是打洞成功。这也从反方面说明没有必要存在外部服务器了,因为它根本帮不上什么忙。

4.TCP很难穿越Linux这种对称NAT

这是为什么呢?起初,我以为可以采用伪造ACK包的方式进行穿越,然而实验没有成功,后来看了源码发现ip_conntrack对TCP的状态机,序列号范围进行了严格的审查,凡是不通过的...怎样呢?ip_conntrack没有权力丢弃它,而是直接return ACCEPT了,这下就根本别指望能购匹配到任何既有的conntrack了,比如以下的场景:

A-模拟公网主机10.16.0.1;

N-模拟NAT主机10.16.0.254;
B-N后面的主机;

最终目标:A连接B

配置:A上丢弃到来的TCP 6667数据包

行为:

1).B绑定端口6667连接A的端口6667
2).连接顺利通过N,在N上留下了:

tcp      6 52 SYN_SENT src=172.16.0.35 dst=10.16.0.1 sport=6667 dport=6667 packets=3 bytes=180 [UNREPLIED] src=10.16.0.1 dst=10.16.0.254 sport=6667 dport=6667 packets=0 bytes=0 mark=0 secmark=0 use=1
一条UNREPLIED的conntrack
3).此时B反客为主,停掉客户端程序,启动监听同一端口的服务器;
4).A以端口6667连接N的6667
5).SYN数据包到达N,被N发回了reset,实验失败。

这个原理很简单,如果看一下ip_conntrack_in这个ip_conntrack的入口函数,将会发现一个下面的逻辑:

ret = proto->packet(ct, *pskb, ctinfo); if (ret < 0) {     /* Invalid: inverse of the return code tells      * the netfilter core what to do*/     nf_conntrack_put((*pskb)->nfct);     (*pskb)->nfct = NULL;     CONNTRACK_STAT_INC(invalid);     //如果发现状态或者序列号有问题,直接返回,跳出Netfilter的当前HOOK点     return -ret; } ... if (set_reply)     set_bit(IPS_SEEN_REPLY_BIT, &ct->status);

packet回调函数实际上就是tcp_packet函数,里面有复杂的状态机检查,序列号检查等逻辑,因此出错后直接返回,进而即使找到了与之相匹配的/proc/net/ip_conntrack文件中的连接,由于无法继续运行下面的逻辑,所以始终不会将对应连接的UNREPLIED字眼抹去,数据包继续进入协议栈的上层,最终发往N本地,由于N没有监听6667,因此reset。

Linux NAT的这种行为说明很难用常规的方式去穿越.

实验简述

理解了上述的知识点之后,如何进行实验就很简单了,我们只需要3台机器来模拟,拓扑场景和上述4中的一模一样,只是将TCP换成了UDP,很容易就成功了,如果不成功怎么办呢?如果不成功一定是因为在NAT的时候源端口被改掉了,那么我们只需要再多试几个端口,直到找到那个不被修改掉的端口为止。对于TCP,由于还没有找到什么方法,只有放弃了...
        如果希望验证两台同在NAT后面的机器的连通性,原理一样,由于没有那么多机器,作罢了。

注解:关于cone NAT

cone NAT实际上是一种主要以“节约IP地址”为目标的NAT设备,它们并没有维护各个连接的状态,也不采取任何安全策略,是双向的,对于full cone设备,一台内部主机会被映射为一个特定的地址,端口对,而不管它访问什么目标,从任何目标到达full cone NAT设备的映射后端口的都能被该NAT设备转发至内网。

也就是说,所谓的cone NAT正如其名字一样,是一把锥子形状的,从NAT设备向远方辐散开来,一个IP地址,端口对对应多个目标地址,端口对。很显然,这种NAT肯定不是基于连接实现的,而是基于“每包”来实现的。为了提高安全性,还是需要使用对称的NAT或者不管它是什么类型的NAT,只要是基于连接来实现的就行,正如Linux的实现一样,如果以地址,端口对来看,它确实有时是锥子形的,然而如果以连接session来看,它就是对称的,这种NAT的穿越是很难的。

本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1268960

Linux对称NAT的UDP穿越相关推荐

  1. 对称NAT穿透的一种新方法

    前言 这种方法从安全的角度来说是利用了目前路由器实现对称NAT的方法中存在端口可以预测的漏洞,利用这个漏洞来实现打洞.加上一次发送大量的包,来增加命中的概率. 参考资料 整理翻译自A New Meth ...

  2. UDP穿越NAT原理

    http://blog.csdn.net/ldd909/article/details/5979967 论坛上经常有对P2P原理的讨论,但是讨论归讨论,很少有实质的东西产生(源代码).在这里我就用自己 ...

  3. iptables下udp穿越结尾篇----iptables与socks5

    从"iptables和natcheck"一文可知,只要在两端都采用了iptables作NAT后,即使两侧都通过了natcheck的兼容性测试,但iptables两侧永远也不能互相穿 ...

  4. linux添加源地址ping,实战经验:Linux Source NAT在Ping场景下的应用

    原标题:实战经验:Linux Source NAT在Ping场景下的应用 有时候,有这样的一种需求: 需要修改IP数据包中的源地址,比如,从某一个主机发送Ping包到另一个主机,需要修改源地址为另一个 ...

  5. Linux系统NAT实现机制的升级改进

    一点牢骚和希望 一直以来,一直对Linux的NAT很不满,也写过<Linux系统如何平滑生效NAT>系列文章中的patch进行修补,还写过一些类Cisco实现的patch,然而都效果不大好 ...

  6. linux nat源码分析,Linux下NAT/NAPT规则源码分析

    前面有一篇文章分析了为什么在PREROUTING做DNAT对本地连接不起作用?本文再紧接着上文,深入分析一下NAT/NAPT的规则. 事情的起因要从上的那篇的文章说起,因为我的本科生毕业设计也是做P2 ...

  7. Linux iptables NAT配置

    Linux iptables NAT配置 1.NAT原理总结 1.2 NAT的实现分为下面类型: 2.iptables规则持久保存 2.1Centos 6 2.2 Centos7+ 3. SNAT和D ...

  8. linux如何关闭udp端口,如何阻止linux RHEL7中的udp端口范围(How to block udp ports range in linux RHEL7)...

    如何阻止linux RHEL7中的udp端口范围(How to block udp ports range in linux RHEL7) 需要测试使用UDP端口范围从5000到60,000英寸的应用 ...

  9. Cisco与Linux的NAT

    Linux一直以来都使用基于连接跟踪的有状态NAT,虽然xtables-addons里面实现了无状态的静态NAT,即RAWNAT,和Cisco的NAT实现相比还是不够灵活,本文给出一个全局意义的解释, ...

最新文章

  1. bat/cmd 抛出错误码和捕获错误
  2. windows apache html5,Windows服务器下的IIS和Apache性能比较
  3. ble mac地址 协议_BLE获取iphone mac地址的方法--【sky原创】
  4. nginx 一个请求发给多台机器_一个机器人可以同时为多台数控机床上下料吗?东智力衡...
  5. Linux基础(5)--Linux常用命令表
  6. 重磅发布!36氪中国新基建之王「大数据领域」TOP50企业揭晓
  7. mac下electron始终安装不成功解决办法
  8. Django运算表达式与Q对象/F对象
  9. 《寒江独钓》的作者教您如何高效阅读本书
  10. Android addr2line 工具使用
  11. cidaemon.exe进程
  12. Rust:error[E0468]: an `extern crate` loading macros must be at the crate root 处理方法
  13. 【python】使用py3-bencode打开torrent文件
  14. 宏碁暗影骑士AN515-55/57/58原厂预装系统oem镜像
  15. 海克斯康三坐标模块化c语言编程,海克斯康三坐标编程手册_海克斯康三坐标教程...
  16. Appender的几种实现方式
  17. 我要双休,单休等于没有休
  18. phpyun职位表“phpyun_company_job”添加字段,保存数据到数据库
  19. 《冰封王座》世界魔兽界十大叱咤风云人物
  20. 刷酸记录(迪维维A酸乳膏)20190906-0908

热门文章

  1. DeepMind提出新型神经网络架构,用无监督方法从视频中提取关键点 | 论文
  2. React Native 0.59.0 发布,使用 React 编写原生应用
  3. aws ec2使用ses邮件服务的坑
  4. Tensorflow MNIST浅层神经网络的解释和答复
  5. 从CCNA到CCIE的网工认证道路规划
  6. shopex PHP Notice,ShopEx PHP远程包含漏洞
  7. 设计模式 — 行为型模式 — 命令模式
  8. 设计模式 — 结构型模式 — 桥接模式
  9. Linux Kernel TCP/IP Stack — L1 Layer — Network Interface
  10. Ansible — Inventory 清单文件