公网、私网、内网、外网彻底讲清楚:NAT、内网穿透与DDNS实战
1. 先把概念理清楚公网、私网、内网、外网到底在说什么很多人第一次接触这几个词是在配路由器、连 NAS、搭开发环境或者调试服务器的时候。明明感觉自己懂一点网络结果一看到“公网 IP”“内网穿透”“NAT 模式”就懵了。更麻烦的是这几个词在日常交流里经常被混着用不同人说“内网”的时候指的可能完全不是一回事。我自己就踩过这个坑。早些年帮朋友调一台家里的存储设备他说“你从外网连一下试试”我理解成从公网访问结果他其实只是想让我从另一个房间的电脑连过去。两个人鸡同鸭讲了半天最后发现是概念没对齐。所以这篇文章我打算把公网、私网、内网、外网这四个词彻底拆开讲清楚顺便把 NAT、内网穿透、DDNS 这些绕不开的配套概念也一并说透。先给一个最粗的框架方便你建立第一印象公网全球唯一的地址空间任何人都能路由到达。私网专门保留出来、不在公网路由的地址段只能在局部网络里用。内网一个组织或家庭内部的网络通常用私网地址。外网相对“内网”而言的外部网络可能是公网也可能是上级网络。你看公网和私网是地址属性的区分内网和外网是相对位置的区分。这两组概念经常被绑在一起说但本质上不是一回事。搞混这一点后面所有的困惑都从这里来。这篇文章适合谁看如果你是刚入行的运维、后端开发、嵌入式工程师或者只是想把家里的 NAS、开发板、小服务器连起来玩的爱好者那这篇内容基本能覆盖你 90% 的疑问。我会从原理讲到实操从地址规划讲到内网穿透方案选型尽量让你看完就能动手。2. 公网与私网地址层面的本质区别2.1 公网 IP 到底是什么为什么它这么稀缺公网 IP 的本质是“全球唯一且可被路由”。你可以把它想象成现实世界里的门牌号快递员只要知道这个号码就能把包裹送到。互联网上的数据包也一样只要目标地址是公网 IP理论上世界上任何一台联网设备都能把数据发过去。IPv4 的公网地址总量是 2 的 32 次方大约 43 亿个。这个数字在互联网早期看起来很多但架不住设备爆炸式增长。手机、电脑、平板、摄像头、智能音箱、车机全都要地址。于是公网 IPv4 早就分配殆尽了这也是为什么现在家庭宽带拿到的几乎都是私网地址而不是公网地址。这里有个关键点很多人不知道你从运营商那里拿到的“宽带 IP”大概率不是公网 IP。运营商在骨干网和你的光猫之间又做了一层 NAT把你放在了一个更大的私网里。这就是所谓的“大内网”或“运营商级 NAT”。所以你在路由器后台看到的 WAN 口 IP可能是一个 100.64.x.x 开头的地址那是运营商内部使用的保留段不是真正的公网。判断自己是不是公网 IP有个很简单的办法登录路由器看 WAN 口 IP然后去任意一个查 IP 的网站看显示的地址。如果两个一致大概率是公网如果不一致那就是被 NAT 了。这个方法不是 100% 准确但足够日常判断。2.2 私网地址段三个保留区间和它们的设计逻辑私网地址是专门从 IPv4 空间里划出来、不在公网路由的段。RFC 1918 定义了三个区间地址段范围常见用途A 类10.0.0.0/8大型企业、云内网、容器网络B 类172.16.0.0/12中型网络、Docker 默认网段C 类192.168.0.0/16家庭、小型办公室为什么是这三段因为当年划分地址时预留了一部分给“私有使用”避免和公网地址冲突。任何路由器在公网出口都不会转发目标地址是这些段的包所以你在家里用 192.168.1.1隔壁老王也用 192.168.1.1完全不会打架。这里有个实操细节Docker 默认会占用 172.17.0.0/16如果你公司内网恰好也用了 172.17 段就会冲突。我遇到过好几次容器起不来排查半天发现是网段撞了。解决办法是改 Docker 的默认网段在/etc/docker/daemon.json里加{ bip: 172.31.0.1/24, default-address-pools: [ {base: 172.30.0.0/16, size: 24} ] }改完重启 Docker 服务冲突就解决了。这个坑在云服务器上尤其常见因为很多云厂商的 VPC 默认就用 172.16 段。2.3 公网和私网之间怎么通信NAT 的核心作用公网和私网不能直接互通中间必须有个“翻译官”这就是 NAT网络地址转换。NAT 的工作方式你可以理解成公司前台外面的人打电话进来前台根据分机号转接里面的人打出去前台把主叫号码换成公司总机。最常见的 NAT 是SNAT源地址转换也就是你家里的路由器干的事。你的电脑用 192.168.1.100 访问百度路由器把源地址换成自己的公网 IP再加一个端口号做标记百度回包时路由器根据端口号把包转回给你的电脑。整个过程你的私网地址对外是不可见的。还有DNAT目的地址转换用于把外部请求转发到内部某台机器。比如你把路由器的 8080 端口映射到内网 NAS 的 80 端口外部访问公网 IP:8080 就能打开 NAS 页面。这就是常说的“端口映射”或“端口转发”。NAT 带来的一个副作用是外部无法主动发起连接到内部。因为 NAT 表里没有对应的映射记录包不知道该转给谁。这就是为什么家里没有公网 IP 时外面连不进来必须靠内网穿透或者反向连接来解决。3. 内网与外网相对位置带来的理解差异3.1 内网不是“私网”的同义词很多人把内网和私网画等号其实不准确。内网强调的是“位置”私网强调的是“地址属性”。一个内网可以用公网地址一个私网也可以跨多个内网。举个真实场景某公司申请了一段公网 IP内部服务器直接用公网地址互联。从地址看是公网但从网络位置看它们仍然是“内网”因为不对外提供服务外面也访问不到。反过来你家里用 192.168.1.0/24这是私网同时也是你家的内网。所以当你听到“内网”这个词先问一句是相对于谁的内网是相对于公网的内网还是相对于某个上级网络的内网这个上下文决定了它到底指什么。3.2 外网的多重含义从公网到上级网络“外网”这个词更模糊。在家庭场景里外网通常指公网在企业场景里外网可能指公司总部网络、云上 VPC或者任何当前网络之外的地方。我见过最典型的混淆是开发说“这个服务要能访问外网”运维理解成“要能访问公网”结果开发其实只是想访问公司另一个机房的服务。两边都没错但理解不一致最后配置出来的东西就不是想要的。一个实用的判断方法是看路由表。你的设备能到达哪些网段哪些就是“可达的外网”。如果默认路由指向公网网关那外网就是公网如果默认路由指向公司核心交换机那外网就是公司其他网段。3.3 一张表把四个概念彻底分开概念本质判断依据典型例子公网地址属性全球唯一、可路由8.8.8.8、云服务器公网 IP私网地址属性保留段、不可公网路由192.168.1.1、10.0.0.1内网相对位置当前网络内部家庭局域网、公司办公网外网相对位置当前网络外部公网、上级网络、其他机房这张表建议你存下来。以后遇到任何网络问题先按这两组维度定位基本不会跑偏。4. 内网穿透与 NAT 打洞没有公网 IP 时怎么办4.1 为什么需要内网穿透没有公网 IP外部就主动连不进来。但现实需求很多在外面访问家里 NAS、给客户演示本地开发的服务、远程调试嵌入式设备。这些都需要把内网服务暴露出去于是就有了内网穿透。内网穿透的核心思路是由内网主动向外建立连接保持通道外部请求通过这个通道转发进来。因为是由内向外发起的NAT 表里有记录所以能通。这就像你给前台打了个电话说“我一直在线上有找我的人直接转给我”而不是等别人打进来。4.2 常见方案对比frp、ngrok、cpolar、EasyTier方案部署方式是否需要公网服务器适用场景frp自建需要长期稳定、可控性强ngrok托管不需要临时演示、快速验证cpolar托管不需要个人用户、轻量使用EasyTier自建/托管视模式而定组网、多节点互联frp 是我用得最多的。它的原理很简单你在公网服务器上跑 frps在内网机器上跑 frpcfrpc 主动连 frps建立隧道。外部访问 frps 的某个端口流量就通过隧道转到内网。配置也不复杂frps 端一个frps.tomlfrpc 端一个frpc.toml填好地址、端口、token 就能跑。ngrok 和 cpolar 属于托管服务省去了自己买服务器的麻烦但免费版通常有带宽和连接数限制适合临时用。EasyTier 更偏向组网适合多台设备互联不是单纯的端口暴露。4.3 实操用 frp 把内网 Web 服务暴露出去假设你有一台公网服务器1.2.3.4内网有一台机器跑着 Web 服务在 8080 端口。步骤如下第一步在公网服务器下载 frp 并解压编辑frps.tomlbindPort 7000 auth.token your_token_here启动 frps./frps -c frps.toml第二步在内网机器编辑frpc.tomlserverAddr 1.2.3.4 serverPort 7000 auth.token your_token_here [[proxies]] name web type tcp localIP 127.0.0.1 localPort 8080 remotePort 8080启动 frpc./frpc -c frpc.toml第三步外部访问1.2.3.4:8080就能看到内网的 Web 服务了。注意公网服务器的防火墙和安全组要放行 7000 和 8080 端口否则连不上。这个坑我踩过排查了半天以为是 frp 配置问题结果是云厂商安全组没开。4.4 NAT 打洞和 UPnP另一条路除了内网穿透还有 NAT 打洞。原理是双方通过一个公网服务器交换各自的 NAT 映射信息然后尝试直接建立连接。如果 NAT 类型允许就能点对点直连不经过中转速度更快。UPnP 则是让内网设备自动向路由器申请端口映射。很多下载工具、游戏主机都用这个。但 UPnP 有安全风险因为它允许内网程序随意开端口企业环境通常禁用。家庭环境可以用但要清楚开了什么。5. 动态公网 IP 与 DDNS让地址变化不再是问题5.1 动态公网 IP 的现实即使你拿到了公网 IP大概率也是动态的。运营商会定期更换或者重拨后变化。这对需要固定地址的服务很不友好。解决办法就是 DDNS动态域名解析。DDNS 的思路是域名固定IP 变化时自动更新解析记录。你在路由器或内网机器上跑一个 DDNS 客户端定期检测公网 IP发现变化就调用域名服务商的 API 更新 A 记录。这样你始终用域名访问不用关心 IP 变成什么。5.2 实操用脚本实现 DDNS以某域名服务商为例写一个简单的 shell 脚本#!/bin/bash DOMAINnas.example.com RECORD_IDyour_record_id API_TOKENyour_token LAST_IP_FILE/tmp/last_ip.txt CURRENT_IP$(curl -s https://api.ipify.org) LAST_IP$(cat $LAST_IP_FILE 2/dev/null) if [ $CURRENT_IP ! $LAST_IP ]; then curl -s -X PUT https://api.example.com/records/$RECORD_ID \ -H Authorization: Bearer $API_TOKEN \ -H Content-Type: application/json \ -d {\value\:\$CURRENT_IP\} echo $CURRENT_IP $LAST_IP_FILE fi加到 crontab 里每 5 分钟跑一次*/5 * * * * /path/to/ddns.sh这个方案简单可靠适合家庭 NAS 场景。注意 API Token 要保管好别提交到公开仓库。5.3 申请公网 IP 的经验不同地区、不同运营商政策不一样。有的直接给有的要打电话申请有的要升级套餐。我的经验是先打客服电话说明需要公网 IP 用于远程访问态度好一点多数情况能办。如果客服说没有可以试试换时间段再打或者去营业厅问。拿到公网 IP 后记得确认是 IPv4 还是 IPv6。现在很多地区 IPv6 已经普及而且 IPv6 地址充足基本人人都有公网 IPv6。如果你的设备和服务支持 IPv6直接用 IPv6 可能比折腾 IPv4 公网更省事。6. 常见问题与排查技巧实录6.1 排查思路从下往上逐层验证网络问题排查最忌讳瞎猜。我的习惯是从物理层往上查网线、网卡、IP 配置、网关、DNS、路由、防火墙。每一层确认通了再往上走。具体到“外网访问不了内网服务”这个问题按这个顺序查内网机器本身服务是否正常curl localhost:8080试试。内网其他机器能否访问curl 192.168.1.100:8080。路由器端口映射是否配置正确公网 IP 是否真的可达从外部 ping 一下。防火墙、安全组是否放行运营商是否封了对应端口80、443、8080 常被封。6.2 常见问题速查表问题可能原因解决办法外部 ping 不通公网 IP运营商封 ICMP、防火墙拦截换 TCP 测试检查防火墙端口映射无效NAT 回流未开、映射配置错开 NAT 回流核对内外端口DDNS 不更新脚本权限、API 变更手动跑脚本看报错检查 Tokenfrp 连不上安全组、token 不匹配检查端口放行和配置文件Docker 网段冲突与内网网段重叠改 daemon.json 的 bipWSL 代理不生效NAT 模式限制改用镜像网络模式或手动配代理6.3 几个容易忽略的坑NAT 回流很多路由器默认不开 NAT 回流导致内网用公网 IP 访问自己的服务失败。开了之后内网访问公网 IP 也能正确转发。这个在企业环境很常见绿盟等设备上都有相关配置。光猫路由 NAT 模式下的 DNS 延迟光猫同时做路由和 NAT 时DNS 转发可能变慢。解决办法是把光猫改桥接用自己路由器拨号DNS 也由自己控制。WSL 的 localhost 代理问题WSL2 默认 NAT 模式Windows 上的代理不会自动镜像到 WSL。要么改镜像网络模式要么在 WSL 里手动配代理环境变量。内网机器下载依赖慢纯内网环境装 nginx、uv 这些工具要么配内网源要么用离线包。我一般提前在有网的机器上下好再拷进去。7. 内网环境下的开发与部署实践7.1 纯内网安装软件的通用套路纯内网环境没有外网装软件是个麻烦事。通用套路是在有网的机器上下载好所有依赖打包拷进去再本地安装。以 RHEL 6.10 配外网 yum 为例如果完全没外网可以搭一个本地 yum 源。把 ISO 挂载配 repo 文件指向本地路径就能用 yum 装了。aarch64 架构装 nginx 也是类似找对应架构的 rpm 包rpm -ivh安装缺依赖就补依赖。pnpm 项目迁移到内网关键是node_modules和 pnpm store。把 store 一起拷过去配好.npmrc指向内网 registry基本能跑。GitLab 内网安装也是提前下好 omnibus 包装完再配。7.2 内网文件共享与协作内网文件共享有很多方案。简单点用 SambaWindows 和 Linux 都能访问。复杂点用 Nextcloud功能全但部署重。还有 Raidrive 这类工具可以把内网存储挂载成盘符用起来像本地磁盘。如果只是临时传文件起个 Python HTTP 服务最快python3 -m http.server 8000内网其他人访问http://你的IP:8000就能下载。简单粗暴但很有效。7.3 内网安全的基本意识内网不等于安全。内网渗透、横向移动这些攻击手法很常见。基本措施要有内网分段、最小权限、日志审计、定期扫描。内网横向渗透的告警信息通常表现为异常端口扫描、异常登录、异常进程。发现这些要及时排查。别觉得内网就高枕无忧很多大事故都是从内网一台机器被拿下开始的。8. 我个人的一些经验体会折腾网络这些年最大的体会是概念清晰比技术细节更重要。公网、私网、内网、外网这四个词只要你能准确区分“地址属性”和“相对位置”这两个维度后面所有的问题都能自己推导出来。第二个体会是先确认需求再选方案。是要长期稳定还是临时用是有公网服务器还是纯内网是单服务还是多设备组网这些问题的答案直接决定你该用 frp 还是 ngrok该自建还是托管。第三个体会是排查问题要有层次。从物理层到应用层一层层确认别跳步。我见过太多人一上来就怀疑配置结果发现是网线没插好。最后分享一个小技巧家里如果 IPv6 可用优先用 IPv6。现在大部分运营商都给了公网 IPv6地址充足不用 NAT直接就能访问。很多路由器也支持 IPv6 防火墙放行配置比 IPv4 端口映射简单得多。这个方向值得花点时间研究能省掉不少内网穿透的麻烦。