服务器网络参数配置
一台服务器装完系统、还没起任何服务之前,有一组网络参数必须先摆对:主机名与 FQDN、/etc/hosts 与本机解析、解析器指向、地址与默认路由、监听面与时钟。这些参数单看都琐碎,但它们是后面每一个服务章节的地基——Nginx 绑不上地址、Samba 报不出自己的名字、邮件服务器证书校验失败,追到根上常常不是服务配错,而是这台机器的"身份与门牌"没对齐。鸟哥把这一章放在服务器篇最前面,用意正在于此:先让机器在网络里有清晰的身份,再谈对外服务。本页把它改写成一份上线前检查单——每一节先讲机制,再给自查命令与判读要点,最后一节汇总成一张可打印的表;持久化配置(Netplan/networkd/nmcli 三系怎么写进磁盘)在网络配置基础已有专页,故障发生后的分层排查方法论见网络故障排除,本页不重复,只做"上线前把参数摆对"这一件事。
内容参考自 Arch Wiki 与 systemd 官方文档(概念框架参考鸟哥的私房菜),见文末参考资料。
学习目标
- 理解主机名、FQDN 与
/etc/hosts三者的关系,以及为什么 Samba/Kerberos 类服务对此敏感 - 分清
resolv.conf的三种管理者(systemd-resolved、NetworkManager、传统直写),会判断自己机器属于哪一态 - 会用
ip -br addr与ip route快速判读地址、前缀与默认路由的健康状态 - 养成"先看监听面再放行防火墙"的顺序习惯,分清
0.0.0.0与指定地址监听的安全含义 - 掌握一张上线前的网络参数检查单,把排障分层法提前到部署阶段
1. 为什么参数先于服务
服务配置是"我打算提供什么",网络参数是"我在网络里是谁"。前者建立在后者之上:一个服务要监听地址,就得先有地址;要校验客户端证书的时间窗口,就得先有时钟(NTP 时间服务);要让同侪用名字找到自己,就得让本机解析器能回答自己的名字。参数错一层,服务层的一切调试都是在错误的地基上盖楼——这也是网络故障排除把"本机"放在排查第一段的原因,本页只是把同样的顺序从"故障后"挪到"上线前"。
检查单思维的价值在于便宜。上线前花五分钟逐项核对,成本以分钟计;投产后再排这类问题,成本以小时计,还叠加了"服务已经有人用"的变更压力。这与改 DNS 前先降 TTL 是同一种保守变更观:在问题最便宜的时刻拦截它。下面各节按检查单的固定顺序展开:身份(主机名与 hosts)→ 解析(resolv 与 nsswitch)→ 地址与路由 → 监听面,最后汇总成表。
2. 主机名与身份
2.1 主机名的三个层次
$ hostnamectl
Static hostname: web01
Icon name: computer-server
Chassis: server
Machine ID: 5f3c2a1b8e9d4c6f...
Boot ID: 3a7b9c...
Operating System: Debian GNU/Linux 12 (bookworm)
$ hostname -f
web01.example.comhostnamectl 的 Static hostname 是内核视角的机器名(uname -n 同源),hostname -f 给出的 FQDN 则是"内核名 + 域名"拼出来的解析结果——注意这个关键差别:FQDN 不是独立配置项,它是拿静态主机名去问解析器(先 /etc/hosts 后 DNS,顺序由 nsswitch.conf 决定)得到的答案。所以"主机名对了但 FQDN 不对"几乎总是 hosts/DNS 侧的问题,改 hostnamectl 无济于事。
修改主机名一条命令,三系通用:
$ sudo hostnamectl set-hostname web01三系差异集中在"谁可能在别处也记了名字":Debian/Ubuntu 旧教程里的 /etc/hostname 直改法仍有效(systemd 兼容读取),但 hostnamectl 是正路;RHEL/Rocky 的 hostnamectl 行为一致,额外注意 /etc/sysconfig/network 里的 HOSTNAME= 是前 systemd 时代遗物,改它不生效;Arch 无额外文件,hostnamectl 即全部。云主机还有一个常见干扰:云镜像的 cloud-init 在首次启动时会按实例名重设主机名,改完名字重启被"改回去",先 systemctl status cloud-init 确认它是否在管这件事。
2.2 /etc/hosts 与 FQDN 的对齐
# /etc/hosts
127.0.0.1 localhost
192.168.56.10 web01.example.com web01推荐写法是本机 IP 一行同时给 FQDN 与短名,FQDN 在前——解析器对一行里的多个名字按出现顺序应答 hostname -f。两个高频错误:把 FQDN 挂在 127.0.0.1 上(本机自解析能用,但其他机器用真 IP 反查时对不上,某些服务广播的地址会变成 loopback);只写短名不写 FQDN(hostname -f 拼不出域名,退化为返回短名)。
验证用 getent 而不是 ping——它走的正是 nsswitch 的解析路径,不带 ICMP 依赖:
$ getent hosts web01.example.com
192.168.56.10 web01.example.com
$ getent hosts "$(hostname -f)"
192.168.56.10 web01.example.com2.3 为什么有些服务对身份敏感
Samba 与 Kerberos 这类协议在握手时互报 FQDN,并用名字反查地址做双向核对:本机解析器答不出自己的名字、或反查(dig -x 192.168.56.10)与正查不一致,轻则告警重则拒绝服务。Postfix 的 HELO 名、TLS 证书的 SAN 字段同样与 FQDN 挂钩。上线前把"正查得地址、反查得名字、两边一致"这条闭环验掉,是这类服务排障里最便宜的一步——本页检查单第 6 节把它列为固定一项。
3. 解析路径自查
3.1 resolv.conf 的三种管理者
/etc/resolv.conf 在现代发行版上有三种存在形态,先判断自己处于哪一态,再谈修改——对着 systemd-resolved 管的文件手改,重启或重连后被改回去,是新手最常见的一坑:
| 形态 | 识别特征 | 谁在写它 |
|---|---|---|
| resolved stub | nameserver 127.0.0.53,文件头有 Generated by systemd-resolved 注释 | systemd-resolved(上游服务器在别处配) |
| NetworkManager 托管 | 文件头标注 NetworkManager | NM 按连接配置(nmcli 的 dns 字段)生成 |
| 传统直写 | 无生成注释,nameserver 直指真实服务器 | 管理员手工(或云镜像的 cloud-init/dhcp 客户端) |
三系默认差异:Ubuntu 桌面与服务器默认跑 systemd-resolved(stub 形态);RHEL/Rocky 默认 NetworkManager 托管;Arch 最小安装则常是传统直写、由用户自选。判断动作是通用的:
$ cat /etc/resolv.conf | head -3
# This is a run-time file managed by systemd-resolved...
nameserver 127.0.0.53
$ resolvectl status | head -12
Global
Protocols: -LLMNR -mDNS +DNSOverTLS DNSSEC=no/supported
resolv.conf mode: stub
Current DNS Server: 192.168.56.2
DNS Servers: 192.168.56.2 223.5.5.5resolvectl status 的判读要点:resolv.conf mode 告诉你 stub 与否;DNS Servers 才是真实上游(stub 地址 127.0.0.53 只是本地代理);+DNSOverTLS 标记上游是否加密(内网 DNS 一般没有,属正常)。要改真实上游,在 resolved 形态下用 resolvectl dns 临时改、或改 resolved.conf/对应连接配置持久化——细节见网络配置基础第 5 节。
3.2 nsswitch 的顺序语义
# /etc/nsswitch.conf(hosts 行)
hosts: files dns myhostnamefiles 在 dns 前,意味着 /etc/hosts 命中就不再查 DNS——这是"hosts 写了却不生效"类问题的第一怀疑点之外的另一半:如果顺序里 files 不在前(少见但存在历史配置),hosts 写得再对也会被 DNS 覆盖。myhostname 模块保证无论如何都能解析本机静态名,是发行版默认加的兜底。改动 nsswitch 属于低频操作,改后用 getent hosts 实测生效即可,无需重启服务。
3.3 自查动作
$ resolvectl status | grep -A2 "Current DNS" # resolved 形态:看真实上游
$ dig +short example.com @223.5.5.5 # 绕开本机配置,验上游链路
$ dig +short example.com # 走本机解析器,两边对比两条 dig 对比是解析路径的分段法:@上游 通而本机不通,问题在本机配置(resolv.conf 形态、nsswitch、resolved 状态);两边都不通,问题在上游或网络层。这与网络故障排除第三段的 DNS 分段一脉相承。内网自建 DNS 的场景,上游应指向自己的 BIND——配置与排错见DNS 服务器。
4. 地址与默认网关
4.1 两条自查命令的判读
$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
ens33 UP 192.168.56.10/24 fe80::20c:29ff:fe5a:8f12/64
$ ip route
default via 192.168.56.2 dev ens33 proto dhcp metric 100
192.168.56.0/24 dev ens33 proto kernel scope link src 192.168.56.10 metric 100ip -br addr 一屏看全:接口状态必须 UP,地址带前缀长度(/24 漏写成 /32 是静态配置的经典笔误,表现为"能 ping 同段、ping 不通网关外")。ip route 的判读要点:默认路由 default via 应当有且仅有一条主用;第二条直连路由由内核按前缀自动生成,scope link 表示同网段直达,属正常。metric 100 是优先级字段,两条默认路由并存时按 metric 小者胜——这正是多网卡机器"时通时断"类问题的第一检查点。
4.2 多网卡与源地址选择
双网卡(如业务网 + 管理网)服务器有三条纪律。其一,默认路由只在一个网段上给,另一个网段只配直连或明细路由,避免两条默认路由互踩;确需并存(多出口),用 metric 显式分出主备。其二,理解源地址选择:本机发起连接时,内核按"路由选出口网卡,再用该网卡上的地址做源地址",所以"对方防火墙只放行业务段地址"而你的流量从管理段出去时会被拒——应用层可用 IP_PKTINFO 显式指定源地址,排障层用 ip route get 对端IP 看内核实际选路。其三,网卡命名:现代发行版默认 predictable names(ens33/enp0s3 按总线槽位命名),云镜像或老脚本假定 eth0 的场合才用 systemd 的 .link 文件或内核参数 net.ifnames=0 改回——改命名是重装级变更,上线前定好,不要投产后动。
4.3 IPv4 与 IPv6 并存
$ ip -6 route | head -3
default via fe80::1 dev ens33 proto ra metric 1024 pref mediumv6 的默认路由常来自 RA(路由通告)而非静态配置,proto ra 字段暴露来源。"v4 全通、v6 悄悄断"的典型场景:服务域名有 AAAA 记录,客户端优先试 v6,RA 失效导致 v6 默认路由消失,表现为"有的客户端慢、有的不通"(取决于各自 v6 状态)。自查动作就是上面临两条命令的 v6 版本。确不需要 v6 时,明确禁用(内核参数或连接配置 ipv6.method disabled)比留着半残状态好——禁用是确定性,半通是隐患。
5. 防火墙与监听面的先手检查
服务起之前先想清楚两件事:它该监听哪个地址、放行哪些来源。本节只给"检查面"的动作,规则怎么写在防火墙(ufw/firewalld/nftables 三系),网关与 NAT 场景见路由与 NAT。
监听面的检查命令与判读:
$ ss -tlnp
State Recv-Q Send-Q Local Address:Port Process
LISTEN 0 128 127.0.0.1:6379 users:(("redis-server",pid=812))
LISTEN 0 511 0.0.0.0:80 users:(("nginx",pid=940))0.0.0.0 表示监听所有 v4 地址(对外服务通常如此,但 Redis/数据库类必须有绑定地址或防火墙兜底——上例 Redis 绑 loopback 是安全姿态);127.0.0.1 只本机可达。上线前对照设计逐端口核对这三列,是"服务绑错面"类事故(绑了 loopback 以为对外可用、绑了 0.0.0.0 本不该暴露)的唯一廉价拦截点。核对完监听面,再在防火墙上按端口与来源放行——顺序很重要:先知道"该开多大口"再开口,与先开口再看服务趴在哪,是两种安全观。
6. 上线检查单
把前五节收敛成一张可打印的表。每行三列:查什么、怎么查、应看到什么。逐行走完即完成一次上线前网络面验收:
| # | 项目 | 验证命令 | 应看到 |
|---|---|---|---|
| 1 | 主机名 | hostnamectl --static | 与规划一致,无残留默认名 |
| 2 | FQDN 闭环 | getent hosts "$(hostname -f)" | 返回本机真实 IP(非 127.0.0.1) |
| 3 | 反查一致 | dig -x 本机IP +short | 返回自己的 FQDN |
| 4 | hosts 内容 | cat /etc/hosts | 真实 IP 行含 FQDN 与短名,FQDN 在前 |
| 5 | 解析形态 | ls -l /etc/resolv.conf; resolvectl status | 明确知道谁在管;上游指向规划的内网 DNS |
| 6 | 地址与前缀 | ip -br addr | 接口 UP,地址与前缀符合规划 |
| 7 | 默认路由 | ip route | 有且仅有一条主用 default,via 正确网关 |
| 8 | v6 状态 | ip -6 route | 要么明确的 v6 路由,要么明确禁用,无半残 |
| 9 | 同网段可达 | ping -c2 网关IP | 0% loss |
| 10 | 监听面 | ss -tlnp | 逐端口与设计一致,无计划外监听 |
| 11 | 时钟 | timedatectl | NTP synchronized: yes(详见 NTP) |
| 12 | 外网解析 | dig +short example.com | 正常返回(验 DNS 链路全通) |
第 9 步只验到网关是刻意的:网关之外属网络故障排除的分层领地,上线检查单的边界是"本机参数全部正确"。把这张表存进部署仓库、纳入交付流程,等于给每台新机器配了一位不知疲倦的初检员——检查单的价值不在条目多寡,而在"每次都查同样的事、查的标准一样"。
7. 常见坑
/etc/hosts 写了域名但服务仍解析失败。 两个根因占绝大多数:nsswitch.conf 的 hosts 行里 files 不在 dns 前(罕见但致命),或 hosts 里只写了短名没写 FQDN,服务按 FQDN 查询时落空。用 getent hosts FQDN 直接复现服务的解析路径,通不过就是 hosts 侧问题,与 DNS 无关。
resolv.conf 被改回去。 先 ls -l /etc/resolv.conf 看是否为符号链接、head -3 看生成注释,判断 resolved stub、NM 托管还是 cloud-init/dhclient 在写,然后去真正的主人那里改——对生成的文件手改,重启、重连网络甚至 DHCP 续租都会把它冲掉。这是"改了不生效"类工单在 DNS 侧的第一根因。
网卡名变了导致服务起不来。 换硬件、迁移云主机后 eth0 变成 ens33,绑定旧名的服务(防火墙规则、bonding、应用配置)集体失效。处置分两层:应急时用 .link 匹配 MAC 固定名字;治本时把所有配置里的名字参数化。命名规则变更的背景(predictable names 解决什么问题)一句话:按固件/总线位置命名,插拔网卡后名字不漂移。
默认路由两条互相踩。 双网卡各自 DHCP 各拿一条 default,metric 相同时内核并不保证稳定选择,表现为路由抖动。处置:只在一个接口保留默认路由,或显式 metric 分主备;静态环境在连接配置里不写网关字段即是"不给默认路由"。
服务绑了 127.0.0.1 以为对外可访问。 症状是本机 curl 全通、外部一律拒绝。ss -tlnp 一眼看穿:监听地址是 loopback。这不是网络问题,是服务配置的绑定地址——但检查动作属于本页第 5 节的监听面核对,上线时逐端口过一遍即可拦截。
IPv6 不通但配置看着全对。 地址有了、服务也监听 [::],但 v6 默认路由来自 RA、上游路由器没发或发了没人收。ip -6 route 里没有 default 行即坐实。要么修复 RA/静态补 v6 路由,要么按第 4.3 节明确禁用 v6——中间态(有地址无路由)留给生产是最差选择。
改了主机名,部分服务还认旧名。 hostnamectl 改的是内核名,读到旧名的服务有两种:启动时缓存了主机名的(重启服务即好),以及证书/配置里写死旧 FQDN 的(属配置问题,回第 2 节把 FQDN 闭环重新走一遍)。Samba/Kerberos 类先跑 hostname -f 确认拼出的新 FQDN 与配置一致再重启,避免把好服务重启进坏状态。
参考资料
- Arch Wiki: systemd-resolved — wiki.archlinux.org/title/Systemd-resolved
- Arch Wiki: Network configuration — wiki.archlinux.org/title/Network_configuration
- Arch Wiki: Network configuration(其中 Checklist 一节为上线检查单的思想来源) — wiki.archlinux.org/title/Network_configuration
- systemd 手册 — man hostnamectl、man systemd-resolved、man nsswitch.conf
- 鸟哥的私房菜 - 网络参数配置 — linux.vbird.org