/etc/passwd 和 /etc/shadow)的完整性。它会检查文件格式、字段数量、用户和组的存在性以及一致性。
pwck 是 "password check" 的缩写,用于检查用户认证文件的完整性。它主要验证以下内容:
/etc/passwd 文件的格式和字段数量/etc/shadow 文件的格式和字段数量pwck 命令通常需要 root 权限才能完全访问 /etc/shadow 文件。普通用户运行可能只能检查 /etc/passwd 文件。
pwck [选项] [passwd [shadow]]
pwck [选项] [文件]
参数说明:
passwd:指定 passwd 文件路径(默认为 /etc/passwd)shadow:指定 shadow 文件路径(默认为 /etc/shadow)| 选项 | 说明 |
|---|---|
-r, --read-only |
只读模式,不修改文件 |
-s, --sort |
按 UID 排序 passwd 和 shadow 文件 |
--root 目录 |
在指定根目录下操作(chroot) |
-q, --quiet |
安静模式,只显示错误信息 |
-h, --help |
显示帮助信息 |
-V, --version |
显示版本信息 |
每行包含7个字段,用冒号分隔:
用户名:密码占位符:UID:GID:用户信息:家目录:登录shell
| 字段 | 说明 | 示例 |
|---|---|---|
| 用户名 | 用户登录名 | root, alice, bob |
| 密码占位符 | x 表示密码在 /etc/shadow 中 | x |
| UID | 用户 ID (0=root, 1-999=系统用户, 1000+=普通用户) | 0, 1000, 1001 |
| GID | 主组 ID | 0, 1000, 1001 |
| 用户信息 | 注释或全名(GECOS 字段) | Alice Smith,,, |
| 家目录 | 用户主目录路径 | /root, /home/alice |
| 登录 shell | 用户默认 shell | /bin/bash, /usr/sbin/nologin |
每行包含9个字段,用冒号分隔:
用户名:加密密码:最后修改:最小天数:最大天数:警告天数:不活动天数:失效日期:保留字段
| 字段 | 说明 | 示例 |
|---|---|---|
| 用户名 | 用户登录名(与 passwd 一致) | root, alice |
| 加密密码 | 加密后的密码,! 或 * 表示锁定,空表示无密码 | $6$salt$hash, !, * |
| 最后修改 | 1970-01-01 起的天数 | 19182 |
| 最小天数 | 密码修改后最少使用天数 | 0 |
| 最大天数 | 密码最多使用天数(到期需修改) | 99999 |
| 警告天数 | 密码到期前多少天开始警告 | 7 |
| 不活动天数 | 密码到期后账户还能使用的天数 | |
| 失效日期 | 账户失效日期(1970-01-01 起的天数) | |
| 保留字段 | 保留 |
检查默认的 /etc/passwd 和 /etc/shadow 文件:
# 以 root 用户运行完整检查
sudo pwck
# 以普通用户运行(只能检查 /etc/passwd)
pwck
# 指定文件检查
sudo pwck /etc/passwd /etc/shadow
# 检查备份文件
sudo pwck /etc/passwd.bak /etc/shadow.bak
输出示例:
$ sudo pwck
user 'ftp': directory '/home/ftp' does not exist
user 'news': directory '/etc/news' does not exist
user 'uucp': directory '/var/spool/uucp' does not exist
user 'gopher': directory '/var/gopher' does not exist
user 'ftp': program '/usr/sbin/nologin' does not exist
pwck: no changes
检查但不修改文件:
# 只读模式,不修改文件
sudo pwck -r
# 安静模式,只显示错误
sudo pwck -q
# 只读且安静模式
sudo pwck -rq
按 UID 排序用户文件:
# 按 UID 排序 passwd 和 shadow 文件
sudo pwck -s
# 排序并检查
sudo pwck -s /etc/passwd /etc/shadow
# 检查排序后的结果
head -10 /etc/passwd
检查常见的用户认证问题:
# 检查无效的登录 shell
sudo pwck | grep "does not exist"
# 检查不存在的家目录
sudo pwck | grep "directory.*does not exist"
# 检查 UID 重复
sudo cut -d: -f3 /etc/passwd | sort -n | uniq -d
# 检查 GID 是否有效
sudo pwck 2>&1 | grep "invalid group"
检查 chroot 环境中的用户文件:
# 检查 /mnt/chroot 中的用户文件
sudo pwck --root /mnt/chroot
# 检查特定目录
sudo pwck --root /backup/system /etc/passwd /etc/shadow
# 错误信息
user 'alice': directory '/home/alice' does not exist
# 修复方法:
# 1. 创建缺失的家目录
sudo mkdir /home/alice
sudo chown alice:alice /home/alice
# 2. 或修改用户的家目录设置
sudo usermod -d /new/home/dir alice
# 3. 如果用户不需要家目录,设置有效目录
sudo usermod -d /tmp alice
# 错误信息
user 'ftp': program '/usr/sbin/nologin' does not exist
# 修复方法:
# 1. 安装缺失的 shell
sudo apt-get install util-linux # 包含 nologin
# 2. 修改用户的登录 shell
sudo usermod -s /bin/bash ftp
# 或设置为有效 shell
sudo usermod -s /usr/sbin/nologin ftp
# 3. 检查有效 shell 列表
cat /etc/shells
# 错误信息
user 'bob': no matching shadow entry
# 修复方法:
# 1. 检查用户是否在 shadow 文件中
sudo grep '^bob:' /etc/shadow
# 2. 如果不存在,从 passwd 同步到 shadow
sudo pwck # 交互式修复,按提示操作
# 3. 手动添加 shadow 条目
sudo vipw -s # 编辑 shadow 文件
# 或使用 useradd 创建
sudo useradd -M -s /bin/bash bob
# 错误信息
invalid line: too few fields
invalid line: too many fields
# 修复方法:
# 1. 检查问题行
sudo awk -F: 'NF != 7 {print NR ": " $0}' /etc/passwd
sudo awk -F: 'NF != 9 {print NR ": " $0}' /etc/shadow
# 2. 手动编辑修复
sudo vipw # 编辑 passwd 文件
sudo vipw -s # 编辑 shadow 文件
# 3. 使用工具修复
sudo pwck # 交互式修复
#!/bin/bash
# userfile_integrity_check.sh - 定期检查用户文件完整性
LOG_FILE="/var/log/userfile_check.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "=== 用户文件完整性检查 - $DATE ===" | tee -a "$LOG_FILE"
# 检查 passwd 和 shadow 文件
echo "1. 运行 pwck 检查..." | tee -a "$LOG_FILE"
sudo pwck -r 2>&1 | tee -a "$LOG_FILE"
echo "2. 运行 grpck 检查组文件..." | tee -a "$LOG_FILE"
sudo grpck -r 2>&1 | tee -a "$LOG_FILE"
# 检查文件权限
echo "3. 检查文件权限..." | tee -a "$LOG_FILE"
ls -l /etc/passwd /etc/shadow /etc/group /etc/gshadow 2>&1 | tee -a "$LOG_FILE"
# 检查重复 UID/GID
echo "4. 检查重复 UID..." | tee -a "$LOG_FILE"
cut -d: -f3 /etc/passwd | sort -n | uniq -d | tee -a "$LOG_FILE"
echo "5. 检查重复 GID..." | tee -a "$LOG_FILE"
cut -d: -f3 /etc/group | sort -n | uniq -d | tee -a "$LOG_FILE"
# 检查无效 shell
echo "6. 检查无效登录 shell..." | tee -a "$LOG_FILE"
while IFS=: read -r user _ _ _ _ _ shell; do
if [ -n "$shell" ] && [ ! -x "$shell" ] && [ "$shell" != "/usr/sbin/nologin" ]; then
echo "警告: 用户 $user 使用无效 shell: $shell" | tee -a "$LOG_FILE"
fi
done < /etc/passwd
echo "=== 检查完成 ===" | tee -a "$LOG_FILE"
#!/bin/bash
# auto_fix_userfiles.sh - 自动修复常见用户文件问题
# 只运行修复模式
FIX_MODE=${1:-dry} # dry 或 apply
echo "用户文件自动修复工具"
echo "模式: $FIX_MODE"
# 1. 运行 pwck 获取问题列表
PROBLEMS=$(sudo pwck -r 2>&1)
# 2. 解析并处理问题
while IFS= read -r line; do
if [[ $line =~ "directory.*does not exist" ]]; then
# 提取用户名和目录
user=$(echo "$line" | grep -o "user '[^']*'" | cut -d"'" -f2)
dir=$(echo "$line" | grep -o "directory '[^']*'" | cut -d"'" -f2)
echo "问题: $line"
if [ "$FIX_MODE" = "apply" ]; then
if [ "$user" = "nobody" ] || [ "$user" = "nogroup" ]; then
echo "跳过系统用户: $user"
elif [ -n "$user" ] && [ -n "$dir" ]; then
echo "修复: 为用户 $user 创建目录 $dir"
sudo mkdir -p "$dir"
sudo chown "$user:$user" "$dir"
fi
fi
elif [[ $line =~ "program.*does not exist" ]]; then
# 提取用户名和程序
user=$(echo "$line" | grep -o "user '[^']*'" | cut -d"'" -f2)
program=$(echo "$line" | grep -o "program '[^']*'" | cut -d"'" -f2)
echo "问题: $line"
if [ "$FIX_MODE" = "apply" ]; then
if [ -n "$user" ] && [ -n "$program" ]; then
# 检查是否有可用的替代 shell
if [ -x "/bin/bash" ]; then
echo "修复: 设置用户 $user 的 shell 为 /bin/bash"
sudo usermod -s /bin/bash "$user"
elif [ -x "/bin/sh" ]; then
echo "修复: 设置用户 $user 的 shell 为 /bin/sh"
sudo usermod -s /bin/sh "$user"
fi
fi
fi
fi
done <<< "$PROBLEMS"
if [ "$FIX_MODE" = "dry" ]; then
echo ""
echo "这是干运行模式,要实际应用修复,请运行:"
echo "sudo $0 apply"
fi
pwck 和 grpck/etc/passwd、/etc/shadow、/etc/group、/etc/gshadowuseradd、usermod、userdel 等工具修改,避免直接编辑文件| 命令 | 检查的文件 | 主要功能 |
|---|---|---|
pwck |
/etc/passwd, /etc/shadow | 检查用户账户完整性,验证用户字段、家目录、shell等 |
grpck |
/etc/group, /etc/gshadow | 检查组账户完整性,验证组字段、组成员等 |
两者都是系统完整性检查工具,建议同时运行以确保用户和组信息的一致性。
可以通过 cron 定期自动运行 pwck 检查:
# 1. 创建检查脚本
sudo nano /usr/local/bin/check_userfiles.sh
# 脚本内容:
#!/bin/bash
LOG="/var/log/pwck_$(date +%Y%m%d).log"
echo "=== pwck 检查 $(date) ===" > "$LOG"
sudo pwck -r >> "$LOG" 2>&1
echo "=== grpck 检查 $(date) ===" >> "$LOG"
sudo grpck -r >> "$LOG" 2>&1
# 2. 设置可执行权限
sudo chmod +x /usr/local/bin/check_userfiles.sh
# 3. 添加到 crontab
sudo crontab -e
# 添加以下行(每月1号凌晨2点运行)
0 2 1 * * /usr/local/bin/check_userfiles.sh
# 4. 检查日志
ls -la /var/log/pwck_*.log
pwck 检查失败的常见处理步骤:
sudo cp /etc/passwd /etc/passwd.backup
sudo cp /etc/shadow /etc/shadow.backup
# 修复家目录
sudo mkdir /home/username
sudo chown username:username /home/username
# 修复无效 shell
sudo usermod -s /bin/bash username
# 修复缺失的 shadow 条目
sudo useradd -M -s /bin/bash username # 重新创建用户
# 或手动编辑
sudo vipw -s
注意: 如果不确定如何修复,可以先在测试环境中尝试,或咨询系统管理员。