LInux 文件权限

  • linux 文件权限详解,uid gid 等

  • 资料来源:

    linux 命令行与 shell 脚本大全

  • 更新

    1
    2
    20.11.07 初始化
    20.11.08 初版

导语

很久就在倒腾 docker 文件权限就遇到了一堆的权限问题,今天一次性搞清楚.其实是个读书笔记.

Linux 用户

/etc/passwod 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat /etc/passwd
# 登录用户名:用户密码:uid:gid:用户文本描述:用户 home 目录:默认 shell

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
...
libvirt-dnsmasq:x:128:137:Libvirt Dnsmasq,,,:/var/lib/libvirt/dnsmasq:/usr/sbin/nologin

这个文件是早期 linux 下存储用户的文件,直到现在都在使用,不过由于安全性问题,用户密码已经转到别的文件存储了.

存储的用户

  • root 自然是地一个,最高权限,uid = 0,gid = 0.
  • 可以看到非常多与系统服务有关的用户,这些其实并不是真正的用户,只是方便系统服务使用而已.
  • 用户账户分配的 uid 起始是在 1000(还可能是 500),gid 同上.

绝对不要直接修改此文件…

/etc/shadow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sudo cat /etc/shadow
# 用户名:加密后密码:1970.1.1 (或到上次修改密码)到现在的天数
# :多少天后才能修改密码:多少天后必须更改密码
# :密码过期前,多少天提醒用户:密码过期后多少天禁用此用户:1970.1.1到用户被禁用的日期的天数
# :其他

root:$6$...eUyG0:18493:0:99999:7:::
daemon:*:18474:0:99999:7:::
bin:*:18474:0:99999:7:::
sys:*:18474:0:99999:7:::
sync:*:18474:0:99999:7:::
games:*:18474:0:99999:7:::
man:*:18474:0:99999:7:::
lp:*:18474:0:99999:7:::
....
libvirt-dnsmasq:!:18496:0:99999:7:::

这个文件是存储所有用户密码的文件,只能 root 用户可以访问.

存储的信息

  • 用户名
  • 加密后的密码
  • 1970.1.1 (或到上次修改密码) 到现在的天数
  • 多少天后才能修改密码
  • 多少天后必须更改密码
  • 密码过期前,多少天提醒用户
  • 密码过期后多少天禁用此用户.
  • 1970.1.1 到用户被禁用的日期的天数
  • 其他

加密方式看起来有 md5 或其他.

添加用户

1
2
3
4
5
6
7
8
$ useradd -D
GROUP=100 # 新用户默认 gid = 100 组
HOME=/home # 默认 HOME 在 /home/username 下
INACTIVE=-1 # 密码过期后不禁用
EXPIRE= # 未被设置成某个过期日期
SHELL=/bin/sh # 默认 shell
SKEL=/etc/skel # 创建 HOME 时,拷贝到 HOME
CREATE_MAIL_SPOOL=no # 为新用户在 mail 下创建文件

useradd -D 可以查看添加用户时的默认设置.要修改默认值在 -D 后面添加具体命令.

1
2
3
4
5
-b # 创建 HOME 位置
-e # 账户过期日期
-f # 密码过期的天数
-g # gid
-s # 默认 shell

添加用户 useradd,没有参数即使用默认设置.(需要 root 用户或 sudo)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-b, --base-dir BASE_DIR       # 新账户的主目录的基目录
--btrfs-subvolume-home # use BTRFS subvolume for home directory
-c, --comment COMMENT # 新账户的 GECOS 字段
-d, --home-dir HOME_DIR # 新账户的主目录
-D, --defaults # 显示或更改默认的 useradd 配置
-e, --expiredate EXPIRE_DATE # 新账户的过期日期
-f, --inactive INACTIVE # 新账户的密码不活动期
-g, --gid GROUP # 新账户主组的名称或 ID
-G, --groups GROUPS # 新账户的附加组列表
-h, --help # 显示此帮助信息并退出
-k, --skel SKEL_DIR # 使用此目录作为骨架目录
-K, --key KEY=VALUE # 不使用 /etc/login.defs 中的默认值
-l, --no-log-init # 不要将此用户添加到最近登录和登录失败数据库
-m, --create-home # 创建用户的主目录
-M, --no-create-home # 不创建用户的主目录
-N, --no-user-group # 不创建同名的组
-o, --non-unique # 允许使用重复的 UID 创建用户
-p, --password PASSWORD # 加密后的新账户密码
-r, --system # 创建一个系统账户
-R, --root CHROOT_DIR # chroot 到的目录
-P, --prefix PREFIX_DIR # prefix directory where are located the /etc/* files
-s, --shell SHELL # 新账户的登录 shell
-u, --uid UID # 新账户的用户 ID
-U, --user-group # 创建与用户同名的组
-Z, --selinux-user SEUSER # 为 SELinux 用户映射使用指定 SEUSER
--extrausers # Use the extra users database

类似的还有一个 adduser + username,相比之下就没有这么多的配置.

  • 创建一个与 username 同名的用户组
  • 创建 HOME 目录,自动将 /etc/skel 下内容拷贝到 /HOME/username
  • 创建后的账户,可以直接登录.

删除用户

userdel + unsername 没有任何参数只会删除 /etc/passwd 里面的用户信息.

userdel -r + username 会删除用户的主目录 + mail 下信息 (多用户时慎用)

修改用户

usermod

  • 可以修改大部分 /etc/passwd 下的属性

  • 比较实用的是 -L/U 一个锁定一个释放,不需要删除用户,即可让用户无法登录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    用法:usermod [选项] 登录名

    选项:
    -b, --badnames # allow bad names
    -c, --comment COMMENT # GECOS 字段的新值
    -d, --home HOME_DIR # 用户的新主目录
    -e, --expiredate EXPIRE_DATE # 设定帐户过期的日期为 EXPIRE_DATE
    -f, --inactive INACTIVE # 过期 INACTIVE 天数后,设定密码为失效状态
    -g, --gid GROUP # 强制使用 GROUP 为新主组
    -G, --groups GROUPS # 新的附加组列表 GROUPS
    -a, --append GROUP # 将用户追加至上边 -G 中提到的附加组中,
    # 并不从其它组中删除此用户
    -h, --help # 显示此帮助信息并退出
    -l, --login NEW_LOGIN # 新的登录名称
    -L, --lock # 锁定用户帐号
    -m, --move-home # 将家目录内容移至新位置 (仅于 -d 一起使用)
    -o, --non-unique # 允许使用重复的(非唯一的) UID
    -p, --password PASSWORD # 将加密过的密码 (PASSWORD) 设为新密码
    -R, --root CHROOT_DIR # chroot 到的目录
    -P, --prefix PREFIX_DIR # prefix directory where are located the /etc/* files
    -s, --shell SHELL # 该用户帐号的新登录 shell
    -u, --uid UID # 用户帐号的新 UID
    -U, --unlock # 解锁用户帐号
    -v, --add-subuids FIRST-LAST # 添加子 UID 范围
    -V, --del-subuids FIRST-LAST # 移除子 UID 范围
    -w, --add-subgids FIRST-LAST # 添加子 GID 范围
    -W, --del-subgids FIRST-LAST # 移除子 GID 范围
    -Z, --selinux-user SEUSER # 用户的新的 SELinux 用户映射

passwd / chpasswd

  • 如同字面意思,修改用户密码
  • passwd + username,自然用户只能修改自己的密码.root 可以改动其他账户密码.
  • passwd -e 可以使下一次用户登录后必须更改密码 (常见于第一次登录)
  • chpasswd 是批量修改用户密码.username:passwd,可以写到文件重定向给 chpasswd.chpaswd < user.txt

chsh / chfn / chage

  • chsh 修改默认 shell
  • chfn 修改用户备注,可以存入很多详细信息
  • chage 修改用户有效期等.(例如密码过期时间)

用户组

linux 管理权限除了 uid 这个和用户一一对应的编码外,还有 gid 用户组这个概念.

/etc/group

与用户信息类似,分组信息也保存在一个文件中 /etc/goup.

1
2
3
4
5
6
7
# 组名:组密码:gid:组成员
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
...
test:x:1001:

通常用户组是从 1000(500) 开始分配的,修改用户 gid 使用 usermod.

特别说明: 在 /etc/passwd 用户作为指定组的默认组时,这个用户在 /etc/group 是不出现的.

创建新组

groupadd + groupname,默认情况下是没有组成员的.

usermod -G groupname username,添加用户到用户组.(这条命令很熟悉了,每次安装 docker 都要来一次)

修改用户组

用户组属性主要就是俩,gid 和 groupname.还有其他组密码等.

组名可以随便改,因为所有安全机制都基于 gid.

1
2
3
4
5
6
7
8
选项:
-g, --gid GID 将组 ID 改为 GID
-h, --help 显示此帮助信息并退出
-n, --new-name NEW_GROUP 改名为 NEW_GROUP
-o, --non-unique 允许使用重复的 GID
-p, --password PASSWORD 将密码更改为(加密过的) PASSWORD
-R, --root CHROOT_DIR chroot 到的目录
-P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files

文件权限

1
drwxr-xr-x  2 test test         2 一月   28 13:31 视频

上面是一条典型的文件权限.具体而言

  • 对象是目录
  • 所有者有 读写执行
  • 组成员有 读 - 执行
  • 其他用户 读 - 执行
12~44~67~9
类型文件所有者权限组成员权限其他用户权限
- 文件r 可读
d 目录w 可写
l 链接x 可执行
c 字符型设备- 没有权限
b 块设备
n 网络设备

权限表示

  • 字符表示权限终究在运算时不方便.例子: rwxr-xr-x
  • 二进制下,文件的权限一共有 3*3 个比特,用二进制表示有 8*3 种.例子: 111 101 101
  • 换算到八进制下,就可以用 3 个数表示权限了.例子: 755

则典型的对于文件夹 777 就是全部权限.而文件则是 666(没有执行)

默认权限

一起都和 umask 命令关联.

1
2
$ umask
002

umask 默认是掩码,即创建新文件 (夹) 时候,默认的权限是 666(777) - 002 = 664(775).

修改默认值也简单 umask + 默认权限掩码

修改权限

上文也说了权限的八进制表示,那修改权限最直接的把新权限表示 + 文件 (夹)

1
chmod 777 dir

这样多少有些不便.另一种是基于字符来的.

1
chmod [ugoa] [+-=] [rwxXstugo]

第一组代表用户

  • u 所有者
  • g 组成员
  • o 其他
  • a 所有

第二组怎样设置权限

  • + 增加权限
  • - 移除权限
  • = 设置成这样的权限

第三组代表权限

  • rwx 各自是 读/写/执行
  • S 对象是目录或已有执行权限,赋予执行权限
  • s 运行时重设置 uid gid
  • u 权限同所有者
  • g 权限同组成员
  • o 权限同其他用户

令: -r 作用于目录可以递归到子文件/子文件夹.

改变所属关系

chown/chgrp 改变文件所有者/文件默认用户组.

1
chown [选项]... [所有者][:[组]] 文件.

注意只有 root 用户可以改变,文件的所有者.

任何文件的所有者都可以改变文件所属的用户组.

结语

文件权限是搞清楚了,但是还有个文件系统的坑没填.

想想就头大…