你刚部署完一个网站,打开浏览器一看——500 错误。查日志,Permission denied。你改了文件权限,没用。你改了文件属主,还是不行。你给了 777,依然报错——因为目录没给执行权限。这种场景我经历太多次了。很多人用了好几年 Linux,对权限还是一知半解,出了问题就乱试 777,试到能跑就行。
但权限模型其实是 Linux 最核心的设计之一,理解了它,你才能真正说自己会用 Linux。
什么是用户、组、文件权限?
Linux 是一个多用户操作系统。这句话说起来简单,背后的含义是:多个用户可以同时在一台机器上干活,而且互相不能乱看乱动对方的东西。
为了实现这个目标,Linux 设计了一套三层的权限控制体系:
文件 → 属主(User) → 属组(Group) → 其他人(Others)
每个文件都被绑定到一个用户和一个组。当有人要访问这个文件时,系统会问三个问题:
- 你是谁?你是这个文件的属主吗?如果是,用属主权限。
- 如果你不是属主,你属于这个文件的属组吗?如果是,用组权限。
- 如果你既不是属主也不是属组成员,那你就是其他人,用其他人的权限。
这个逻辑很清晰吧?
打个比方,你可以把 Linux 想象成一个写字楼:
这个类比只是帮助理解,真实实现并不完全一致。
有一个特殊用户叫 root,它是超级管理员,不受任何权限限制。哪怕权限是 000,root 照样能读写。
为什么需要用户和组?
最早的 Unix 设计出来就是给多人用的。几十年过去了,这个设计依然好用,为什么?
安全隔离
这是最核心的原因。如果没有权限隔离,一个普通用户误删了系统文件,整个机器就挂了。应用程序如果漏洞被黑客入侵,黑客只能拿到应用程序用户的权限,没法直接染指整个系统。
最小权限原则
在生产环境中,比较好的做法是给每个服务创建单独的用户。比如 nginx 跑在 nginx 用户下,mysql 跑在 mysql 用户下。这样就算其中一个服务被攻破,攻击者也不能随便读写其他服务的文件。
我见过不少人图省事,所有服务都用 root 跑,这等于把家门钥匙直接放在门口。一旦出问题,就是全境失守。
协作共享
组的设计方便团队协作。开发组共享项目代码,大家都有读写权限,但其他人看不到。这个设计到今天依然适用。
权限到底是怎么工作的?
三种基本权限
对文件来说,有三种基本权限:
很多人以为只要我有文件权限,就能访问文件。不对!你必须对文件所在的所有父目录都有执行权限,才能到达这个文件。
如果目录没有 x 权限,就算你有文件的 r 权限,也读不了。
权限的数字表示
权限用数字表示的时候,就是三个权限位相加:
所以常见的 755 就是:
644 就是:
看一下实际例子
用 ls -l 看看文件权限:
$ ls -l-rw-r--r-- 1 alice developers 1024 Jul 1 10:00 app.pydrwxr-xr-x 2 alice developers 64 Jul 1 10:00 src
逐段解释:
第一段 -rw-r--r--:
- 第一个字符:
- 表示普通文件,d 表示目录,l 表示软链接 - 接下来三个:
rw- → 属主 alice 有读写权限,没有执行 - 再接下来三个:
r-- → 组 developers 成员只有读权限
第二段 1:硬链接个数。不用太关心。
第三段 alice:属主用户名。
第四段 developers:属组名。
常用命令全解析
查看当前用户和组
whoami # 我是谁id # 显示我的用户ID、组ID、所属哪些组groups # 显示我所属的所有组
创建用户(useradd)
useradd 用户名 # 创建新用户(默认不创建家目录)useradd -m 用户名 # 创建用户,同时创建家目录 /home/用户名useradd -M 用户名 # 创建用户,明确不创建家目录useradd -s /sbin/nologin 用户名 # 创建用户,指定登录 shell 为 nologin(禁止登录)useradd -r 用户名 # 创建系统用户(UID < 1000,不创建家目录)useradd -d /data/用户名 用户名 # 指定家目录路径useradd -e 2026-12-31 用户名 # 设置账号过期日期useradd -u 1500 用户名 # 指定 UID
常用选项一览:
大多数发行版 useradd 默认不创建家目录,记得加 -m 参数。我刚开始经常忘,结果登录的时候提示 No directory, logging in with HOME=/。
修改密码(passwd)
passwd 用户名 # 给指定用户设置密码(root 可以改任何人的密码)passwd # 修改自己的密码passwd -d 用户名 # 删除用户密码,允许空密码登录passwd -e 用户名 # 强制用户下次登录时必须修改密码passwd -n 7 用户名 # 设置密码最短使用天数(7 天内不能改密码)passwd -x 90 用户名 # 设置密码最长使用天数(90 天后必须改密码)passwd -w 7 用户名 # 密码过期前 7 天开始警告passwd -i 3 用户名 # 密码过期后 3 天内仍可登录,超过则锁定
passwd -e 在新人入职时特别有用。你创建好账号,设一个临时密码,然后 passwd -e 新人,对方第一次登录系统就会强制要求改密码。既安全又不尴尬。
锁定与解锁用户
锁定用户分两种:锁密码和锁账号。
锁密码——用户仍然可以用 SSH Key 等方式登录,只是不能用密码:
passwd -l 用户名 # 锁定密码,在 /etc/shadow 中密码字段前加 !!passwd -u 用户名 # 解锁密码passwd -S 用户名 # 查看密码状态(PS = 正常,LK = 锁定,NP = 无密码)
锁账号——账号直接过期,任何方式都登不进来:
usermod -L 用户名 # 锁定账号,在 /etc/shadow 中密码字段前加 !(注意和 passwd -l 的区别)usermod -U 用户名 # 解锁账号
passwd -l 和 usermod -L 的区别可以不用太纠结,日常用 passwd -l 就行。两者的效果都是让密码失效,只是 /etc/shadow 里的标记方式不同。
禁止用户登录
有时候你需要一个用户来跑服务,但不希望别人用这个账号登录系统。比如 nginx 用户、mysql 用户,都是"服务用户",不需要登录 shell。
usermod -s /sbin/nologin 用户名 # 改成 nologin,登录时显示提示信息后退出usermod -s /bin/false 用户名 # 改成 /bin/false,登录时直接退出(无提示)
/sbin/nologin 和 /bin/false 的区别:
/sbin/nologin:用户尝试登录时会显示一行提示信息(可以自定义),然后退出/bin/false
$ cat /etc/passwd | grep nginxnginx:x:996:993:nginx user:/var/cache/nginx:/sbin/nologin
最后一列就是 shell。服务用户的 shell 基本都是 /sbin/nologin。
如果你想让某个用户连 FTP 都不能用,但能用 SSH:
usermod -s /usr/sbin/nologin 用户名
然后把 /usr/sbin/nologin 加到 /etc/shells 里(不推荐,大多数情况下直接用 /sbin/nologin 就够了)。
直接改回来就行:
usermod -s /bin/bash 用户名
改完之后 su - 用户名 试一下能不能登进去。如果之前还锁了密码,记得一起解:
passwd -u 用户名
修改用户信息(usermod)
usermod -l 新用户名 旧用户名 # 重命名用户(改用户名)usermod -d /new/home 用户名 # 修改家目录路径(不会自动移动文件)usermod -m -d /new/home 用户名 # 修改家目录路径,同时把旧文件搬过去usermod -c "备注" 用户名 # 修改用户备注信息(GECOS 字段)usermod -e 2026-12-31 用户名 # 修改账号过期日期usermod -s /bin/bash 用户名 # 修改登录 shell
删除用户(userdel)
userdel 用户名 # 删除用户,但保留家目录和邮件userdel -r 用户名 # 删除用户,同时删除家目录和邮件
userdel -r 会直接删掉家目录下的所有文件,没法恢复。删之前确认一下有没有需要保留的数据。另外,用户创建的文件(分散在系统各处)不会自动删除,属主会变成数字 UID,需要用 find / -uid UID 去找。
创建组
groupadd 组名 # 创建新组useradd -G 组名 用户名 # 创建用户时把用户加入组usermod -aG 组名 用户名 # 把已有的用户添加到组
usermod -G 会覆盖用户原来的所有组!一定要加 -a 参数(append),意思是"追加"到组。
# 正确:追加,不影响原来的组usermod -aG docker alice# 错误:alice 只属于 docker 组了,原来的组全没了usermod -G docker alice
查看用户属于哪些组
groups 用户名
例子:
$ groups alicealice : alice docker developers
说明 alice 是这三个组的成员。
修改文件属主和属组:chown
chown = change owner,改文件的属主和属组。
chown 用户名 文件 # 只改属主chown 用户名:组名 文件 # 同时改属主和属组chown :组名 文件 # 只改组,不改属主chown -R 用户名:组名 目录 # 递归改目录下所有文件
例子:
# 把 /var/www 目录的属主改成 nginx 用户,属组改成 nginx 组chown -R nginx:nginx /var/www# 只把组改成 developerschown :developers /home/alice/project
修改文件属组:chgrp
其实 chown :group 就能改组,chgrp 只是更直观:
chgrp 组名 文件chgrp -R 组名 目录
修改文件权限:chmod
chmod = change mode,改权限位。
两种写法:数字法和符号法。
数字法(最常用):
chmod 644 文件 # 属主 rw,组 r,其他人 rchmod 755 目录 # 属主 rwx,组 rx,其他人 rxchmod -R 755 目录 # 递归
符号法(适合改个别权限):
u 代表属主,g 代表组,o 代表其他人,a 代表所有人。
chmod u+x 文件 # 给属主加上执行权限chmod g+w 文件 # 给组加上写权限chmod o-r 文件 # 移除其他人的读权限chmod a+x 文件 # 给所有人加执行权限
/etc 下的用户配置文件详解
用户和组的信息都存在 /etc 下面的几个文件里。我们来逐个看清楚它们到底存了什么。
/etc/passwd:用户信息数据库
这是最核心的用户信息文件,所有用户信息都存在这里。我们先看一个实际例子:
$ cat /etc/passwd | head -5root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinalice:x:1000:1000:Alice Smith:/home/alice:/bin/bashnginx:x:996:993:nginx user:/var/cache/nginx:/sbin/nologin
每一行用冒号分成 7 个字段,我们一个个说:
| | |
|---|
| | root |
| | x |
| | 0 root,1-999 系统用户,1000+ 普通用户 |
| | |
| | |
| | /root、/home/alice、/var/cache/nginx |
| | /bin/bash |
很早以前密码真的存在这里,但是所有人都能读这个文件,太不安全了。后来就把密码移到了 /etc/shadow,这里只放一个 x 占位。
关于 UID 的约定:
UID 0UID 1-999UID 1000 及以上
大多数发行版第一个创建的普通用户 UID 就是 1000,第二个 1001,以此类推。
/etc/shadow:加密密码存放地
/etc/shadow 才是真正存密码的地方。这个文件只有 root 能读,普通用户看不了,这就安全多了。
我们看个例子:
sudo cat /etc/shadow | grep alicealice:$6$xyz...$abcdef...:19000:7:90:7:3:19500:
还是冒号分隔,一共 9 个字段:
| | |
|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | 从 1970-01-01 算起的天数,到期后不能登录 |
| | |
第二个字段的密码格式:$id$salt$hashed
特殊的密码状态:
- 密码字段是空:用户不需要密码就能登录(非常不安全,不推荐)
- 密码开头是
! 或 !!:密码被锁定,用户不能登录(passwd -l 和 usermod -L 就是这么干的) ! 是 usermod -L 加的,!! 是 passwd -l 加的,效果差不多
/etc/shadow 权限必须是 ---------- 或者 -rw-------,只有 root 能读写。如果不小心改成任何人能读,那所有加密密码就泄露了,攻击者可以离线暴力破解。
/etc/group:组信息数据库
所有的组信息都存在这里。格式和 passwd 很像:
$ cat /etc/group | head -5root:x:0:bin:x:1:daemon:x:2:users:x:100:developers:x:1000:alice,bob
四个字段:
这里容易混淆一个点:用户的主组不在这个列表里。
比如用户 alice 的主组是 developers(GID 1000),你不用把 alice 写到第四个字段里,因为主组信息已经在 /etc/passwd 的 GID 字段里了。第四个字段只放附加组成员。
举个例子:
alice:x:1000:1000:Alice:/home/alice:/bin/bashdevelopers:x:1000:docker:x:987:alice,bob
这里:
- alice 的主组是 developers(GID 1000)
- alice 还是 docker 组的附加成员,所以 docker 那行的最后一列写上 alice
/etc/gshadow:组密码存放地
和 /etc/shadow 对应,组密码存在这里。现在基本不用组密码了,但文件还是存在。格式类似,有兴趣可以自己看看,一般不用管它。
/etc/default/useradd:创建用户的默认配置
当你用 useradd 创建用户时,很多默认参数都从这里读:
$ cat /etc/default/useradd# useradd defaults fileGROUP=100HOME=/homeINACTIVE=-1EXPIRE=SHELL=/bin/bashSKEL=/etc/skelCREATE_MAIL_SPOOL=yes
几个重要的:
HOME=/homeSHELL=/bin/bash:默认 shell 是 bash,如果不想让用户登录,创建的时候要自己改SKEL=/etc/skel:骨架目录,新建用户时,会把这里的文件复制到新家目录
这就是"骨架目录"。新建用户时,系统会把 /etc/skel 里的所有东西复制到用户新家目录。这里一般放 .bashrc、.profile 这些初始配置文件。如果你想让所有新建用户都默认有某些配置,改 /etc/skel 就行。
/etc/login.defs:登录相关默认配置
这里放一些创建用户时的默认规则:
MAIL_DIR /var/spool/mailPASS_MAX_DAYS 99999PASS_MIN_DAYS 0PASS_MIN_LEN 5PASS_WARN_AGE 7UID_MIN 1000UID_MAX 60000SYS_UID_MIN 201SYS_UID_MAX 999GID_MIN 1000GID_MAX 60000SYS_GID_MIN 201SYS_GID_MAX 999CREATE_HOME yesUMASK 077
重点说几个:
UID_MIN 1000CREATE_HOME yes:默认创建家目录(这就是为什么你不加参数也会创建 /home/用户名,不同发行版默认不一样)UMASK 077:新建家目录的 umask,077 意味着只有你自己能读,其他人不能看,安全
四个文件的关系总结
画个关系图你就明白了:
/etc/passwd → 用户基本信息 + 主组 GID/etc/shadow → 用户加密密码 + 过期信息/etc/group → 组信息 + 附加组成员/etc/gshadow → 组密码(基本不用)
它们四个配合起来,就是 Linux 用户组权限的完整信息存储。
虽然你可以用 vi 直接编辑,但推荐用命令改:
这些命令会帮你正确更新所有四个文件,不容易出错。
一个真实的生产环境例子
走一遍完整流程,看看权限在实际中怎么用。
比如你接手了一个 Python Web 应用要部署:
- 创建专用用户和组
groupadd myappuseradd -m -g myapp myapp
- 把代码放到 /var/www/myapp
chown -R myapp:myapp /var/www/myapp
- 设置正确的权限
# 目录需要 x 权限才能进入,所以 755find /var/www/myapp -type d -exec chmod 755 {} \;# 普通文件只需要读写,所以 644find /var/www/myapp -type f -exec chmod 644 {} \;# 启动脚本需要执行权限chmod 755 /var/www/myapp/start.sh
- 应用需要写日志,创建日志目录,修改权限
mkdir /var/log/myappchown myapp:myapp /var/log/myappchmod 755 /var/log/myapp
- nginx 需要读取静态文件,把 nginx 用户加入 myapp 组
usermod -aG myapp nginx
- 给组开放读权限就行
chmod g+r /var/www/myapp/static
整个流程下来,权限清晰:
工程实践经验
哪些权限设置是安全的?
为什么不要随便用 777?
777 意味着任何人都可以读写执行。等于你把文件放在公共场所,谁都能改。如果攻击者能上传一个文件到 777 目录,他就能直接执行它。
我见过太多项目为了图省事,整个目录都是 777,这是在给黑客开门。
💡 如果遇到 Permission denied 怎么办?特殊权限位:SUID、SGID、Sticky Bit
这三个不常用,但碰到了要认识:
- SUID (4xxx):运行程序时,以文件属主的权限运行,不是以执行者的权限。比如
passwd 命令需要改 /etc/shadow,所以设置了 SUID。 - SGID (2xxx):目录设置 SGID 后,在这个目录下创建的文件,自动继承目录的属组。共享项目的时候很有用。
- Sticky Bit (1xxx,通常是 /tmp):目录设置后,只有文件属主才能删除自己的文件。
/tmp 人人都能写,但你不能删别人的文件。
一般来说,你不太需要手动设置这些。但看到权限位有四位比如 4755,要知道第一位是特殊权限。
精细化权限:ACL 访问控制列表
传统的 UGO(User/Group/Others)模型只能给一个用户、一个组设置权限。如果你想给多个用户、多个组设置不同权限怎么办?
这就要用 ACL(Access Control List)了。ACL 允许你对任意用户、任意组设置单独的权限,比 UGO 精细得多。
基本用法:setfacl
# 给用户 alice 单独加读权限setfacl -m u:alice:r 文件# 给组 dev 加读写执行权限setfacl -m g:dev:rwx 目录# 给用户 bob 移除所有 ACL 权限setfacl -x u:bob 文件# 移除所有 ACL 规则setfacl -b 文件# 递归给目录下所有文件设置setfacl -R -m g:dev:rw 目录
例子:我们项目叫 myproject,有三个开发:alice、bob、charlie,都在 dev 组。我们还需要让 nginx 能读项目里的静态文件,但不需要给 nginx 用户加进 dev 组。
# 用传统 UGO:属主是项目用户,组是 dev,其他人只读chown myapp:dev /var/www/myprojectchmod 750 /var/www/myproject# 用 ACL 给 nginx 单独开放读权限setfacl -m u:nginx:rx /var/www/myproject
这样:
完美比传统方式要灵活得多。
查看 ACL
getfacl 文件
输出大概是这样:
# file: myproject# owner: myapp# group: devuser::rwxuser:nginx:r-xgroup::r-xmask::r-xother::---
mask 是什么?
ACL 有个 mask 概念。它相当于一个"上限":所有用户和组的 ACL 权限,不能超过 mask。
比如 mask: r-x,就算你给某个用户 rwx,实际也只能拿到 r-x。
mask 会自动计算,不用手动改。如果你手动改了 ACL,记得让系统重新计算 mask:
setfacl -m m:rwx 目录
让 ACL 自动继承到新建文件
给目录加一个默认 ACL,这个目录下新建的文件会自动继承 ACL:
# 设置默认 ACL,所有新文件自动让 nginx 能读setfacl -m d:u:nginx:rx /var/www/myproject
d: 前缀表示"默认规则"。
这个功能在共享项目目录里特别好用。你不用每次新建文件都重新设一遍 ACL,默认规则会自动生效。
ACL 什么时候需要用?
大多数场景下,传统 UGO 够用了。但碰到上面这些情况,ACL 就是正确的选择。
常见坑
父目录没有执行权限,ACL 再开也没用。ACL 只是在传统权限之上加规则,不绕过基础权限检查。父目录连 x 权限都没有,ACL 开了也进不去。
删文件的时候,权限看目录,不看文件。只要目录有 w 权限,不管文件属主是谁,都能删。ACL 可以限制谁能删谁不能删。
文件系统要支持 ACL。现在绝大多数发行版默认都开了,不用管。老系统可能需要挂载的时候加 acl 选项。
常用命令汇总
| |
|---|
setfacl -m u:用户名:权限 文件 | |
setfacl -m g:组名:权限 文件 | |
setfacl -m d:u:用户名:权限 目录 | |
setfacl -x u:用户名 文件 | |
setfacl -b 文件 | |
getfacl 文件 | |
sudo 权限管理
如果你想让普通用户能执行一些 root 才能干的活,不要直接把密码给人家,用 sudo。
编辑 /etc/sudoers(用 visudo 命令):
alice ALL=(ALL) /usr/bin/systemctl restart nginx
这样 alice 就能用 sudo systemctl restart nginx 重启 nginx,但不能干别的。
一次真实的线上故障:为什么图片全部 403?
事情是这样的。
那天下午,我部署完一个网站,首页正常,文字内容都有,但所有图片全是裂的。打开浏览器开发者工具一看,所有图片请求全部返回 403 Forbidden。
排查过程
第一步,看 nginx 配置。路径没问题,root 指向正确,location 块也没少。
第二步,看文件权限。ls -l 一看,图片文件全是 644:
$ ls -l /var/www/site/images/-rw-r--r-- 1 root root 204800 Jul 3 14:00 banner.jpg-rw-r--r-- 1 root root 102400 Jul 3 14:00 logo.png
644,属主可读写,其他人只读。nginx 又不是属主,但至少能读吧?为什么还是 403?
第三步,我突然想到一件事——目录权限。往上翻一层:
$ ls -ld /var/www/site/images/drw-r--r-- 2 root root 4096 Jul 3 14:00 images/
看到了吗?drw-r--r--,也就是 744。
为什么 744 的目录,里面的文件读不了?
这就是很多人容易搞混的地方:文件和目录的权限语义不一样。
对于文件:
对于目录:
关键就在 x 权限。没有 x 权限的目录,你连进都进不去,更别说读里面的文件了。
回到这个例子:images/ 目录权限是 744,分解一下:
- 属主(root):rwx(7)—— root 能正常访问,没问题
- 属组:r--(4)—— 只能
ls 列出文件,不能访问 - 其他人:r--(4)—— 同上,只能列出,不能访问
nginx 进程跑在 nginx 用户下(或者 www-data),它不是 root,也不在属组里,所以被归类为"其他人"。其他人只有 r 权限,没有 x 权限。
结果就是:nginx 可以 ls 看到目录里有哪些图片,但不能打开这些图片文件。所以返回 403。
很多人以为:只要文件权限是 644,就一定能被读到。不对。
要访问一个文件,你需要对从根目录到该文件路径上的每一层目录都有 x(执行)权限。任何一层断了,后面的都访问不了。
就像你要进一个房间,你不仅要能打开房间门(文件权限),还得能走进大楼(/)、走进楼层(/var)、走进走廊(/var/www)、走到房间门口(/var/www/site/images)。中间任何一道门锁了,你都进不去。
修复
修起来很简单,给目录加上 x 权限就行:
chmod 755 /var/www/site/images/
或者更精细一点,只给需要的人加:
# 属主 rwx,属组 r-x,其他人 r-xchmod 755 /var/www/site/images/# 或者更保守:属主 rwx,属组 r-x,其他人不给权限chmod 750 /var/www/site/images/
改完之后,图片全部恢复正常。
这次故障教会我的
这次排查让我真正理解了 Linux 权限模型里最容易被忽略的一点:目录的 x 权限。
以前学权限的时候,书上说"目录的 x 权限代表可以进入目录",背是背了,但没真正理解它的实际意义。直到线上图片挂了,自己一步步排查出来,才算真正搞懂。
从那以后,我养成了一个习惯:部署完网站,用 Web 服务器用户的角度去验证一遍。不是用 root 或者你自己的账号,而是用 nginx/www-data 的身份:
# 用 nginx 用户身份测试是否能访问文件sudo -u nginx cat /var/www/site/images/banner.jpg > /dev/null && echo "OK" || echo "FAIL"
如果这个命令返回 FAIL,那浏览器里一定是 403。
另外,我还写了一个检查脚本,专门扫目录权限。核心逻辑就一行:
# 检查从根目录到目标路径的每一层,是否都有 x 权限namei -l /var/www/site/images/banner.jpg
namei 会列出路径中每一层目录的权限,你一眼就能看出哪一层断了。
常见陷阱
陷阱一:忘记父目录需要执行权限
你有一个文件 /home/alice/secret.txt,权限是 777,所有人都能读。但如果你把 /home/alice 权限改成 700,那其他人还是读不了。因为别人进不去你的家目录。
很多人犯这个错:文件权限开了,目录权限没开,还是访问不到。
陷阱二:用了 usermod -G 没加 -a,把用户原来的组全弄没了
这个错误真的太常见了。我刚学 Linux 也犯过。本来只是想把用户加到 docker 组,结果用户原来的组全被覆盖了,导致各种权限错误。
记住:追加组一定要加 -a。
陷阱三:nginx/php-fpm 进程用户不对
部署完网站,老是 Permission denied。一看,nginx 跑在 nginx 用户,文件属主是 root,权限 600,nginx 当然读不了。
正确做法:要么把文件属主改成 nginx,要么把 nginx 加入文件的组。
陷阱四:上传文件后权限不对
如果你用 FTP 上传文件,文件的属主是 FTP 用户,不是 Web 服务器用户。Web 服务器读不到。
这时候需要检查一下 FTP 的 umask 设置,或者上传后统一改一次权限。
陷阱五:家目录权限太开放
很多人把自己家目录设成 755,任何人都能进去看。这本来也没什么,但如果你里面有 .ssh/id_rsa 私钥,权限应该是 600,不然 SSH 会拒绝使用它,因为太不安全了。
陷阱六:锁了密码就以为用户登不进来
passwd -l 锁的是密码,不是账号。如果用户配了 SSH Key,照样能登录。真正想彻底阻止登录,要改 shell 为 /sbin/nologin,或者用 usermod -L 加 usermod -s /sbin/nologin 双保险。
还有,有人用 passwd -l 锁定用户后又去 usermod -U 解锁,结果发现解不了。因为 passwd -l 打的是 !! 标记,usermod -U 只能解 ! 标记。混用两个命令很容易把自己搞晕。
陷阱七:创建服务用户忘记加 nologin
服务用户默认创建出来是可以登录的,如果你忘了指定 nologin 的 shell,等于给攻击者多开了一扇门。创建服务用户的标准写法:
useradd -r -M -s /sbin/nologin 服务名
-r 创建系统用户,-M 不创建家目录,-s 禁止登录。三个一起用。
善意忠告
权限这个东西,说穿了就是一句话:最小权限原则。
给够用的最小权限就够了,不要给更多。你不需要让全世界都能写你的代码,不需要让全世界都能读你的日志。
我刚学 Linux 的时候,也是碰到 Permission denied 就直接 chmod 777,反正能跑就行。后来碰过一次安全问题,才明白权限设计不是没事找事,它是你系统的第一道防线。
真的,花一个小时把这个东西彻底搞懂,比你以后每次出问题都乱试一百次强太多。这是基础中的基础,理解了用户组权限,你才算真正入门 Linux。