惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
J
Java Code Geeks
博客园_首页
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
P
Palo Alto Networks Blog
V
Vulnerabilities – Threatpost
雷峰网
雷峰网
O
OpenAI News
SecWiki News
SecWiki News
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
N
News | PayPal Newsroom
Project Zero
Project Zero
Forbes - Security
Forbes - Security
IT之家
IT之家
A
Arctic Wolf
WordPress大学
WordPress大学
Jina AI
Jina AI
T
Tor Project blog
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
Attack and Defense Labs
Attack and Defense Labs
博客园 - 聂微东
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy International News Feed
Cloudbric
Cloudbric
G
GRAHAM CLULEY
博客园 - 叶小钗
H
Hacker News: Front Page
腾讯CDC
量子位
Help Net Security
Help Net Security
人人都是产品经理
人人都是产品经理
C
Cyber Attacks, Cyber Crime and Cyber Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
爱范儿
爱范儿
L
Lohrmann on Cybersecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recorded Future
Recorded Future
C
CERT Recently Published Vulnerability Notes

Yesterday17's Blog

2026 新年解密红包 / Melody Flag | Yesterday17's Blog 谈谈 Iori 的设计思路(二):如何实现一个 Showroom 录制工具? | Yesterday17's Blog 谈谈 Iori 的设计思路(一):从 Nico Timeshift 说起 | Yesterday17's Blog Iori Minyami 0.1.0 发布 | Yesterday17's Blog 2025 新年解密红包 / Melody Flag | Yesterday17's Blog 使用 Cloudflare Warp 解决罗森票务的海外登录问题 | Yesterday17's Blog How To Blog 04: The Astro v5 Era | Yesterday17's Blog 谈谈 tokio::select! 的公平性 | Yesterday17's Blog Learning Pingora 05 - Connect with TLS | Yesterday17's Blog Leaving Bytedance | Yesterday17's Blog 大橋彩香 AsiaTour「Reflection」上海公演 个人向记录 & Repo | Yesterday17's Blog Recoving from burnout - What happened? | Yesterday17 Yubikey 重建手册 | Yesterday17's Blog How To Blog 03: Heimus | Yesterday17's Blog 🪧 Blog Migration Accouncement | Yesterday17's Blog Learn Your IDE - VSCode 是如何仅重启插件的? | Yesterday17's Blog How To Blog 02: Astro❤️Password | Yesterday17's Blog How To Blog 01: Why, How, and the Future | Yesterday17's Blog Learning Pingora 04 - Establish L4 Connection | Yesterday17's Blog Learning Pingora 03 - Upstreams and Peers | Yesterday17's Blog Learning Pingora 02 - A Simple HTTP Server | Yesterday17's Blog Learning Pingora 01 - Getting Started | Yesterday17's Blog 2024 新年解密红包 / Melody Flag | Yesterday17's Blog 向新的一年飞驰——记录 2023 | Yesterday17's Blog 「サクラノ刻」对话选摘(2) | Yesterday17's Blog PGP Key Revocation 注销声明 | Yesterday17's Blog 「サクラノ刻」对话选摘(1) | Yesterday17's Blog 2023 新年解密红包 / Melody Flag | Yesterday17's Blog 『蒼の彼方のフォーリズム』通关感想 | Yesterday17's Blog 单显卡直通教程 | Yesterday17's Blog 对博客与笔记的思考 | Yesterday17's Blog Project Anni 之旅(3)自动化 Flutter 应用 CI/CD 上架流程 | Yesterday17's Blog AsobiStage 直接播放链接 | Yesterday17 如何在后分P时代进行投稿——sswa使用详解 | Yesterday17's Blog JSON RPC 与 LSP 协议基础 | Yesterday17's Blog Grajapa Shueisha / BookEnd 加密方式调查 | Yesterday17's Blog 【2022篇+WriteUp】如何再收一个新年红包? | Yesterday17's Blog 如何将良心云的良心功能清理干净 | Yesterday17's Blog 【油猴脚本】bilibili 投稿页面返回旧版+旧版页面强制允许分P上传 | Yesterday17's Blog Cloudr1v1 授权方式分析 | Yesterday17 Typora 1.0.2 逆向实录 | Yesterday17's Blog Project Anni 之旅(2)ValueAfterTable——toml-rs的实现与限制 | Yesterday17's Blog IPv4透明代理+IPv6 Passthrough——树莓派单臂软路由折腾记 | Yesterday17's Blog Chaos; Child 汉化补丁 神秘编码探索 | Yesterday17's Blog 镣铐与舞蹈——个性与共性之迷思 | Yesterday17's Blog Go 学习笔记 02 - 找准 io 之道 | Yesterday17's Blog NAT Slipstreaming v1 原理浅析 | Yesterday17's Blog 绕过「9-nine-」的 CDKEY 验证——KrkrPlugin 正(?)向实录 | Yesterday17's Blog 静流的青春纪念册——「サクラノ刻 -櫻の森の下を歩む-」体验版感言 | Yesterday17's Blog Project Anni 之旅 01 - 从 clap-builder 到 derive | Yesterday17's Blog [Google CTF 2021] CPP WriteUp | Yesterday17's Blog 获取 アソビステージ 的实际播放链接 | Yesterday17's Blog 90 行 Rust 代码实现 AsyncTeeReader | Yesterday17's Blog 或许还算有价值一读的文章列表 | Yesterday17's Blog 从零开始的 Seedbox 之旅 | Yesterday17's Blog [随笔]技术型博客行文迷思(1) | Yesterday17's Blog 浅谈 git fetch 的工作方式 | Yesterday17's Blog 『ソーサレス*アライヴ! ~the World's End Fallen Star~』通关感想" | Yesterday17's Blog Rust std::fmt 格式语法简述 | Yesterday17's Blog 日亚修改居住国的解决方案 | Yesterday17's Blog [Windows/Linux] GC553 的 Switch 完美采集之路 | Yesterday17's Blog 【翻译】Subtyping and Variance / 子类型与变型 | Yesterday17's Blog Berd's Red Envelope 2021 WriteUp | Yesterday17's Blog 【中英对照】ALSA 音频 API 使用教程/A Tutorial on Using the ALSA Audio API | Yesterday17's Blog 从 cue_scanner.l 看 CUE Sheet 的词法单元 | Yesterday17's Blog Postman 历史记录导出的解决方案 | Yesterday17's Blog 《恋爱绮谭 不存在的夏天》通关感想 | Yesterday17's Blog [微机实验/TD-PITE] 微机接口综合实验 | Yesterday17's Blog [微机实验/TD-PITE] 键盘扫描及数码管显示实验 | Yesterday17's Blog [微机实验/TD-PITE] 数码管显示实验 | Yesterday17's Blog Airsonic Advanced+Google Drive+Caddy 部署纪实 | Yesterday17's Blog X-NUCA 2020 - hellowasm 题解 | Yesterday17's Blog [微机实验/TD-PITE] 8251 串行接口实验 | Yesterday17's Blog Node.js child_process.fork 与 env 污染 RCE | Yesterday17's Blog EP.01 「夜の向日葵」 | Yesterday17's Blog [微机实验/TD-PITE] 8254 定时/计数器实验+选做实验 | Yesterday17's Blog [JLU CTF/2020] babywasm WriteUp | Yesterday17's Blog PHP 反序列化与经典利用 | Yesterday17's Blog WebAssembly 逆向简述 | Yesterday17's Blog 『彼女、お借りします』一期完结点评 | Yesterday17's Blog [微机实验/TD-PITE] D/A 转换实验+选做实验 | Yesterday17's Blog [微机实验/TD-PITE] A/D 转换实验+选做实验 | Yesterday17's Blog 开源项目申请 JetBrains Open Source License 简单流程 | Yesterday17's Blog 微软拼音与 JetBrains 搜索快捷键冲突的解决方案 | Yesterday17's Blog [微机实验/TD-PITE] 8259 中断优先级实验+选做实验 | Yesterday17's Blog IFTTT 测试(续) | Yesterday17 IFTTT 测试 | Yesterday17's Blog [微机实验/TD-PITE] 存储器扩展实验+选做实验 | Yesterday17's Blog 新版 GCC 针对 -fdump-translation-unit 的替代方案 | Yesterday17's Blog 一次 HSTS 策略配置的排错之旅 | Yesterday17's Blog YukiNative 踩坑记——Windows 的消息队列 | Yesterday17's Blog 我是我自己——论获取 HTTPS 证书时的验证步骤 | Yesterday17's Blog 【设计文档】对 PUG 的大规模设计修订(1.1) | Yesterday17's Blog GS65 折腾记(2)加装固态,分区,Grub2 引导 Manjaro LiveCD | Yesterday17's Blog 「さくら、もゆ。」的空白字体列表——一次逆向问题定位过程实录 | Yesterday17's Blog GSuite 探索篇(1)使用 Service Account 向 Google Drive 传输文件 | Yesterday17's Blog 『サクラノ詩 -櫻の森の上を舞う-』通关感想 | Yesterday17's Blog 《ATRI -My Dear Moments-》通关感想 | Yesterday17's Blog [工具][VSCode 扩展] AegiKit——方便 Aegisub 使用的工具箱 | Yesterday17's Blog 贝塞尔曲线、字体矢量化与曲线运算 | Yesterday17's Blog
NAT 类型初探 | Yesterday17's Blog
Yesterday17 · 2020-06-28 · via Yesterday17's Blog

最近被人抓去研究 Switch 联机的 NAT 类型,经过一晚上的折腾,总算有了点收获,这里就来总结一下好了(

ToC

  • NAT?
  • 圆锥NAT
    • 完全圆锥型(Full Cone
    • 受限圆锥型(Address Restricted Cone)
    • 端口受限圆锥型(Port-Restricted cone NAT)
    • 小结
  • 对称型 NAT(Symmetric NAT)
  • 检测 NAT 类型
  • 结语

NAT?

我们知道,由于 IP 地址短缺的问题日益严重,为了缓解这个问题,NAT 开始流行起来。NATNetwork Address Translation 的缩写,意为网络地址转换。

NAT 有两种基本的类型,最为简单的就是 IP 地址的一对一映射,这种 NAT 被称为 Basic NAT。但这种 NAT 并不能解决上面所说的问题,因此我们实际遇到的情况很少。

而另外一种就相当普遍了。基于目前我们使用的所有传输层协议基本都是 TCPUDP,而作为客户端一般很难将 65535 个端口耗尽的特点,出现了以端口映射为原理的 NAT,称作 NAPT。这种 NAT 的一个特点就是端口可能会因为大量的连接而耗尽,因此需要辅以一些对客户端的限制以保持端口资源的持续可用。

圆锥NAT

出于不同需求,NAT 也有着不同的类型。

NAT 的类型主要分为两类:圆锥型和对称型。圆锥型的特点是:只根据源地址和源端口这两个因素分配外部 IP 和端口。

换句话说,一旦客户端尝试用 12345 端口访问网络,那么之后再用 12345 端口访问网络时,分配到的还是原来的外部 IP和端口。

根据不同的安全需要,圆锥型 NAT 分为以下三类:

完全圆锥型(Full Cone

Full Cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Full_Cone_NAT.svg/400px-Full_Cone_NAT.svg.png
Full Cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Full_Cone_NAT.svg/400px-Full_Cone_NAT.svg.png

完全圆锥型 NAT,又称一对一 NAT,其特点就是完全的一对一。一个端口一旦分给了一个人,那它就是你的,谁都可以访问。

这个特性对于点对点通讯而言是至关重要的,因为这样就相当于 NAT 不存在了。因此对于使用了 UDP 的游戏联机,我们都希望自己的 NAT 类型是 Full Cone,这样一旦连接建立,那么那个端口就代表我们,因而任意的其他用户就可以通过那个端口与我们连接了。

正如同上文描述的一样,这种 NAT 对源主机的 IP 地址和端口没有限制

受限圆锥型(Address Restricted Cone)

Address Restricted Cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Restricted_Cone_NAT.svg/600px-Restricted_Cone_NAT.svg.png
Address Restricted Cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Restricted_Cone_NAT.svg/600px-Restricted_Cone_NAT.svg.png

这种 NAT 的特点是:服务端和客户端通信的前提是客户端和服务端通信过。换句话说,也就是没有跟客户端通信过的主机无法使用这个端口。

如图所示,图中 Server1 是可以和 Client 正常通信的,而 Server2 则不行。可以看到 Server2 在尝试通信时遇到了一面“墙”,即图中箭头坐标的黑色竖线。

这种 NAT 实质上是限制了源主机的 IP,对源主机的端口没有限制。可以看出,相比于 Full Cone,这种 NAT 更加安全;但作为安全的代价,它没有 Full Cone 那么灵活。

端口受限圆锥型(Port-Restricted cone NAT)

Port-Restricted cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Port_Restricted_Cone_NAT.svg/600px-Port_Restricted_Cone_NAT.svg.png
Port-Restricted cone NAT https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/Port_Restricted_Cone_NAT.svg/600px-Port_Restricted_Cone_NAT.svg.png

这种 NAT 光看图的话看起来可能有点不明所以,但其实是相对于 Address Restricted Cone 又增加了一条限制:只能接收从与其通信主机的通信端口发来的数据。

图中的 Server1 尝试用另一个端口(也就是下面的圆点)向 Client 发送数据,在这种 NAT 下这是做不到的。

这种 NAT 同时限制了源主机的 IP 和端口

小结

可以看到,从 Full ConePort-Restricted Cone,这三种 NAT 的安全策略是逐渐收紧的,但与之对应的,灵活性也是依次收紧的。

但尽管灵活性收紧,但圆锥型的 NAT 还是都可以做到 P2P 的,但下面介绍的对称型 NAT 就不是这样了。

圆锥为什么称作圆锥呢?可能是因为内部主机的多个请求对应到同一个外部 IP 和端口?也有可能是所有的服务器返回都从一个端口像圆锥一样涌进目标主机?没有考证到来源可能就是这样的吧(笑)

对称型 NAT(Symmetric NAT)

600px-Symmetric_NAT.svg.png (600×270)
600px-Symmetric_NAT.svg.png (600×270)

最后就是对称型 NAT 了。这种 NAT 和之前的三种有着本质性的区别,也就是“对称”。对称的话需要考虑的东西就多了:不仅是源 IP 和源端口,还要考虑目标 IP 和目标端口。

对「源 IP、源端口、目标 IP、目标端口」这样一个四元组,对称型 NAT 会为这个连接专门分配一个外部 IP 和端口;而当任何一项发生改变时,对称型 NAT 又会分配不同的外部 IP和端口组合。

而为了安全性,这种 NAT 也只能接收你访问的服务器发回的内容。这样的分配方式对于每个连接都好像是对称的,我想这就是它的名字的来源吧。

检测 NAT 类型

我们知道,NAT 也就意味着我们没有属于自己的公网 IP,因此各种需要公网 IP 的协议也就无法正常使用了。不过好在我们有圆锥型 NAT,而这种类型的 NAT 由于其「可复用外部 IP/端口」的特性,可以实现一定的内网穿透。而对称型 NAT 就比较麻烦了,两个对称型 NAT 下的设备是一定无法实现 P2P 的。

那我们又怎么知道我们在 NAT 下,或者换句话说,怎么知道我们在哪种 NAT 下呢?于是就出现了 STUN 协议。

STUNSession Traversal Utilities for NAT 的缩写,它允许位于 NAT(或多重 NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的 NAT 之后以及 NAT 为某一个本地端口所绑定的 Internet 端端口。这些信息被用来在两个同时处于 NAT 路由器之后的主机之间创建 UDP 通信。该协议由 RFC 5389 定义。[5]

下面这张图是我从维基百科 STUN 的页面拿到的,简单翻译了一下。源地址是 [6]

STUN 使用的算法
STUN 使用的算法

观察图中各个圆角矩形,分为了绿色、黄色和红色三种。绿色和黄色都可以实现 P2P,而红色一定无法实现 P2P(想一想,为什么?)。

结语

本文简单地整理了一下各种 NAT 的特点,以及 NAT 类型发现:STUN 协议的基本探测过程。

毕竟是初探,其实全文自己的理解还是比较少的毕竟现在其实也没太大需求,等之后吧(逃。就当是学习笔记好了(笑)