> Linux文件权限详解:chmod和chown实战

为什么权限问题这么常见

“Permission denied”——这可能是Linux新手遇到最多的报错了。我刚开始用Linux的时候,解决方案永远是chmod 777,后来才知道这有多危险。

今天来彻底搞懂Linux的权限体系,以后遇到权限问题不再抓瞎。

理解权限表示

查看文件权限

1
2
3
4
5
6
$ ls -la /var/www/
total 12
drwxr-xr-x  3 root     root     4096 Jan  9 10:00 .
drwxr-xr-x 14 root     root     4096 Jan  9 10:00 ..
drwxr-xr-x  2 www-data www-data 4096 Jan  9 10:00 html
-rw-r--r--  1 www-data www-data  612 Jan  9 10:00 index.html

每一列的含义:

示例含义
第1列-rw-r--r--权限位
第2列1硬链接数
第3列www-data属主(owner)
第4列www-data属组(group)
第5列612文件大小(字节)
第6-8列Jan 9 10:00修改时间
第9列index.html文件名

权限位解析

1
2
3
4
5
6
7
-rw-r--r--
│├──┤├──┤├──┤
│  │   │   │
│  │   │   └── 其他用户权限(other): r-- = 只读
│  │   └────── 属组权限(group): r-- = 只读
│  └────────── 属主权限(owner): rw- = 读写
└───────────── 文件类型: - = 普通文件, d = 目录, l = 链接

三种基本权限:

符号数字含义对文件对目录
r4查看内容列出目录内容
w2修改内容创建/删除文件
x1执行运行脚本进入目录

chmod命令:修改权限

数字模式(推荐)

数字模式更直观,把权限转换成三位数字:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 权限计算:r=4, w=2, x=1,相加即可
# 755 = rwxr-xr-x(属主全权限,其他只读+执行)
# 644 = rw-r--r--(属主读写,其他只读)

$ chmod 755 script.sh
$ ls -l script.sh
-rwxr-xr-x 1 root root 1234 Jan  9 10:00 script.sh

$ chmod 644 config.txt
$ ls -l config.txt
-rw-r--r-- 1 root root 567 Jan  9 10:00 config.txt

常用权限组合:

权限值含义适用场景
755rwxr-xr-x目录、可执行脚本
644rw-r–r–普通文件、配置文件
600rw——-私钥、敏感配置
700rwx——私密目录(如.ssh)
777rwxrwxrwx永远不要用!

符号模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# u=属主, g=属组, o=其他, a=所有
# +=添加, -=移除, ==设置

# 给属主添加执行权限
$ chmod u+x script.sh

# 移除其他用户的写权限
$ chmod o-w file.txt

# 给所有用户添加读权限
$ chmod a+r file.txt

递归修改

1
2
3
4
5
6
# 递归修改整个目录
$ chmod -R 755 /var/www/html/

# 更精细的做法:目录755,文件644
$ find /var/www/html/ -type d -exec chmod 755 {} \;
$ find /var/www/html/ -type f -exec chmod 644 {} \;

chown命令:修改属主和属组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 修改属主
$ sudo chown www-data file.txt

# 同时修改属主和属组
$ sudo chown www-data:www-data file.txt

# 只修改属组
$ sudo chown :www-data file.txt
# 或者用chgrp
$ sudo chgrp www-data file.txt

# 递归修改
$ sudo chown -R www-data:www-data /var/www/html/

实际输出:

1
2
3
4
5
6
7
$ ls -l /var/www/html/index.html
-rw-r--r-- 1 root root 612 Jan  9 10:00 index.html

$ sudo chown www-data:www-data /var/www/html/index.html

$ ls -l /var/www/html/index.html
-rw-r--r-- 1 www-data www-data 612 Jan  9 10:00 index.html

实战场景

场景1:Nginx 403 Forbidden

这是最常见的权限问题:

1
2
3
4
5
6
7
8
# Nginx默认以www-data用户运行
$ ps aux | grep nginx
root       1234  0.0  0.1  65432  1234 ?  Ss  10:00  0:00 nginx: master
www-data   1235  0.0  0.3  65432  3456 ?  S   10:00  0:00 nginx: worker

# 确保网站文件属于www-data
$ sudo chown -R www-data:www-data /var/www/mysite/
$ sudo chmod -R 755 /var/www/mysite/

场景2:SSH密钥权限

1
2
3
4
5
6
7
8
9
# SSH对密钥权限要求非常严格
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_ed25519        # 私钥
$ chmod 644 ~/.ssh/id_ed25519.pub    # 公钥
$ chmod 600 ~/.ssh/authorized_keys

# 如果权限不对,会报错:
# WARNING: UNPROTECTED PRIVATE KEY FILE!
# Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open.

场景3:Shell脚本无法执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ ./deploy.sh
-bash: ./deploy.sh: Permission denied

$ ls -l deploy.sh
-rw-r--r-- 1 root root 1234 Jan  9 10:00 deploy.sh

# 缺少执行权限,添加它
$ chmod +x deploy.sh
$ ./deploy.sh
Deploying...

特殊权限位

权限数字作用示例
SUID4xxx以文件属主身份执行/usr/bin/passwd
SGID2xxx以文件属组身份执行共享目录
Sticky1xxx只有属主能删除/tmp
1
2
3
4
5
6
7
8
# 查看特殊权限
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Jan  9 10:00 /usr/bin/passwd
#   ^ 这个s就是SUID

$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 Jan  9 10:00 /tmp
#        ^ 这个t就是Sticky bit

权限排查清单

遇到"Permission denied"时,按这个顺序检查:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 1. 查看当前用户
$ whoami
deploy

# 2. 查看文件权限和属主
$ ls -la /path/to/file

# 3. 查看用户所属组
$ groups deploy
deploy : deploy www-data sudo

# 4. 检查目录链路上每一级的权限
$ namei -l /var/www/mysite/index.html
f: /var/www/mysite/index.html
dr-xr-xr-x root     root     /
drwxr-xr-x root     root     var
drwxr-xr-x root     root     www
drwxr-xr-x www-data www-data mysite
-rw-r--r-- www-data www-data index.html

总结

权限管理的核心原则是最小权限:只给必要的权限,不要图省事用777。记住常用的几个数字组合就行:目录755、文件644、私密文件600。

如果你想更深入地了解用户和权限管理,推荐阅读Linux用户与权限管理详解。关于SSH密钥的权限配置,可以参考SSH远程连接完全指南

Linux权限 Chmod Chown
cd ..