标签:
我先将我的架构图贴上来,稍后我在慢慢讲解。
我们都知道IPv4,很多人也知道局域网,但是很初入研发行列的人并不知道局域网IP(私有网络IP地址段)这件事情的存在。那么私有网路IP段是什么?一句话概括就是,你使用的IP地址是可以被重复的,你能访问公有网络IP地址段(IP地址不可重复),但是别人没办法访问你的IP地址。那么这些地址都是什么,可以看下面这个表
开始地址 | 结束地址 | IP数量 |
|
A类,8位掩码,1个地址段 | 10.0.0.0 | 10.255.255.255 | 16777216 |
B类,12位掩码,16个地址段 | 172.16.0.0 | 172.31.255.255 | 1048576 |
C类,16位掩码,256个地址段 | 192.168.0.0 | 192.168.255.255 | 65536 |
NAT的工作原理是基于TCP状态机和IP:Port元组的对照关系表。我们假设我们的公有网络IP地址位202.96.199.13,我们使用的私有网络IP地址段位192.168.1.0/24。我们可以假设用户A的机器IP地址位192.168.1.10,网关地址是192.168.1.1。那么当用户A访问了一次Web,我们会在我们的网关(NAT路由器)上有什么呢?
内网IP | 内网Port | 外网IP | 外网Port | 目标IP | 目标Port | 协议类型 |
192.168.1.10 | 4859 | 202.96.199.13 | 8762 | 8.8.8.8 |
53 | UDP |
192.168.1.10 | 6736 |
202.96.199.13 | 3698 | 220.181.112.244 | 80 | TCP |
192.168.1.10 | 6737 | 202.96.199.13 | 3789 | 220.181.112.244 | 443 | TCP |
我们可以看到一个TCP的访问会出现内网IP和Port,外网IP和Port,还有目标IP和Port,以及协议类型。NAT路由器的工作就是将内网发出去的IP包的原IP和Port替换成外网的IP和Port,当收到数据包将目标IP和Port替换成内网IP和Port。如果内网IP开启了一个新TCP链接,这个表中没有,NAT路由器会创建一个新的条目。如果公网想访问内网该怎么办呢?,不是说绝对不可能,这个可以通过DNAT完成,但是有限制,这个限制限制了外网IP上的Port被永久映射到内网某个IP和Port上。也就是说,不能一个端口被任意使用,具体细节参看Linux iptables中的相关介绍。
这时候会有同学发出疑问,你不说NAT的工作原理是基于TCP嘛,为什么表上有UDP呢?因为NAT路由器在实现的时候考虑到UDP了,UDP虽然没有状态,但是可以通过统计是否有流量及设置超时的时间来决定是否关闭一条NAT规则。而TCP的关闭就会依照TCP的状态机和超时机制来决定何时关闭。
从上面的讲解我们可以看到我们想让公有IP访问私有IP的HTTP服务,需要使用DNAT。但是如果不只一个人使用这个端口那就悲剧了。那么如果我们所有暴露的服务端口都是HTTP协议的,那么这个事情就非常好解决了,可以使用ngrok这个工具。那么其中的原理是什么呢?一个是泛域名技术,另一个是HTTP/1.1的header的host域。
通过使用泛域名技术,我们可以拥有很多类似usera.mbooks.me,userb.mbooks.me这种域名。另一方面,根据HTTP/1.1规范的规定,我们每个HTTP请求的host字段指定的是我们要访问的域名。这样我们就可以在一个IP:Port上使用多个域名了。
满足这两个条件之后,我们剩下的就是让RevProxy主动去连接AccessPoint了。当然AccessPoint后RouteMesh是有公网IP地址的,这样别人才能访问到。
我们假设有一个用户D,他的机器在NAT路由器后面。他所需要的是开启自己的Web服务器,并绑定一个IP:Port。接着启动RevProxy,并将刚才的IP:Port传入进去。然后用户只要访问RevProxy返回的域名就可以了。
RevProxy接收到IP:Port后,主动连接到具有公网IP地址的AccessPoint,AccessPoint会随机生成一个域名给RevProxy,如我们可能会生成ae24.mbooks.me这种域名。然后AccessPoint将自己和生成的域名写入Redis。之后RevProxy和AccessPoint保持一个长链接。
RouteMesh解析请求的HTTP头,找出host字段。之后通过查询Redis找出相应的AccessPoint,并将请求转发给相应的AccessPoint。AcessPoint将请求转发给RevProxy。
当RevProxy收到请求,将请求中的host替换成用户指定的IP,并转发给用户应用。
标签:
原文地址:http://my.oschina.net/u/236698/blog/499650