为了账号安全,请及时绑定邮箱和手机立即绑定

关于 NAT,你所不知道的一切

标签:
Linux

作者:YongHao_Hu,原文地址

作为程序员,我们都知道,ipv4地址很早就不够用了,然后有一项技术,可以内网用同一个外网 ip——是的,那就是 NAT(Network Address Translation),网络地址交换技术。

它的原理,其实很简单。假如分配给你的内网地址是10.9.8.11, 而公网是169.5.6.1, 内网地址是没办法与外网通信的——因为其他地方也有内网,也会有跟你一样的地址10.9.8.11。

当你要建立一条 tcp 连接(即是访问外部网络时),该TCP端口号就当是80吧, 会先把网络包发送给路由器(通常路由器内含 NAT 了),NAT 用一个表记录下你的内网地址10.9.8.11,端口号:80,而 NAT 会分配一个随机的端口号给你,如467,再把你的地址转换成公网169.5.6.1:467,与你要访问的目标地址建立起链接。

现在你发出去这条路是通了,别人发过来的包,NAT 怎么判断该发回去哪台内网机器呢?

NAT 会分配你一个端口号(在上面是467),所以当有外部网络访问467时,NAT 会根据记录下的表,找到467端口对应的是内网10.9.8.11:80,转发回去。

既然是用表记录了,自然要考虑到表会不会满的问题。端口数量是有限的0~65535,作为程序员的我们都会想到,肯定是要删除很久不用的链接的。是的,一旦NAT 表里某记录很久不活跃,没有包发出收入(通常是5-30分钟,可以自行设置),就会把该记录删除掉。

但是这就带来了一个问题,假如我的程序像 QQ一样,需要长时间的链接呢? NAT 丢弃不活跃链接的时候,是不会通知内网的你以及外网的程序的,也就是说,是不可能重建的了。

最合理的方法当然就是自己实现心跳包,每隔一段时间程序发送一个小包给对方,对方也发回来,不仅保活,也可以检查服务是否遇到不可知错误而中断了。 不一定需要自己实现心跳包,对稳定性需求不高,可以用 linux 内核提供的 TCP keepalive。启用后,系统会按设定的时间(默认是2小时),发送一个包过去。

# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
  • tcp_keepalive_time: 如果在该时间内没有数据往来,则发送探测包。

  • tcp_keepalive_intvl: 探测包发送间隔时间。

  • tcp_keepalive_probes:

尝试探测的次数。如果发送的探测包次数超过该值仍然没有收到对方响应,则认为连接已失效并关闭连接。

当然默认的2小时比较鸡肋,2小时内没有数据来往,NAT 早踢了你的链接了,一个比较合理的设定是15-30分钟。

iptalbes

Linux 本身就能够做一个 NAT,你知道吗?

想想 docker 是怎么样访问外部网络的?docker 里的 container(容器)都是内网10.xx.xx.xx,宿主机是怎么样与内网通信呢?

Yes,答案一样是 NAT。

Linux 本身就提供了 iptables来做 NAT,具体流程from《鸟哥的 linux 私房菜》:

  1. 先经过 NAT table 的 PREROUTING 链;

  2. 经由路由判断确定这个封包是要进入本机与否,若不进入本机,则下一步;

  3. 再经过 Filter table 的 FORWARD 链;

  4. 通过 NAT table 的 POSTROUTING 链,最后传送出去

PREROUTING会修改目标IP, POSTROUTING链会修改来源 IP, 通常我们的 NAT 内网转外网是修改来源 IP(即内网 IP),成为来源 NAT(Source NAT, SNAT)。
尽管你在宿主机能够解析到archive.ubuntu.com,

% nslookup archive.ubuntu.com
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   archive.ubuntu.com
Address: 10.18.75.45

在 /etc/docker/daemon.json里配置了 docker 的 dns 使用本机,以及8.8.8.8, 还是无法解析.

这时候就只能去改/etc/hosts 了, 把 nslookup 得到的 ip 地址直接写到里面:

archive.ubuntu.com 10.18.75.45

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
59
获赞与收藏
236

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消