一、前言
NSCD (Name Service Cache Daemon)是一个系统缓存服务,用于缓存常见的名称服务信息,例如用户、组、主机名和服务。它可以提高系统的性能,减少对名称服务的频繁查询和网络流量,从而加快系统的响应速度。
NSCD在许多 Linux 发行版中默认安装,可以使用 systemctl status nscd
命令检查其运行状态。如果需要启动、停止或重新启动 NSCD,可以使用 systemctl start nscd
、systemctl stop nscd
或 systemctl restart nscd
命令。
如果你在/etc/Hosts指定某个IP解析域名,发现实际请求过程中并不生效,那么这时候就要考虑系统内是否存在nscd进程。
开启nscd的hosts缓存服务后,先会优先查找nscd缓存表,如果缓存表里没有,
/etc/hosts
也没有,再正常发起dns query。
二、安装
某些发行版nscd在系统内内置(GNB Lib C库),如没有内置或采用的是最小化安装的系统(minimal),则可以直接从软件源安装。
发行版 | 安装命令 |
---|---|
Arch/Manjaro | pacman -Sy glibc |
CentOS/RedHat | yum install -y nscd |
Debian/Ubuntu | apt-get install -y nscd |
Gentoo | USE="nscd" emerge –ask glibc |
其中Gentoo注意要加上nscd的USE标记,否则默认不会携带nscd包。
三、nscd.conf参数含义说明
默认配置文件路径在/etc/nscd.conf
,使用grep、sed过滤掉空行和注释后,可以看到默认配置,这里将每一行的含义都分别注释出来:
$ grep -vE '^$|^#' /etc/nscd.conf|sed -nr 's/^\s*//gp
debug-level 0
paranoia no
enable-cache passwd yes
positive-time-to-live passwd 600
negative-time-to-live passwd 20
suggested-size passwd 211
check-files passwd yes
persistent passwd yes
shared passwd yes
max-db-size passwd 33554432
auto-propagate passwd yes
enable-cache group yes
positive-time-to-live group 3600
negative-time-to-live group 60
suggested-size group 211
check-files group yes
persistent group yes
shared group yes
max-db-size group 33554432
auto-propagate group yes
enable-cache hosts yes
positive-time-to-live hosts 3600
negative-time-to-live hosts 20
suggested-size hosts 211
check-files hosts yes
persistent hosts yes
shared hosts yes
max-db-size hosts 33554432
enable-cache services yes
positive-time-to-live services 28800
negative-time-to-live services 20
suggested-size services 211
check-files services yes
persistent services yes
shared services yes
max-db-size services 33554432
enable-cache netgroup yes
positive-time-to-live netgroup 28800
negative-time-to-live netgroup 20
suggested-size netgroup 211
check-files netgroup yes
persistent netgroup yes
shared netgroup yes
max-db-size netgroup 33554432
这些参数说明使用man nscd.conf
就能看到各个参数的详细解释,以下是一些常用参数的释义:
参数 | 说明 |
---|---|
debug-level | debug等级,0表示不输出任何信息。 |
paranoia | 偏执模式,启用偏执模式会导致nscd周期性地重新启动。 |
enable-cache | 开启缓存。 |
positive-time-to-live | TTL缓存时间,默认3600s。 |
negative-time-to-live | 如果Name Service找不到条目,则会将其添加到缓存中并标记为“不存在”。此选项设置从缓存中删除不存在的条目的时间。password和host缓存默认为20秒,group缓存默认为60秒。 |
suggested-size | 设置用于存储缓存项的哈希的大小。由于这是一个散列,正常应该大于预期缓存的最大条目数,并且应该是质数。默认为211个条目。 |
check-files | 定期检查/etc/passwd、/etc/group或/etc/hosts的修改时间(分别用于passwd、group和host缓存),如果文件自上次检查以来已更改,则使缓存无效。 |
persistent | 保留缓存内容,以便在nscd重新启动时提供服务。设置偏执模式时很有用。 |
shared | 用于服务nscd数据库的内存映射与客户端共享,这样客户端就可以直接在其中搜索,而不必每次执行查找时都通过套接字询问守护进程。 |
max-db-size | 用于配置 nscd 缓存数据库的最大大小,单位为Byte。 |
auto-propagate | 会自动将缓存数据的变化广播到其他进程,以确保缓存数据的一致性。 |
threads | 等待请求的线程数量。 |
logfile | 日志文件路径。 |
server-user | 运行用户,即使用哪个用户来运行nscd服务。 |
四、nscd命令选项说明
1、-d, –debug
在当前终端下以debug模式运行,可以看到输出的调试日志。
将会在当前终端运行nscd进程,如果后台已经nscd服务,使用
systemctl stop nscd
暂停下即可。
2、-f, –config-file=NAME
指定nscd的配置文件路径:
nscd -f /etc/nscd.conf
3、-F, –foreground
前台运行,将不会打印任何输出信息到屏幕上。
nscd -F
当然如果你想后台运行也可以配合nohup &或screen来实现,但nscd默认就已经由systemd掌管了,没必要多此一举,这里只是展示各个参数的作用。
4、-g, –statistics
输出当前的配置统计,将输出生效后的各个参数选项配置情况和缓存命中率统计等。
nscd -g
我这里只配置了hosts缓存:
$ grep -vE '^$|^#' /etc/nscd.conf|sed -nr 's/^\s*//gp'
debug-level 4
paranoia no
logfile /var/log/nscd.log
enable-cache hosts yes
positive-time-to-live hosts 3600
negative-time-to-live hosts 200
suggested-size hosts 211
check-files hosts no
persistent hosts yes
shared hosts yes
max-db-size hosts 33554432
可以看到输出信息参数值都能对上:
5、-i, –invalidate=TABLE
使指定的缓存失效,后面可以接:passwd、group、hosts、services、netgroup。
比如使hosts缓存失效:
nscd -i hosts
6、-K, –shutdown
终止nscd进程,此选项并不会影响systemd管理的nscd服务进程。
nscd -K
7、-t, –nthreads=NUMBER
指定运行的的线程数。
nscd -t <线程数量>
在/etc/nscd.conf配置文件则通过threads
选项来指定。
五、用法实战
以缓存hosts为例,其它tables缓存参数没有区别,/etc/nscd.conf配置如下:
debug-level 4
paranoia no
logfile /var/log/nscd.log
enable-cache hosts yes
positive-time-to-live hosts 3600
negative-time-to-live hosts 200
suggested-size hosts 211
check-files hosts no
persistent hosts yes
shared hosts yes
max-db-size hosts 33554432
重启nscd服务:
systemctl restart nscd.service
首先验证下缓存是否可以命中,第一次ping,nscd没有相关的缓存条目,于是加入到缓存中,第二次ping,从缓存拿到结果。
1、check-files
上述配置中,check-files为关闭状态,即当我们修改hosts文件时,也不会触发更新缓存。当域名缓存到nscd后,尝试修改/etc/hosts,并再次访问域名,发现并不会走/etc/hosts:
此时我们把配置文件的check-files选项启用,并重启nscd服务,且清除hosts缓存:
$ cat /etc/nscd.conf
debug-level 4
paranoia no
logfile /var/log/nscd.log
enable-cache hosts yes
positive-time-to-live hosts 3600
negative-time-to-live hosts 200
suggested-size hosts 211
check-files hosts yes
persistent hosts yes
shared hosts yes
$ systemctl restart nscd
$ nscd -i hosts
再尝试看看是否会走/etc/hosts:
结果符合预期,以qq.com为例,nscd进程会监视/etc/hosts,当触发修改后,则将老的缓存条目清除,下次访问时发现缓存qq.com域名,那么先走/etc/hosts,能找到地址,把地址加入缓存。
2、dig、nslookup处理逻辑
这两个命令并不会读取/etc/hosts,也不会走nscd缓存,而是直接向/etc/resolv.conf配置的NS发送dns query。但实际访问域名,会走nscd的缓存,缓存没有再查找/etc/hosts,/etc/hosts没有则正常发起dns查询。
使用getent命令可以测试域名实际在系统中会先解析到哪个地址:
getent <database> <key>
所以,当你发现dig、nslookup解析没有问题,但ping、curl等实际访问域名都是另一个IP,且指定/etc/hosts的情况下也没效果,此时就要考虑nscd缓存,以及check-files的启用状态。
3、抓包验证
- 首先通过
nscd -i hosts
清除缓存条目,之后使用getent或者其它任何访问域名的命令,来触发一次DNS解析拿到A记录(比如下图中的三个IP); - 此时再修改/etc/hosts,由于nscd.conf的check-files是启用状态,检测到/etc/hosts文件变化后,清除qq.com的缓存条目;
- 此时我们使用ping命令再次触发解析,nscd没有qq.com的缓存(前面已经清除qq.com的缓存条目),读取/etc/hosts文件,匹配到192.168.1.100内网地址,nscd将内网地址加入到缓存中;
- 此时执行第二次getent,匹配nscd缓存到qq.com 192.168.1.100,不会再发起A记录的dns query请求,从下图中可以看到整个过程。
六、总结
NSCD的主要作用是缓存名称服务查询的结果,可以加快名称服务查询的速度,查询结果不必每次都从网络或本地DB(/var/cache/nscd)中获取,所以能一定程度上减少对网络和本地数据库的负载。也正因为此特性,如果缓存的查询结果过时或不准确,可能会导致应用程序出现错误或安全问题。此外,如果nscd服务出现故障,可能会导致名称服务查询失败或变慢。
同时,nscd可以缓存多种名字服务数据库,包括hosts、passwd、group、services、netgroup等。对于每种数据库,nscd都可以配置其缓存大小、生存时间等参数,以满足不同的需求。
总之,nscd是一个优秀的Name Service缓存守护进程,可以提高系统的名字服务性能,但是在实际应用中需要注意配置参数,避免出现缓存不一致等问题。
附带PDF版本