Linux命令-nologin(用于系统账户或需要禁止交互式登录的场景)

nologin 是 Linux 系统中用于限制用户登录的特殊命令和 shell。它通常用于系统账户或需要禁止交互式登录的场景。

📦 基本概念

  • 作为命令/usr/sbin/nologin 直接执行时会显示提示信息并拒绝登录
  • 作为 shell/sbin/nologin/usr/sbin/nologin/etc/passwd 中指定为用户 shell

🎯 主要用途

  1. 系统账户安全:防止系统服务账户被用于交互式登录
  2. 用户账户锁定:临时或永久禁止用户登录系统
  3. 服务账户管理:为应用程序创建专用但无法登录的账户

💡 核心用法

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

🎯 最佳实践

  1. 系统账户 :所有系统服务账户都应使用 nologinfalse shell
  2. 自定义消息:为服务账户提供有用的提示信息
  3. 定期审计 :定期检查 /etc/passwd 中的 shell 配置
  4. 最小权限:配合适当的文件权限和 sudo 配置
  5. 监控日志:监控登录尝试,特别是被拒绝的登录
  6. 备份配置 :修改前备份 /etc/passwd/etc/shadow

nologin 是 Linux 系统安全的重要工具,合理使用可以有效降低系统安全风险,同时为系统管理提供清晰的账户管理策略。

相关推荐
是阿建吖!1 小时前
【Linux】信号
android·linux·c语言·c++
城北徐宫1 小时前
Linux信号深度解剖:5种产生、3张表、4次切换
linux·c++·学习
倔强的石头1061 小时前
【Linux指南】Linux快捷键与系统实用技巧
linux·运维·服务器
番茄地瓜2 小时前
Linux 配置静态 IP 步骤
linux·运维·服务器
liulilittle2 小时前
论 Linux 内核态全局稳态带宽的卡尔曼估计与工程实现
linux·服务器·网络·c++·计算机网络·tcp·通信
Irissgwe2 小时前
五、应用层协议HTTP
linux·网络·网络协议·http·状态码·url
.千余3 小时前
【Linux】 传输层协议UDP:从端口号到传输机制
linux·运维·udp
囚~徒~4 小时前
轻量化的虚拟机
linux·运维·服务器
SteveSenna4 小时前
Ubuntu 20.04 安装 Isaac Sim 4.5 + Isaac Lab
linux·运维·服务器