服务器公网IP和内网IP有什么区别?使用场景与配置方法

刚接触服务器的人经常会被几个 IP 搞晕:控制台上写的"公网 IP"、登录后在系统里看到的"内网 IP"、还有路由器管理页里的"192.168.x.x"。同样是 IP 地址,有的能在任何地方直接连上,有的只在机房内部或者同一个 VPC 里面有效;有的要额外付费,有的免费还跑得更快。分不清这些概念,很容易出现两类问题:一是把数据库、Redis 这类只该内网访问的服务绑到了公网地址上,白白扩大暴露面;二是明明两台机器在同一个机房,数据同步却绕了一大圈走公网,既慢又费流量。

这篇文章把公网 IP 和内网 IP 的定义、RFC1918 私网地址段、NAT 的工作原理、云服务器上的几种形态(直接公网 IP、弹性 IP、NAT 网关、负载均衡)、内网互通的优势,以及具体的配置方法讲清楚。读完你应该能回答三个问题:我的服务该用哪个地址、怎么让内网机器访问外网、怎么把内网服务安全地暴露出去。

一、公网 IP 与内网 IP 的定义

公网 IP:全球唯一、可直接路由

公网 IP 是由 IANA 逐级分配给各大洲的互联网注册机构,再分配给运营商和云厂商的地址。它的核心特征是在全球互联网上唯一,任何一台联网设备都能直接把它作为目的地址发包,路由设备知道该往哪里转发。

判断一个地址是不是公网 IP,最快的办法是看它是否落在私网保留地址段里。如果不在,且不是下面提到的几类特殊地址,那它基本就是公网地址。

在服务器上查自己用到的地址:

ip -4 addr show                 # 查看网卡上配置的所有 IPv4 地址
ip route show                   # 查看路由表,default 那行是出网走哪张网卡
curl -s ifconfig.me; echo       # 从外部看自己的出网公网 IP

注意第三种情况:curl ifconfig.me 得到的地址,和你网卡上 ip addr 看到的地址可能不一样。这不是出错,而是说明你的机器本身只有内网地址,出网流量经过了 NAT 网关,被转换成了另一个公网地址。

内网 IP:可复用、只在局部有效

内网 IP(也叫私网 IP、私有地址)不要求全球唯一。不同的公司、不同的 VPC 里可以重复使用同一段地址,比如你家路由器用 192.168.1.0/24,你家邻居的路由器也用这段,两者互不影响,因为这些地址永远不会出现在公网的路由表里。

RFC1918 定义了三段 IPv4 私有地址,这是必须记住的内容:

地址段 可用主机数 常见使用场景
10.0.0.0/8 约 1677 万 云上 VPC、大型企业内网,最常见
172.16.0.0/12(172.16–172.31) 约 104 万 企业内网、Docker 默认网桥、K8s 部分网络插件
192.168.0.0/16 约 6.5 万 家用路由器、办公网、小型局域网

除了这三段,还有几类地址虽然不是内网地址,但同样不能作为普通公网地址使用,排查时容易踩坑:

地址段 用途 遇到时说明什么
127.0.0.0/8 本机回环 服务只监听 127.0.0.1 时,外部一律连不上
169.254.0.0/16 链路本地(APIPA) DHCP 没拿到地址时的自动分配,说明网络配置有问题
100.64.0.0/10 运营商级 NAT 保留地址 常见于家宽、4G/5G 网络,说明你被 CGNAT 了
224.0.0.0/4 组播 不是单播地址

169.254.x.x 是一个很有价值的信号。 如果你在服务器上看到网卡拿到了这个段的地址,说明 DHCP 请求没有收到响应,先去查虚拟网络的 DHCP 配置或者网卡是否接对了网络,而不是去查 DNS。

二、NAT:为什么内网地址能上网

内网地址不能直接在公网上路由,那内网机器是怎么访问互联网的?答案是 NAT(网络地址转换)。

SNAT:出方向,多台机器共用一个出口

SNAT(源地址转换)发生在数据包离开网络时。路由器或 NAT 网关把包的源 IP 从内网地址改成自己的公网地址,同时记录一条映射表项;回来的时候再按表项改回去。

因为转换时可以同时改源端口,所以一个公网地址能支撑几万台内网机器同时上网,这项技术叫 NAPT(或 PAT,端口多路复用)。你家宽带里所有手机电脑共享一个出口 IP、云上 VPC 里没有公网 IP 的机器通过 NAT 网关访问外网,用的都是这个机制。

一个直接的推论:SNAT 是内网主动发起的,外部无法主动连进来。 这是 NAT 天然带来的安全属性,也是为什么内网机器"不容易被打"。

DNAT:入方向,把服务暴露出去

DNAT(目的地址转换)解决的是反向问题:外部用户访问网关的公网地址和某个端口,网关把这个请求转发给内网的某台机器。

这就是常说的端口映射。家用路由器里的"虚拟服务器"、云服务器上的 DNAT 规则、Kubernetes 的 NodePort 和 Ingress,本质上都是 DNAT。

# iptables 实现 SNAT:让 10.0.0.0/24 网段通过 eth0 出网
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

# iptables 实现 DNAT:访问本机 8080 转发到内网 10.0.0.10 的 80 端口
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \
  -j DNAT --to-destination 10.0.0.10:80

# 转发链要放行,否则包在 FORWARD 被丢掉(常见坑)
sudo iptables -A FORWARD -d 10.0.0.10 -p tcp --dport 80 -j ACCEPT
sudo iptables -A FORWARD -s 10.0.0.10 -p tcp --sport 80 -j ACCEPT

现代发行版上推荐用 nftables,规则更清晰:

sudo nft add table ip nat
sudo nft 'add chain ip nat postrouting { type nat hook postrouting priority srcnat ; policy accept ; }'
sudo nft 'add chain ip nat prerouting { type nat hook prerouting priority dstnat ; policy accept ; }'
sudo nft add rule ip nat postrouting oifname "eth0" masquerade
sudo nft add rule ip nat prerouting iifname "eth0" tcp dport 8080 dnat to 10.0.0.10:80
sudo nft list ruleset

风险提示:在远程机器上改防火墙和 NAT 规则前,先确认自己有控制台 VNC 之类的带外管理方式。 规则写错导致断连时,这是唯一的救回方式。另外开 ip_forward 是 NAT 生效的前提:

sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-forward.conf
sudo sysctl -p /etc/sysctl.d/99-forward.conf

SNAT 与 DNAT 对比

维度 SNAT DNAT
方向 内网访问外网 外网访问内网
改写字段 源 IP(通常还有源端口) 目的 IP(通常还有目的端口)
发起方 内网主动 外网主动
典型用途 内网机器上网、下载更新 发布网站、远程桌面映射
安全风险 低,外部无法主动入站 高,等于把服务暴露到公网

三、云服务器上的几种公网形态

物理机时代,公网 IP 就是运营商分配的一个地址。到了云上,形态多了起来,选错会影响成本和灵活性。

形态 工作方式 适用场景 特点
固定公网 IP 直接分配给云主机,系统内可见 单机应用、临时测试 简单直观;随实例释放,不利于迁移
弹性公网 IP(EIP) 独立的地址资源,与实例解耦 生产环境、需要保留地址 可随时绑定/解绑到其他实例,系统内通常看不到这个地址
NAT 网关 VPC 级出网设备,做 SNAT 内网机器需要访问外网但不对外服务 多台机器共享出口,按并发连接数和流量计费
负载均衡(CLB/ALB) 对外提供 VIP,转发到后端 多实例、需要高可用 后端实例可以完全不要公网 IP,安全性最好
端口转发/DNAT 网关上做目的地址转换 少量服务需要从公网访问内网机器 粒度细,规则多了难维护

关键区别在系统内是否可见:直接绑定固定公网 IP 时,ip addr 能看到这个公网地址;用 EIP 时,云厂商一般是在网关层做的一对一 NAT,系统里看到的仍然是内网地址,但发包出去源地址会被换成 EIP。用 NAT 网关和负载均衡时同理。

这一点的实际影响是:如果服务监听在 0.0.0.0 上,无论哪种形态都能通;如果只监听在内网地址上,EIP 和负载均衡转发依然能通,但如果监听在公网地址上而该地址不在系统内,服务根本起不来。 所以最稳妥的做法是服务一律监听 0.0.0.0,把访问控制交给安全组和防火墙。

四、内网互通的价值:免费、更快、更稳

这是新手最容易忽略、但收益最大的一条。

内网流量通常免费或极便宜

主流云厂商对同地域、同 VPC 内的内网流量基本不计费或费率极低,而公网出流量是另外计费的。同样是每天同步 500GB 数据,走内网和走公网的账单差距非常大。

内网带宽和延迟都更好

同地域同可用区内的两台云主机,内网延迟通常在 0.1 到 1 毫秒量级,内网带宽可以做到数 Gbps 到数十 Gbps;而走公网要出机房、过运营商网络,延迟取决于物理距离,同城几毫秒、跨城十几到几十毫秒,带宽还受你购买的公网带宽上限限制。

架构上的正确用法

Web 层与数据库层之间走内网。 应用服务器连 MySQL、Redis 时用内网地址,数据库实例完全不要公网 IP。这既省钱又快,还消除了数据库被直接扫描的风险。

跨可用区要注意。 同地域不同可用区之间,内网依然互通,但延迟会升高到 1 到 3 毫秒量级,部分厂商会收取跨区流量费。对延迟极其敏感的场景(比如数据库主从同步),尽量让主备在同一个可用区,或者接受这点延迟。

跨地域不通。 不同地域的 VPC 默认完全隔离,要走公网或者购买专线/对等连接类产品,并做加密。这一点和可用区完全不同,规划时不要想当然。

验证内网是否真的通、走的哪条路:

ping -c 5 10.0.0.10
ip route get 10.0.0.10          # 看这个目的地址走哪张网卡、哪个网关
traceroute -n 10.0.0.10         # 内网互通时应该只有一跳

traceroute 只有一跳且延迟在亚毫秒级,说明确实走的内网直连。如果跳了好几跳还出现了公网地址,说明配置有问题,流量绕出去了。

五、安全层面的对比:暴露面

公网 IP 意味着这台机器在全球任何角落都能被扫描到。经验上,一台有公网 IP 的机器暴露在公网上,SSH 默认端口在几分钟到几小时内就会出现在各类扫描器的日志里,接下来就是持续的密码爆破。

内网 IP 则天然隔离,外部无法主动发起连接。所以安全上的基本原则是:

最小化公网暴露面。 只有真正需要被用户直接访问的服务(Web 的 80/443)才放在有公网入口的位置;数据库、缓存、消息队列、内部管理后台一律只开内网。

用安全组而不是系统防火墙做第一道防线。 安全组是云厂商在虚拟化层做的,即使系统内的防火墙被误关,仍然生效,且是"默认拒绝"模型,配置错了不会把服务暴露出去。

需要远程管理内网机器时,不要给每台机器都挂公网 IP。 更合理的做法是建一台堡垒机或跳板机,只暴露这一台,其他机器从它跳进去。SSH 支持一条命令完成跳转:

ssh -J user@跳板机公网IP user@10.0.0.10
# 或者在 ~/.ssh/config 里配置好,之后直接 ssh web01
Host bastion
    HostName 203.0.113.10
    User ops

Host web01
    HostName 10.0.0.10
    User ops
    ProxyJump bastion

改 SSH 端口前务必先留一条原有连接不断开。 具体操作是:保留当前已登录的会话,新开一个窗口用新端口测试,确认能连上再关旧会话。否则配置错了可能永久失去访问。

六、配置实操

配置静态内网 IP

云主机的内网地址一般由 DHCP 分配,通常不建议手动改。真要改成静态的,各发行版做法不同。

Ubuntu 20.04 及以后用 netplan(/etc/netplan/00-installer-config.yaml):

network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 10.0.0.10/24
      routes:
        - to: default
          via: 10.0.0.1
      nameservers:
        addresses: [223.5.5.5, 119.29.29.29]
sudo netplan try        # 有 120 秒确认窗口,断连会自动回滚,强烈推荐
sudo netplan apply

风险提示:远程修改网络配置有断连风险,一定用 netplan try 而不是直接 apply。

RHEL、Rocky、CentOS 用 NetworkManager:

nmcli con show
sudo nmcli con mod eth0 ipv4.addresses 10.0.0.10/24
sudo nmcli con mod eth0 ipv4.gateway 10.0.0.1
sudo nmcli con mod eth0 ipv4.dns "223.5.5.5 119.29.29.29"
sudo nmcli con mod eth0 ipv4.method manual
sudo nmcli con up eth0

绑定弹性公网 IP

在控制台操作:申请 EIP → 选择目标实例 → 绑定。绑定后从外部验证连通性:

ping -c 4 你的EIP
curl -sS -I http://你的EIP

如果 ping 通但端口不通,问题不在 IP 绑定上,而是安全组或系统防火墙没放行,按后面的排查顺序走。

Windows 上的操作

配置静态地址:

Get-NetIPAddress -AddressFamily IPv4
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.1.10 `
  -PrefixLength 24 -DefaultGateway 192.168.1.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("223.5.5.5","119.29.29.29")

查看出网公网地址:

(Invoke-RestMethod -Uri "https://ifconfig.me/ip").Trim()

Windows 上做端口映射(相当于 DNAT):

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 `
  connectaddress=192.168.1.20 connectport=80
netsh interface portproxy show all
# 删除:netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8080

注意 Windows 上还要保证防火墙放行对应端口,且 portproxy 依赖 IP Helper 服务运行。

快速自查清单

确认一台机器的网络身份,按顺序跑这几个命令就够了:

ip -4 addr show                      # 系统内的地址,通常是内网地址
ip route show default                # 出网走哪个网关
curl -s ifconfig.me; echo            # 外部看到的出网公网地址
ss -lntup                            # 服务监听在哪个地址哪个端口

ss -lntup 的输出里,Local Address:Port 列如果是 0.0.0.0:80 表示监听所有地址;如果是 127.0.0.1:3306,那只有本机能连,外网一律不通——这是"MySQL 连不上"的高频原因之一。

常见问题

系统里看到的 IP 和控制台显示的不一样,是不是有问题?

不是。使用弹性 IP、NAT 网关、负载均衡时,公网地址配置在网关设备上,云主机系统内只有内网地址。这是正常设计,好处是地址可以灵活漂移。要确认出网地址用 curl ifconfig.me。

有了公网 IP,为什么端口还是访问不了?

公网 IP 只解决"路由可达",不等于"端口开放"。还要依次满足:云安全组放行端口、系统防火墙放行、服务进程在监听且监听地址包含公网访问进来的那个地址、应用自身没有做来源限制。四项缺一不可。

内网 IP 可以直接改成公网 IP 吗?

不能。公网地址是稀缺资源,由机构统一分配,不能自己指定。云上要对外服务,只能申请弹性 IP、NAT 网关或负载均衡,由厂商从地址池分配。

两台机器 ping 内网地址不通,可能是什么原因?

按顺序查:两台是否在同一 VPC 和同一地域(跨地域默认不通);安全组是否放行了 ICMP(部分厂商安全组默认拒绝 ICMP,但 TCP 端口可能是通的,这时用 nc 测端口比 ping 更可靠);系统防火墙是否拦了 ICMP;网卡路由是否正确。

把数据库绑到 0.0.0.0 是不是很危险?

取决于它有没有公网入口。如果实例只有内网地址且安全组只放行了内网网段,绑 0.0.0.0 问题不大;一旦有公网 IP 或做了端口映射,绑 0.0.0.0 就等于对全球开放。稳妥做法是绑内网地址配合安全组限制来源段,同时设强密码并禁用默认账号。

NAT 网关和直接给每台机器挂公网 IP,哪个划算?

机器少且都需要对外服务时,直接挂 IP 简单直观;机器多、只有出网需求时,NAT 网关更省地址也更安全,但要注意它有并发连接数上限,高并发出网场景可能被限制。具体计费各家不同,以官方标价为准。

总结

  • 公网 IP 全球唯一可直接路由,内网 IP 可复用且只在局部有效;RFC1918 三段私网地址是 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16,看到 169.254.x.x 说明 DHCP 失败,看到 100.64.x.x 说明处于运营商级 NAT 之下。
  • SNAT 让内网共享出口上网,外部无法主动入站,这是 NAT 天然的安全属性;DNAT 做端口映射把服务暴露出去,是唯一需要谨慎评估的操作。做 NAT 前必须开 net.ipv4.ip_forward,并记得放行 FORWARD 链。
  • 云上优先选弹性 IP 或负载均衡而非固定公网 IP,前者可漂移便于迁移,后者能让后端实例完全不暴露;系统内通常只看到内网地址,这是正常现象,用 curl ifconfig.me 确认出网地址。
  • 同地域同 VPC 内网互通,延迟在亚毫秒到 1 毫秒量级、带宽可达数 Gbps 且流量基本免费,Web 与数据库之间务必走内网;同地域跨可用区延迟升到 1 到 3 毫秒,跨地域默认不通需专线或对等连接。
  • 暴露面控制是网络安全的第一原则:数据库、缓存、管理后台一律不给公网入口,远程管理走跳板机加 ProxyJump,访问控制用安全组(默认拒绝、虚拟化层生效)而不是只依赖系统防火墙。
  • 服务监听地址统一用 0.0.0.0,把访问控制交给安全组;监听在 127.0.0.1 是"外部连不上"的最常见原因,用 ss -lntup 一眼就能看出来。