这篇文章写于 2019-11-30 可能其中的内容已经发生更改
简介
我们知道其实有很多内网穿透,或者能实现这个功能的工具,可以分为以下几类:proxy代理、第三方服务器、UPnP、DMZ、sproofing、dns转换、pwnat
-
监听端口,反代型
- frp
- ngrok
他们有两个明显的缺点,1. 只能代理端口 2. 不是 p2p,需要服务器中转
-
普通 vpn
- WireGuard
- OpenVPN
- ...
他们有一个矛盾,要么流量的路由不是最短的(就是说有中转),要么配置特别麻烦(就是加入一个服务器就要修改所有的服务)
-
Automatic full mesh routing (通俗的来说就是 p2p)
- tinc-vpn
- nebula(slack 大量运用,十多天前开源)
- zerotier
(越后面的配置越容易)
他们都有一个特征,有一个类似于中心化管理的地方(比如 nebula 叫做 lighthouse)他们记录了每个服务器的ip,这样就能建立 p2p 的 vpn 了
-
pwnat
这个通过一些方法能在不需要第三方参与的情况下完成 p2p 链接。
nebula
这里说一下 nebula 配置因为国内相关的内容比较少
-
生成证书
先在自己的电脑上下载 cli 工具 Release
./nebula-cert ca -name "RedRock"
这时这个目录下面就有了 ca.key(根据这个生成,要保护好) 和 ca.crt
-
生成节点的证书
./nebula-cert sign -name "lighthouse1" -ip "192.168.101.1/24" ./nebula-cert sign -name "node1" -ip "192.168.101.2/24" ./nebula-cert sign -name "node2" -ip "192.168.101.3/24"
-
编写配置文件 (config.yaml)
-
lighthouse
pki: ca: /etc/nebula/ca.crt cert: /etc/nebula/lighthouse1.crt key: /etc/nebula/lighthouse1.key static_host_map: lighthouse: am_lighthouse: true interval: 60 # 如果是 lighthouse 这里必须留空 hosts: listen: host: 0.0.0.0 port: 4242 # 避免防火墙 nat 映射过期 punchy: true tun: # 网卡名字 dev: nebula1 drop_local_broadcast: false drop_multicast: false tx_queue: 500 mtu: 1300 routes: logging: level: info format: text firewall: conntrack: tcp_timeout: 120h udp_timeout: 3m default_timeout: 10m max_connections: 100000 outbound: - port: any proto: any host: any inbound: - port: any proto: any host: any
-
node
pki: ca: /etc/nebula/ca.crt cert: /etc/nebula/node1.crt # 这里需要改名字 key: /etc/nebula/node1.key static_host_map: # 必须准确的告诉 nebula lighthouse 服务器的地址 "192.168.101.1": ["xx.xx.xx.xx:4242"] lighthouse: am_lighthouse: false interval: 60 hosts: # lighthouse 服务器地址 - "192.168.101.1" listen: host: 0.0.0.0 # 设置为 0 随机生成 port: 0 # 避免防火墙 nat 映射过期 punchy: true tun: # 网卡名字 dev: nebula1 drop_local_broadcast: false drop_multicast: false tx_queue: 500 mtu: 1300 routes: logging: level: info format: text firewall: conntrack: tcp_timeout: 120h udp_timeout: 3m default_timeout: 10m max_connections: 100000 outbound: - port: any proto: any host: any inbound: - port: any proto: any host: any
-
-
服务器安装配置
- 将 ca.crt 和对应的 xxx.crt, xxx.key 上传到 /etc/nebula/
- 上传对应系统的 nebula 到 /usr/local/bin/
- 可执行
chmod +x /usr/local/bin/nebula
- systemd 服务
cat > /etc/systemd/system/nebula.service <<EOF [Unit] Description=nebula Wants=basic.target After=basic.target network.target [Service] SyslogIdentifier=nebula StandardOutput=syslog StandardError=syslog ExecReload=/bin/kill -HUP $MAINPID ExecStart=/usr/local/bin/nebula -config /etc/nebula/config.yaml Restart=always [Install] WantedBy=multi-user.target EOF systemctl enable nebula systemctl start nebula
UDP 打洞
这些工具的都使用了 UDP 打洞, 穿透 NAT 的一个难点就是需要在 NAT 中建立一个映射关系,而且这个映射关系还和 NAT 的类型有关,所以有些 NAT 就不能穿透(需要进行猜测端口),这里讲的是,两边都是 限制锥形NAT或者端口限制锥形NAT
zerotier
zerotier 的结构比较有趣,我们来看看他的组成
这个组成其实和 dns 比较相似,如果 LEAF(叶子) 之间没有链接,就到 moon 中去找,如果没有的话继续向上PLANET 查询
然后他的配置在网上都烂大街了,这里就不说了。需要注意的就是如果加入 moon 服务器可能不怎么顺利,需要把 moon 生成的文件粘贴到 LEAF 对应的目录中。
pwnat
这个就更为神奇了,他能在不用第三方的参与下,完成 p2p 的链接,之前不是说了一个外部索引服务器来存储每个服务的 ip 地址,并且还要转发映射关系。这就是参与进来的第三方,而 pwnat 通过伪装 ICMP跳跃点 的方式来得知对方的 ip。
什么是 ICMP 跳跃点?大家用过路由追踪吧,TTL 规定了数据报被丢弃前,最多能够经过的节点数。
- 这个时候 NAT Host(服务器) 启动了之后,它开始向固定地址1.2.3.4发送固定的 ICMP回应请求包(ICMP echo request packets)。显然,我们无法从 1.2.3.4 收到返回的 ICMP回应数据包
- Non-NAT Host(知道服务器IP地址)会向服务器发送 ”ICMP超时数据包“(ICMP Time Exceeded packet)。 这个ICMP数据包里面包含了服务器发送到 1.2.3.4 的“原始”固定ICMP回应请求数据包。
为什么要这样做呢?
我们假装是互联网上的一个 ICMP跳越点,礼貌地告诉服务器它原来的 “ICMP回应请求” 数据包无法传递到1.2.3.4。而你的NAT是一个“聪明”的设备,它会注意到”ICMP超时数据包“内的数据包与服务器主权发出“ICMP回应请求”数据包相匹配“。然后它将”ICMP超时数据包“转发回NAT后面的服务器,包括来自客户端的完整IP数据包头,从而让服务器知道客户端IP地址是什么
p2p 跟前端(js)有有什么联系?
-
WebRTC
WebRTC 其中的一种模式就是 peer-to-peer 的
-
ipfs (一种 p2p 协议)
- PeerTube p2p 的视频网站
- ...
参考
- https://www.usenix.org/legacy/event/usenix05/tech/general/full_papers/ford/ford_html/
- http://samy.pl/pwnat/pwnat.pdf
- https://www.cnblogs.com/GO-NO-1/p/7241556.html
- https://www.zhihu.com/question/20436734
- https://imweb.io/topic/5a4a6cb2a192c3b460fce37f
- https://zhuanlan.zhihu.com/p/40816201
- https://evilpan.com/2015/10/31/p2p-over-middle-box/
- https://blog.csdn.net/coldboy258/article/details/93133860
- https://github.com/slackhq/nebula
- https://github.com/slackhq/nebula/blob/master/examples/service_scripts/nebula.service
- https://zhuanlan.zhihu.com/p/36811672