公司服务器从几十台涨到几百台的时候,你会发现最痛苦的不是装系统,而是每台机器都要手动加一遍用户。
今天说 CentOS 7 上配置 NIS 的详细过程。NIS 全称 Network Information Service,是早年 Sun 搞出来的集中账号管理方案,虽然比 LDAP 老,但在内网环境下够简单、够直接,尤其适合那种“我就想让所有 Linux 机器共享同一套用户和密码”的场景。我这次就把服务端、客户端、常见坑完整过一遍,照着做基本能跑通。
1. 内容整体设计与思路拆解
1.1 NIS 能解决什么问题
先想清楚为什么要上 NIS。运维日常里最常见的痛点是:新同事入职,你要在几十台服务器上重复执行 useradd;有人改密码,你得挨台机器去同步;离职要删号,也是一台一台来。这些操作在机器少的时候手动还能忍,机器一多就纯属消耗生命。
NIS 的核心思路就是“集中存储、按需拉取”。所有用户、密码、组的信息集中在 NIS 服务器上,客户端机器启动时通过 ypbind 找到服务器,登录时去服务器查询用户信息,本地不再需要真正创建这个用户。你能在客户端看到 NIS 上的用户并且直接用他的账号登录,这就够了。
1.2 方案选型:为什么不用 LDAP 或直接上 Kerberos
现在很多新人上来就推荐 LDAP,说功能更强大、支持 TLS、能存更多属性。这话没错,但 LDAP 的目录结构设计、schema 扩展、权限模型、证书配置,学习成本相当高。如果只是想让 Linux 集群共享账号密码,NIS 的部署时间大约只需要 LDAP 的五分之一。
平心而论,NIS 的缺点是明文传输、认证机制弱,所以在跨公网环境我绝不推荐。但在一个可信的内网网段里,比如机房内网、办公室研发内网,NIS 作为账号统一方案完全够用,而且排查问题直观——配置文件就那几个,命令就那么几条。选型逻辑说白了就是:场景匹配比功能堆砌更重要。
1.3 整体架构与核心组件
配置 NIS 之前,先把架构捋清楚。整套系统包含三块:
- NIS 服务端:安装 ypserv,负责生成和维护用户数据库的 map 文件,响应客户端的查询请求。
- 绑定客户端:安装 ypbind 和 yp-tools,ypbind 负责自动找到并绑定 NIS 服务器。
- 辅助服务:yppasswdd 允许用户在客户端上修改自己的 NIS 密码,rpcbind 是所有 RPC 服务(NIS 依赖 RPC 传输)的基础,必须先启动。
NIS 服务器可以配置 master/slave,中小规模场景一台 master 就足够。下面的实操就以单台 master 为例。
2. 核心细节解析与实操要点
2.1 NIS 域名与网络规划
很多人第一次接触 NIS 会被“域名”这个名字带偏,以为 NIS 域名就是 DNS 域名。其实它只是一个逻辑分组标识,在同一 NIS 域中的客户端才能看到该域的用户数据。
我的习惯是在规划阶段就定好统一的命名规范,比如内网环境一律使用example.local或nis.yourdomain.com,服务端和客户端必须完全一致。域名不一致是新手最常见的坑,ypbind 怎么都绑不上。
同时建议把 NIS 服务器的 IP 和主机名写成静态对应关系,推荐直接写入每台机器的 /etc/hosts,避免依赖内网 DNS。因为 ypbind 在使用server指令指定服务器时需要解析主机名,如果解析不到就会陷入等待超时。
2.2 理解 map 文件和数据库的概念
NIS 服务端并不是直接读 /etc/passwd 给客户端看的,而是通过make -C /var/yp将这些本地文件编译成二进制的 map 数据库,存放在/var/yp/<NIS域名>/目录下。
这一点必须提前理解,否则后面改用户时会很困惑:明明在服务端改了密码,客户端却还是显示旧密码,原因就是没重新生成 map。map 文件包含 passwd、group、hosts(如果你选择发布)、shadow 等,具体发布哪些由 /var/yp/Makefile 控制。
2.3 端口与防火墙的底层逻辑
NIS 基于 RPC 协议,早期依赖 portmap(rpcbind)来映射端口号。ypserv 本身默认动态使用的端口可能会让防火墙配置比较头疼,但常见的几个服务端口是固定的:rpcbind 111,ypserv 834,yppasswdd 853,ypxfrd 875。
在内网环境,我推荐两种做法:如果机器之间完全可信任,直接在 firewalld 中允许这几个端口;如果网络策略严格,就在/etc/sysconfig/network里给 NIS 服务指定固定端口,再只放行指定端口。后面的实操里我会给出具体的 firewall-cmd 命令。
3. 实操过程与核心环节实现
3.1 服务端软件安装与初始化配置
我用一台 CentOS 7.9 的最小化安装机器作为 NIS 服务器,IP 规划为 192.168.10.10,主机名 nisserver。先安装所需软件包:
yum install -y ypserv yp-tools安装完成后确认服务端程序的版本和路径。CentOS 7 的 ypserv 主程序位于 /usr/sbin/ypserv,辅助命令 ypinit 位于 /usr/lib64/yp/ypinit(64位系统下在 lib64,32位在 /usr/lib/yp/),这个路径在使用 ypinit 时需要注意。
接着设置 NIS 域名。编辑 /etc/sysconfig/network,追加一行:
NISDOMAIN=example.local然后执行以下命令让域名在当前会话立即生效:
nisdomainname example.local确认生效可以执行nisdomainname,输出 example.local 即正常。这个操作顺序不能反:如果先启动 ypserv 再设域名,服务端无法正确识别域,后面 ypbind 很难绑定成功。
接着修改 /etc/ypserv.conf。这个文件控制服务端的访问规则,安全起见我会在文件末尾加一行限制来源网段:
192.168.10.0/24 : * : * : none这行的含义是:来自 192.168.10.0/24 网段的客户端,对任意 map 的查询都不做限制(none 表示不拒绝)。如果你的内网网段不同,把 IP 段替换掉。配置文件修改后重启 ypserv 生效。
3.2 初始化 NIS 数据库(ypinit 的关键操作)
这是整个配置过程中最核心的一步。初始化数据库前,先确保服务器上已有的用户和组信息是最终想要的,因为 ypinit 会把 /etc/passwd、/etc/group、/etc/shadow 等文件编译成 map。
执行初始化命令:
/usr/lib64/yp/ypinit -m执行过程中会提示输入 NIS 服务器的名称,也就是 master 服务器的 hostname:
next host to add: nisserver next host to add:第二行直接按 Ctrl+D 结束即可,因为这里只配置单台 master。如果误输入了错误的主机名,后面生成 map 时可能出现同步错误,需要重新执行 ypinit。
初始化完成后,再手动生成一遍全部 map,确保初始数据是最新的:
make -C /var/yp执行完可以在 /var/yp/example.local/ 目录下看到 passwd.byname、passwd.byuid、group.byname、shadow.byname 等文件。看到这些文件说明数据库生成成功。
3.3 启动服务并配置防火墙
CentOS 7 使用 systemd 管理服务,启动前先把需要的基础服务拉起来:
systemctl enable --now rpcbind systemctl enable --now ypserv systemctl enable --now yppasswdd然后检查监听状态:
rpcinfo -p localhost输出里应该能看到 100004、100009 等程序号对应的 ypserv 和 yppasswdd 服务。如果 rpcinfo 里看不到,说明 rpcbind 启动顺序或域名设置有误,多半是 ypserv 启动失败。
防火墙方面,我在内网测试环境直接放行了核心端口:
firewall-cmd --permanent --add-port=111/tcp firewall-cmd --permanent --add-port=111/udp firewall-cmd --permanent --add-port=834/tcp firewall-cmd --permanent --add-port=834/udp firewall-cmd --permanent --add-port=853/tcp firewall-cmd --permanent --add-port=853/udp firewall-cmd --permanent --add-port=875/tcp firewall-cmd --permanent --add-port=875/udp firewall-cmd --reload如果 production 环境的安全策略更严格,建议先关闭 NIS 各服务的随机端口,给服务固定端口再放行,这部分需要改动系统文件并重载服务,不再展开。
3.4 客户端完整配置过程
我用第二台 CentOS 7 机器做测试客户端,IP 为 192.168.10.20,主机名 nisclient。客户端安装的软件包与服务端不同,需要的是绑定工具和查询工具:
yum install -y ypbind yp-tools注意客户端不需要安装 ypserv,那是服务端程序。yp-tools 提供 ypwhich、ypcat、ypmatch 这些查询命令,调试时一旦绑定不上,全靠它们定位问题。
设置客户端的 NIS 域名,同样写入 /etc/sysconfig/network:
NISDOMAIN=example.local立即生效:
nisdomainname example.local编辑 /etc/yp.conf,手动指定 NIS 服务器。这里有两种写法:直接写 IP 或写主机名。如果写主机名,要确保 /etc/hosts 里有对应记录。我的测试环境直接写 IP 更省事。
domain example.local server 192.168.10.10接下来配置名称服务切换。编辑 /etc/nsswitch.conf,把 passwd、shadow、group 三行改为同时查询本地文件和 NIS:
passwd: files nis shadow: files nis group: files nis顺序很重要。files 在前表示本机用户优先,NIS 作为补充;如果你希望 NIS 用户覆盖本地同名用户,就把 nis 放前面。日常场景我建议 files 在前,更安全——万一 NIS 服务器抽风,本地 root 等关键账号还能用。
这里我再强调一个容易忽略的细节:启动 ypbind 前确认 rpcbind 已启动,否则 ypbind 会因为无法注册 RPC 而绑定失败。
systemctl enable --now rpcbind systemctl enable --now ypbind如果你希望用户第一次登录时自动创建家目录,还要启用 mkhomedir:
authconfig --enablemkhomedir --update这一步需要安装 oddjob-mkhomedir 和相关 pam 模块,否则会报错。执行完该命令后,系统会在客户端本地为 NIS 用户自动创建 /home/用户名 目录。
3.5 功能验证与测试方法
配置完成后,先做绑定验证。在客户端执行:
ypwhich预期输出是 NIS 服务器的主机名或 IP,表示绑定成功。如果返回Domain not bound,说明 ypbind 没有连上服务端。
接着验证数据能正常拉到:
ypcat passwd | grep nistest如果能输出 nistest 用户的信息,说明 passwd map 查询正常。再用 getent 验证系统级查询:
getent passwd nistest ssh nistest@127.0.0.1最后用 SSH 或直接在控制台登录测试是最有说服力的验证方式。我第一次配完 NIS,就是用一个新建的 NIS 用户从客户端 SSH 登录本机,成功进去并且自动创建了家目录才算彻底放心。到这一步,NIS 服务端和客户端的核心链路就通了。
4. 常见问题与排查技巧实录
4.1 问题速查表
配置 NIS 时我踩过的坑不少,这里整理成一张速查表,方便你对照排查:
| 现象 | 可能原因 | 排查命令与解法 |
|---|---|---|
| ypwhich 提示 Domain not bound | NIS 域名不一致、rpcbind 未启动 | 检查nisdomainname,对比服务端与客户端域名;确保 rpcbind 启动 |
| ypbind 启动失败 | 端口被防火墙挡掉 | rpcinfo -p 服务端IP验证 RPC 通路 |
| getent 看不到 NIS 用户 | nsswitch.conf 未配置或 ypbind 未启动 | 检查 /etc/nsswitch.conf 是否含 nis;检查 ypbind 状态 |
| 客户端拿到旧密码 | 服务端修改用户后没重新生成 map | 在服务端执行make -C /var/yp |
| 登录时报 could not chdir to home | mkhomedir 未配置 | 执行authconfig --enablemkhomedir --update,确认 oddjob-mkhomedir 已安装 |
| yppasswd 修改密码失败 | yppasswdd 未启动 | 检查服务端 yppasswdd 状态 |
4.2 域名不生效的坑
NIS 域名是系统级配置,我遇到过一种情况:sysconfig/network 里写了 NISDOMAIN,但重启后域名丢失。这是因为某些 CentOS 7 环境下,network 服务默认不会把 NISDOMAIN 传给内核接口。
稳妥的做法是把域名设置写进开机自启动,例如在 /etc/rc.local 中追加nisdomainname example.local,并确保 rc.local 有执行权限。这个操作不复杂,但在生产环境里能让故障发生率显著降低。
域名不一致还有一个隐蔽场景:你设置域名时敲了不同的后缀,比如服务端是 example.local,客户端多打了一个点,写成 example.local.,绑定就会一直超时。这个连 ypbind 日志都不太看得出,让我当时排查了半个小时,最后用ypwhich -d逐字比对方才定位。
4.3 客户端重启后失联的修复流程
NIS 客户端经常在重启后出现“登录界面一直转圈,卡在验证阶段”的病例。真正原因通常是 ypbind 启动比 network 早,网络还没就绪就尝试绑定,超时失败后系统认为用户验证失败。
遇到这种情况别慌,在单用户模式下先把 /etc/nsswitch.conf 里的passwd: files nis临时改回passwd: files,重启后进入系统,再手动启动 rpcbind 和 ypbind。确认ypwhich正常后再把 nis 加回去。
这个坑我觉得有必要多说一句:NIS 的内网依赖特性决定了它对网络状态极其敏感。有条件的话建议给客户端配 NetworkManager 的在线等待机制,或者用 systemd 的 After= 和 Wants= 约束 ypbind 的启动顺序,避免网络未就绪就抢跑。
4.4 安全加固与运维建议
NIS 是明文协议,这一点不能回避。我能给的建议是在部署前先审视网络边界:只在完全可控、无对外暴露的网段内使用。如果网络环境稍微复杂,建议至少在服务端用 /etc/ypserv.conf 做来源限制,或者干脆考虑 LDAP + Kerberos。
还有几个运维上的小习惯值得养成:
- 服务端所有用户变更操作后,立刻执行
make -C /var/yp,形成肌肉记忆。 - 定期备份 /var/yp 目录,map 损坏时能快速恢复。
- 不要在 NIS 服务器上运行需要频繁修改用户的其他管理软件,避免 map 频繁重建出问题。
- 用系统审计命令定期检查 ypserv 日志,确认没有异常来源的查询请求。
我个人在实际操作中最深的体感是:NIS 本身不难,难的是把“域名、端口、map 生成”这一条链路吃透。只要把这三个环节的底层逻辑理顺,CentOS 7 上配置 NIS 这件事,基本就是照着命令复制粘贴的机械操作。踩过几轮坑之后,我现在配置一套 NIS 主从环境的时间能控制在一小时以内,希望这篇记录也能帮你把时间压到这个量级。