像玩乐高一样玩 simpletun
作者| dog250责编 | 张文出品 | CSDN(ID:CSDNnews)netcat 小巧而灵活,能应付各种你需要的网络测试。但要明白 netcat 所能应对的网络场景基本...
作者 | dog250 责编 | 张文
出品 | CSDN(ID:CSDNnews)
netcat 小巧而灵活,能应付各种你需要的网络测试。
但要明白 netcat 所能应对的网络场景基本都和端到端有关,比如和 TCP,UDP 有关。
网络还有另一面,即链路本身。如果你想模拟一个防火墙,模拟一个 NAT 怎么办?用 netcat 能做到吗?这个时候你可能就必须自己写内核模块了吧。
Netfilter?eBPF?NFV?这些都太复杂了!
可以在用户态完成的时候就尽量在用户态搞,简单稳定最重要。
我推荐 simpletun。
simpletun 并不是某个著名的开源软件,但是在网上一找可以找一大片,随便找一个杂耍即可。我说的 simpletun 模拟搭建网络设备的功能并不是说用它的二进制直接就能做到,而是说你可以随意对它进行三两行的那种魔改,让它实现你需要的功能。
搭建一个 TCP 隧道我这里就不说了,详见:
https://github.com/marywangran/simpletun/blob/main/simpletun.c
本文我要演示一个 NAT 功能。
正好我要调研一个 NAT64 的方案,我在思考如果没有现成方案的话能不能用 tun 设备搭建一个,当然了,肯定是有现成方案的,也就没有动用 tun 设备。但总想试试,看看到底有多简单,那就简单写了一个:
https://github.com/marywangran/simpletun/blob/main/tunnat.c
玩法很简单,README 里都写了:
这里的关键就几行代码:
if (FD_ISSET(tap_fd, &rd_set)) { struct iphdr *iph; /* data from tun/tap: just read it and write it to the network */ unsigned int addr1 = inet_addr(from_ip); unsigned int addr2 = inet_addr(to_ip);
nread = cread(tap_fd, buffer, BUFSIZE); iph = (struct iphdr *)buffer; if (addr2 == iph->daddr) { iph->daddr = addr1; } else if (addr1 == iph->saddr) { iph->saddr = addr2; } else { continue; } iph->check = 0; iph->check = ip_checksum((unsigned short *)iph, 20);
nwrite = cwrite(tap_fd, buffer, nread);}
当然,如果你想实现一个完整可用的 NAT,那肯定需要维护一些链表保存 session 之类,但 POC 不需要这些。
相对应的,如果你想用 tun 模拟一个 NAT64,也并不困难:
将需要被 NAT64 的流量路由到 tun 网卡。
用你的程序将从 tun 字符设备读取的裸包 IPv4 头换成 IPv6 头。
将换完的裸包作为 buffer 写回到 tun 字符设备。
额外在外部配合一些个配置即可,这些配置基本上用 iproute2 都可以完成。
simpletun 的确很 low,就像 netcat 和 nginx 相比也很 low 一样,问题是你需要拿它做什么。我之所以善于在很短的时间验证一个事情行还是不行,在于我不善于折腾复杂的东西。
我一向的观点就是,如果我是一个画家,我希望拿起笔来作画,而不是去学那些复杂的工具。
到底很多领域的所谓牛人是在该领域真的很牛呢,还是说作为活体说明书很牛呢?很多的优秀设计师因为不会 CAD 找不到工作,也有很多的菜鸟设计师因为精通 CAD 而登峰造极…
程序员如何避免陷入“内卷”、选择什么技术最有前景,中国开发者现状与技术趋势究竟是什么样?快来参与「2020 中国开发者大调查」,更有丰富奖品送不停!
☞程序员硬核“年终大扫除”,清理了数据库 70GB 空间☞一行代码没写,凭啥被尊为“第一位程序员”?
☞任正非就注册姚安娜商标道歉;人人影视字幕组因盗版被查;JIRA、Confluence 等产品本月停售本地化版本 | 极客头条
更多推荐
所有评论(0)