尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Ubuntu系统用户管理全解析:从/etc/passwd到安全审计实战

Ubuntu系统用户管理全解析:从/etc/passwd到安全审计实战 1. 从一次权限故障说起为什么需要列出用户那天下午服务器上的一个定时脚本突然报错提示“权限被拒绝”。我登录上去一看脚本试图向一个特定目录写入日志但目录的所有者是一个我几乎没印象的用户名。这台Ubuntu服务器运行了快两年期间经过多位同事维护装过各种服务创建过不少临时账户。现在我需要快速搞清楚系统里到底有哪些用户那个陌生的用户是谁创建的它属于哪个组有没有登录权限这直接关系到故障的定位和后续的安全审计。在Linux世界里尤其是在Ubuntu这样的服务器主力军上“用户”远不止是那个用来登录的账号。每一个运行的服务如nginx、mysql、每一个后台进程都可能关联着一个特定的系统用户。理解如何全面、清晰地“列出用户”是系统管理、安全运维乃至日常问题排查的一项基础且关键的技能。这不仅仅是执行一两条命令而是理解用户体系的构成并能从不同维度获取你需要的信息。对于刚接触Linux的朋友可能会觉得cat /etc/passwd或者ls /home就是全部。实际上前者信息庞杂包含了很多系统功能账户后者可能不完整因为用户的家目录不一定在/home下。而对于有经验的管理员则需要能区分登录用户与非登录用户nologin能筛选特定组如sudo组的成员甚至能结合登录日志查看当前或历史的活跃用户。本文将从一个运维老兵的视角带你彻底掌握在Ubuntu系统中列出用户的多种方法及其适用场景。我们会从最简单的命令开始逐步深入到结合其他工具进行过滤、分析和审计确保无论你是在排查问题、进行安全检查还是单纯想了解系统状况都能找到最趁手的“兵器”。2. 核心武器库/etc/passwd 文件与基础解析命令所有用户信息的源头都指向一个文件/etc/passwd。这是一个纯文本文件存储了系统上所有用户的基本信息。每行代表一个用户由冒号:分隔成7个字段。root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash mysql:x:116:123:MySQL Server,,,:/nonexistent:/bin/false我们来拆解一下每个字段的含义用户名用户登录时使用的名称如root,ubuntu。密码占位符历史上这里存放加密后的密码现在出于安全考虑密码已移至/etc/shadow文件。x表示密码存在shadow文件中。用户ID用户的数字标识符。0代表root普通用户通常从1000开始。组ID用户所属主组的数字标识符。描述也称为GECOS字段通常包含用户全名、房间号、电话等信息。可以为空。家目录用户登录后的初始工作目录。登录Shell用户登录后启动的Shell程序。/bin/bash表示可登录/usr/sbin/nologin或/bin/false表示该账户不可用于交互式登录常用于服务账户。直接查看这个文件是最原始的方法cat /etc/passwd。但信息太多不易阅读。因此我们有了更专业的命令。getent passwd这是查看用户信息的“标准姿势”。getent命令从名称服务切换库NSS获取数据库条目它不仅查看本地的/etc/passwd如果系统配置了LDAP、NIS等集中用户管理它也能一并显示。对于绝大多数Ubuntu桌面或服务器环境它的输出和cat /etc/passwd一致但它是更推荐的做法。less /etc/passwd当用户很多时用less可以上下翻页查看比cat更友好。仅仅列出所有行还不够我们经常需要过滤。例如只想看可以登录的用户即登录Shell不是nologin或false的getent passwd | grep -vE “(/nologin|/false)$”这个命令使用grep -v进行反向匹配-E启用扩展正则表达式(/nologin|/false)$匹配以/nologin或/false结尾的行然后将其排除。或者我想找出UID大于等于1000的普通用户在大多数Ubuntu默认配置中这是普通用户的起始UIDawk -F: ‘$3 1000 {print $1}’ /etc/passwd这里使用了awk-F:指定冒号为字段分隔符$3代表第三个字段UID条件满足时打印第一个字段用户名。注意UID起始值如1000并非绝对。它由/etc/login.defs文件中的UID_MIN参数定义。在一些老系统或定制系统中这个值可能不同。使用grep ^UID_MIN /etc/login.defs可以查看确切值。3. 进阶查询按需筛选与组合信息在实际工作中我们很少需要看全部用户更多的是带有特定目的的查询。这就需要组合使用命令和过滤器。3.1 列出所有可登录系统的用户这个需求很常见比如做安全审计时需要确认哪些账户可能被用于SSH登录。关键在于检查第7个字段登录Shell。getent passwd | awk -F: ‘$7 ! “/usr/sbin/nologin” $7 ! “/bin/false” {print $1 “ (” $7 “)”}’这个awk命令判断Shell不是nologin或false然后打印出用户名和其Shell更直观。你可能会看到除了/bin/bash还有/bin/sh、/usr/bin/zsh等这些都是有效的登录Shell。3.2 列出属于特定组的用户用户和组的关系是多对多的。一个用户可以属于多个附加组。查看/etc/group文件可以知道组有哪些成员但使用getent和id命令更直接。方法一使用getent groupgetent group sudo输出类似sudo:x:27:ubuntu,adminuser。这表示sudo组的GID是27成员有ubuntu和adminuser两个用户。方法二使用members命令可能需要安装members命令专为此设计输出更干净。# 首先安装 sudo apt install members # 然后使用 members sudo直接输出ubuntu adminuser方法三遍历所有用户检查其所属组如果你想用脚本实现或者members命令不可用可以这样做getent passwd | cut -d: -f1 | while read user; do if id -nG “$user” | grep -qw “sudo”; then echo “$user” fi done这个脚本稍微复杂点先获取所有用户名然后遍历每个用户使用id -nG列出该用户所属的所有组名再用grep -qw安静地查找是否包含“sudo”组。如果包含则打印该用户名。3.3 列出当前登录的用户这关乎系统的实时状态。who命令是最经典的选择。who输出示例ubuntu pts/0 2024-05-27 10:15 (192.168.1.100)它显示了用户名、终端类型、登录时间及来源IP。w命令信息更丰富还显示了用户当前正在执行的命令和系统负载。w输出示例10:20:15 up 15 days, 2:30, 1 user, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN IDLE JCPU PCPU WHAT ubuntu pts/0 192.168.1.100 10:15 5.00s 0.05s 0.00s wlast命令则用于查看历史登录记录对于追踪异常登录非常有用。last -n 10 # 查看最近10条登录记录3.4 列出拥有家目录的用户有时我们想清理磁盘空间需要知道哪些用户实际拥有家目录。不能只看/home因为家目录路径可能在/etc/passwd的第6字段自定义。getent passwd | awk -F: ‘{if ($6 ! “” system(“[ -d \”” $6 “\” ]”) 0) print $1 “:” $6}’这个命令有点技巧它使用awk调用system()函数执行shell测试命令[ -d “目录” ]检查该目录是否存在。如果存在返回状态码0则打印用户名和家目录。注意包含空格的路径名可能会带来问题但在标准Ubuntu安装中很少见。一个更简单但可能不精确的方法是假设家目录都在/home下且以用户名命名ls -1 /home/4. 使用专用工具更人性化的展示对于系统管理员有一些命令提供了比原始/etc/passwd数据更友好、信息更集中的视图。lslogins命令这是一个非常强大的工具专门用于列出用户信息默认输出就很有用。sudo lslogins输出是一个格式清晰的表格包含用户名、UID、GID、家目录、Shell、最后登录时间等。它需要sudo权限来读取/etc/shadow中的部分信息如密码过期时间。sudo lslogins -u # 只列出普通用户UID 1000-u参数非常实用能直接过滤掉系统账户。chage -l 用户名虽然这是查看单个用户密码和账户过期详情的命令但在审计时结合列表命令对可疑账户逐一检查其过期状态是很好的安全实践。# 先列出所有可登录用户然后检查其中一个 sudo chage -l ubuntu图形化界面对于Ubuntu桌面版如果你在桌面环境可以通过“设置”-“用户”来查看和管理用户。但对于服务器运维命令行是唯一途径。实操心得在脚本中批量处理用户时我强烈推荐使用getent而不是直接读取/etc/passwd。因为getent的行为是标准化的并且兼容各种用户来源配置。直接解析/etc/passwd文件虽然快但在配置了外部用户目录如LDAP的环境中会得到不完整的结果。养成使用getent的习惯能让你的脚本更具可移植性。5. 实战场景安全审计与用户清单导出现在让我们回到开头的场景并扩展成一次小型的主动安全审计。假设我需要生成一份当前系统的用户分析报告。目标列出所有可登录的用户并标注其是否在sudo组。列出所有UID为0root权限的用户除了root本身这可能是严重的安全隐患。列出最近30天内从未登录过的用户可能是废弃账户。实现脚本#!/bin/bash echo “ 系统用户安全审计报告 echo “生成时间$(date)” echo “” echo “1. 可登录用户及sudo权限” echo “用户名 | Shell | 在sudo组中” echo “— | — | —” getent passwd | awk -F: ‘$7 !~ /(nologin|false)$/ {print $1 “:” $7}’ | while IFS: read user shell; do if id -nG “$user” | grep -qw “sudo”; then sudo_member“是” else sudo_member“否” fi printf “%-15s | %-20s | %s\n” “$user” “$shell” “$sudo_member” done echo “” echo “2. 检查除root外UID为0的用户潜在后门” awk -F: ‘$3 0 $1 ! “root” {print “警告发现非root用户UID为0:”, $1}’ /etc/passwd if [ $? -ne 0 ]; then echo “未发现异常。” fi echo “” echo “3. 最近30天未登录的用户需确认是否为废弃账户” # 此检查需要lastlog命令和sudo权限 sudo lastlog -b 30 | tail -n 2 | grep -v “Never logged in” | awk ‘{print $1}’ /tmp/recent_users 2/dev/null getent passwd | awk -F: ‘$3 1000 {print $1}’ | while read user; do if ! grep -qw “^$user$” /tmp/recent_users 2/dev/null; then # 检查是否为服务账户不可登录 shell$(getent passwd “$user” | cut -d: -f7) if [[ “$shell” ~ (nologin|false) ]]; then continue # 跳过服务账户 fi echo “ - $user” fi done rm -f /tmp/recent_users echo “” echo “审计完成。”脚本解读与注意事项第一部分通过检查登录Shell和id -nG命令的结果生成了一个可登录用户及其sudo权限的表格。第二部分直接检查/etc/passwd寻找任何UID为0且用户名不是root的账户。这通常是一个危险信号。第三部分使用了lastlog -b 30来列出所有在最近30天内登录过的用户。然后我们获取所有普通用户UID1000并与最近登录列表对比找出未在最近登录列表中的用户。同时我们过滤掉了Shell为nologin/false的服务账户避免误报。踩坑提醒lastlog命令的输出格式可能因系统或本地化设置略有不同。在生产环境中运行前最好先在测试机上看一下lastlog命令的实际输出格式并相应调整awk ‘{print $1}’这部分确保它正确提取出用户名。此外lastlog数据可能被清除或轮转对于非常老的账户“从未登录”的状态也可能是正常的。导出纯净用户列表 如果只需要一个简单的用户名列表用于其他脚本可以这样做# 导出所有用户名 getent passwd | cut -d: -f1 all_users.txt # 导出所有普通用户可登录用户名 getent passwd | awk -F: ‘$3 1000 $7 !~ /(nologin|false)$/ {print $1}’ login_users.txt通过这样一系列的命令组合和脚本编写你就能从不同维度清晰地掌握Ubuntu系统上的用户状况无论是用于日常管理、故障排查还是安全审计都能做到心中有数。记住了解你的用户是管理好系统的第一步。
返回列表