nologin 是 Linux 系统中用于限制用户登录的特殊命令和 shell。它通常用于系统账户或需要禁止交互式登录的场景。
📦 基本概念
- 作为命令 :
/usr/sbin/nologin直接执行时会显示提示信息并拒绝登录 - 作为 shell :
/sbin/nologin或/usr/sbin/nologin在/etc/passwd中指定为用户 shell
🎯 主要用途
- 系统账户安全:防止系统服务账户被用于交互式登录
- 用户账户锁定:临时或永久禁止用户登录系统
- 服务账户管理:为应用程序创建专用但无法登录的账户
💡 核心用法
1. 直接使用 nologin 命令
bash
# 直接运行会显示提示信息并退出
/usr/sbin/nologin
# 查看退出状态码
echo $? # 通常返回 1
2. 在 /etc/passwd 中配置用户 shell
bash
# 查看当前用户的 shell
echo $SHELL
# 查看 /etc/passwd 中的 shell 配置
cat /etc/passwd | grep nologin
# 典型配置示例(在 /etc/passwd 中)
# daemon:x:2:2:daemon:/sbin:/usr/sbin/nologin
# www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
3. 修改用户 shell 为 nologin
bash
# 使用 usermod 命令修改现有用户
sudo usermod -s /usr/sbin/nologin username
# 使用 chsh 命令修改当前用户的 shell(需要密码)
chsh -s /usr/sbin/nologin
# 创建新用户时指定 nologin shell
sudo useradd -s /usr/sbin/nologin -M -r serviceuser
# 验证修改
grep username /etc/passwd
4. 恢复用户登录权限
bash
# 恢复为 bash shell
sudo usermod -s /bin/bash username
# 恢复为 sh shell
sudo usermod -s /bin/sh username
# 恢复为默认 shell(在 /etc/default/useradd 中定义)
sudo usermod -s /bin/bash username
🔧 自定义 nologin 提示信息
1. 创建自定义提示文件
bash
# 创建提示文件(通常位于 /etc/nologin.txt 或 /etc/issue.net)
sudo nano /etc/nologin.txt
示例内容:
===========================================
账户访问被拒绝
===========================================
此账户已被系统管理员禁用。
如需恢复访问权限,请联系 IT 支持部门。
联系电话: 123-456-7890
邮箱: support@example.com
拒绝时间: $(date)
===========================================
2. 配置 nologin 使用自定义消息
bash
# 方法1:使用 -f 选项指定文件(如果 nologin 支持)
/usr/sbin/nologin -f /etc/nologin.txt
# 方法2:修改 nologin 源码重新编译(高级用法)
# 或者使用自定义脚本替代
3. 使用自定义 shell 脚本
bash
# 创建自定义拒绝登录脚本
sudo nano /usr/local/bin/mynologin
bash
#!/bin/bash
# 自定义拒绝登录脚本
cat << 'EOF'
╔═══════════════════════════════════════╗
║ 账户访问已被禁止 ║
╠═══════════════════════════════════════╣
║ 原因:此账户仅用于系统服务 ║
║ 禁止交互式登录 ║
║ ║
║ 如需帮助,请联系系统管理员 ║
║ 邮箱:admin@company.com ║
║ 电话:分机 1001 ║
╚═══════════════════════════════════════╝
EOF
# 记录登录尝试
echo "$(date): 用户 $USER 尝试登录 (来自 $SSH_CLIENT)" >> /var/log/nologin_attempts.log
exit 1
bash
# 设置执行权限
sudo chmod +x /usr/local/bin/mynologin
# 应用到用户
sudo usermod -s /usr/local/bin/mynologin username
📊 nologin 与 /bin/false 的区别
| 特性 | /usr/sbin/nologin |
/bin/false |
|---|---|---|
| 提示信息 | 显示拒绝登录消息 | 无任何输出 |
| 交互性 | 显示消息后退出 | 立即静默退出 |
| 日志记录 | 可自定义消息和日志 | 无日志功能 |
| 用户友好 | 较友好,可说明原因 | 不友好,直接拒绝 |
| 退出码 | 通常为 1 | 0 |
| 典型用途 | 系统服务账户 | 完全禁止任何交互 |
🔍 查看系统中的应用
1. 查找使用 nologin 的用户
bash
# 查找所有使用 nologin 的用户
grep nologin /etc/passwd
# 统计数量
grep -c nologin /etc/passwd
# 显示详细信息
grep nologin /etc/passwd | cut -d: -f1,6,7 | column -t -s:
2. 查看系统账户配置
bash
# 常见的系统账户使用 nologin
grep -E '(daemon|bin|sys|sync|games|man|lp|mail|news|uucp)' /etc/passwd
# 查看服务账户
grep -E '(www-data|mysql|postgres|redis|nginx|apache)' /etc/passwd
⚡ 实际应用场景
场景 1:安全锁定用户账户
bash
#!/bin/bash
# 安全锁定用户账户脚本
USERNAME="$1"
REASON="$2"
ADMIN_EMAIL="admin@example.com"
if [[ -z "$USERNAME" ]]; then
echo "用法: $0 <用户名> [原因]"
exit 1
fi
# 检查用户是否存在
if ! id "$USERNAME" &>/dev/null; then
echo "错误: 用户 $USERNAME 不存在"
exit 1
fi
# 创建自定义提示消息
cat > /tmp/nologin_$USERNAME.txt << EOF
===========================================
账户已被锁定
===========================================
用户名: $USERNAME
锁定时间: $(date)
锁定原因: ${REASON:-"违反安全策略"}
如需解锁,请联系系统管理员:
邮箱: $ADMIN_EMAIL
电话: 400-123-4567
===========================================
EOF
# 移动提示文件到安全位置
sudo mv /tmp/nologin_$USERNAME.txt /etc/nologin_$USERNAME.txt
sudo chmod 644 /etc/nologin_$USERNAME.txt
# 锁定用户账户
echo "正在锁定用户账户: $USERNAME"
sudo usermod -s /usr/sbin/nologin "$USERNAME"
# 可选:同时锁定密码
sudo passwd -l "$USERNAME"
# 记录操作日志
echo "$(date): 用户 $USERNAME 被锁定,原因: ${REASON:-"未指定"}" | sudo tee -a /var/log/user_lock.log
echo "用户 $USERNAME 已被成功锁定"
echo "提示信息保存在: /etc/nologin_$USERNAME.txt"
场景 2:批量创建服务账户
bash
#!/bin/bash
# 批量创建服务账户(使用 nologin shell)
# 服务账户列表
SERVICES=(
"app1:1001:/opt/app1"
"app2:1002:/opt/app2"
"dbbackup:1003:/backup"
"monitor:1004:/var/monitor"
)
echo "开始创建服务账户..."
echo "======================"
for service in "${SERVICES[@]}"; do
# 解析配置
IFS=':' read -r username uid homedir <<< "$service"
echo "创建账户: $username"
# 创建用户组
sudo groupadd -f "$username"
# 创建用户(无登录权限)
sudo useradd \
-r \
-s /usr/sbin/nologin \
-d "$homedir" \
-g "$username" \
-u "$uid" \
-c "Service account for $username" \
"$username"
# 创建家目录并设置权限
sudo mkdir -p "$homedir"
sudo chown "$username:$username" "$homedir"
sudo chmod 750 "$homedir"
# 创建自定义 nologin 消息
sudo tee "$homedir/.nologin.txt" > /dev/null << EOF
此账户 ($username) 是系统服务账户。
禁止交互式登录。
如需管理此服务,请使用:
sudo systemctl status ${username}
sudo journalctl -u ${username}
服务器: $(hostname)
创建时间: $(date)
EOF
echo " - UID: $uid"
echo " - 家目录: $homedir"
echo " - Shell: $(grep "^$username:" /etc/passwd | cut -d: -f7)"
echo "---"
done
echo "服务账户创建完成"
echo "使用以下命令验证:"
echo "grep -E '$(echo ${SERVICES[@]} | tr ' ' '\n' | cut -d: -f1 | tr '\n' '|')' /etc/passwd"
场景 3:检查系统安全配置
bash
#!/bin/bash
# 检查系统账户安全配置
echo "=== 系统账户安全检查 ==="
echo "检查时间: $(date)"
echo ""
# 1. 检查使用登录 shell 的系统账户
echo "1. 使用登录 shell 的系统账户:"
echo "----------------------------------------"
grep -E '^(root|bin|daemon|adm|lp|sync|shutdown|halt|mail|news|uucp|operator|games|gopher|ftp|nobody|systemd-|dbus|polkitd|abrt|rtkit|saslauth|postfix|chrony|sshd):' /etc/passwd | \
grep -v nologin | \
grep -v false | \
while IFS=: read -r user pass uid gid desc home shell; do
if [[ "$shell" != "/usr/sbin/nologin" && "$shell" != "/bin/false" ]]; then
printf "%-15s %-10s %s\n" "$user" "UID:$uid" "$shell"
fi
done
echo ""
# 2. 检查空密码账户
echo "2. 空密码或弱密码账户:"
echo "----------------------------------------"
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
echo ""
# 3. 检查 UID 0 的账户(除了 root)
echo "3. UID 为 0 的非 root 账户:"
echo "----------------------------------------"
awk -F: '($3 == 0 && $1 != "root") {print $1}' /etc/passwd
echo ""
# 4. 检查最近登录的用户
echo "4. 最近登录的用户:"
echo "----------------------------------------"
last -n 10 | head -10
echo ""
# 5. 建议操作
echo "=== 安全建议 ==="
echo "1. 将不需要登录的系统账户 shell 改为 /usr/sbin/nologin"
echo "2. 定期检查 /etc/passwd 和 /etc/shadow 文件权限"
echo "3. 禁用不必要的系统账户"
echo "4. 监控登录失败尝试"
⚠️ 重要注意事项
1. 系统账户管理
bash
# 不应修改的系统账户(通常已配置为 nologin)
# daemon, bin, sys, adm, lp, mail, news, uucp, etc.
# 检查哪些系统账户仍使用登录 shell
grep -E '^[^:]+:[^:]*:[0-9]{1,3}:' /etc/passwd | \
awk -F: '$3 < 1000 && $7 !~ /(nologin|false)/ {print $1 " -> " $7}'
2. SSH 相关配置
bash
# 即使使用 nologin,用户仍可能通过其他方式访问
# 确保 SSH 配置正确
# 检查 SSH 配置
sudo grep -E "^(AllowUsers|DenyUsers|AllowGroups|DenyGroups)" /etc/ssh/sshd_config
# 完全禁止用户 SSH 登录(在 nologin 基础上)
echo "DenyUsers username1 username2" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
3. 权限控制
bash
# 即使使用 nologin,用户仍可能通过其他方式执行命令
# 确保文件权限正确
# 检查用户的 crontab
sudo crontab -u username -l
# 检查用户的 at 任务
sudo atq
# 检查用户的 sudo 权限
sudo grep "username" /etc/sudoers /etc/sudoers.d/*
🔄 相关命令对比
| 命令/Shell | 用途 | 特点 |
|---|---|---|
/usr/sbin/nologin |
拒绝登录并显示消息 | 用户友好,可自定义消息 |
/bin/false |
立即退出,无输出 | 静默拒绝,退出码为 0 |
/bin/true |
立即成功退出 | 用于测试,退出码为 0 |
passwd -l |
锁定用户密码 | 用户无法使用密码登录 |
usermod -L |
锁定用户账户 | 同 passwd -l |
chsh -s |
更改用户 shell | 修改登录 shell |
🎯 最佳实践
- 系统账户 :所有系统服务账户都应使用
nologin或falseshell - 自定义消息:为服务账户提供有用的提示信息
- 定期审计 :定期检查
/etc/passwd中的 shell 配置 - 最小权限:配合适当的文件权限和 sudo 配置
- 监控日志:监控登录尝试,特别是被拒绝的登录
- 备份配置 :修改前备份
/etc/passwd和/etc/shadow
nologin 是 Linux 系统安全的重要工具,合理使用可以有效降低系统安全风险,同时为系统管理提供清晰的账户管理策略。