linux权限
缺乏安全性的系统不是完整的系统。系统中必须有一套能够保护文件免遭非授权用户浏览或修改的机制。Linux沿用了Unix文件权限的办法,即允许用户和组根据每个文件和目录的安全性设置来访问文件。
linux的安全性
Linux安全系统的核心是用户账户。每个能进入Linux系统的用户都会被分配唯一的用户账户。用户对系统中各种对象的访问权限取决于他们登录系统时用的账户。
用户权限是通过创建用户时分配的用户ID(User ID,通常缩写为UID)来跟踪的。UID是数值,每个用户都有唯一的UID,但在登录系统时用的不是UID,而是登录名。登录名是用户用来登录系统的最长八字符的字符串(字符可以是数字或字母),同时会关联一个对应的密码。
Linux系统使用特定的文件和工具来跟踪和管理系统上的用户账户。
/etc/passwd文件
Linux系统使用一个专门的文件来将用户的登录名匹配到对应的UID值。这个文件就是/etc/passwd文件,它包含了一些与用户有关的信息。下面是Linux系统上典型的/etc/passwd文件的一个例子。
[root@localhost tmp]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
root用户账户是Linux系统的管理员,固定分配给它的UID是 0 。就像上例中显示的,Linux系统会为各种各样的功能创建不同的用户账户,而这些账户并不是真的用户。这些账户叫作系统账户,是系统上运行的各种服务进程访问资源用的特殊账户。所有运行在后台的服务都需要用一个系统用户账户登录到Linux系统上。
在安全成为一个大问题之前,这些服务经常会用root账户登录。遗憾的是,如果有非授权的用户攻陷了这些服务中的一个,他立刻就能作为root用户进入系统。为了防止发生这种情况,现在运行在Linux服务器后台的几乎所有的服务都是用自己的账户登录。这样的话,即使有人攻入了某个服务,也无法访问整个系统。
Linux为系统账户预留了500以下的UID值。有些服务甚至要用特定的UID才能正常工作。为普通用户创建账户时,大多数Linux系统会从500开始,将第一个可用UID分配给这个账户(并非所有的Linux发行版都是这样)。
/etc/passwd文件包含了7个字段的信息,每个信息之间用:隔开,具体的信息含义如下:
-
登录用户名
-
用户密码
-
用户账户的UID(数字形式)
-
用户账户的组ID(GID)(数字形式)
-
用户账户的文本描述(称为备注字段)
-
用户HOME目录的位置
-
用户的默认shell
/etc/passwd文件中的密码字段都被设置成了x,这并不是说所有的用户账户都用相同的密码。
在早期的Linux上,/etc/passwd文件里有加密后的用户密码。但鉴于很多程序都需要访问
/etc/passwd文件获取用户信息,这就成了一个安全隐患。随着用来破解加密密码的工具的不断演进,用心不良的人开始忙于破解存储在/etc/passwd文件中的密码。Linux开发人员需要重新考虑这个策略。
现在,绝大多数Linux系统都将用户密码保存在另一个单独的文件中(叫作shadow文件,位置在/etc/shadow)。只有特定的程序(比如登录程序)才能访问这个文件。
/etc/passwd是一个标准的文本文件。你可以用任何文本编辑器在/etc/password文件里直接手动进行用户管理(比如添加、修改或删除用户账户)。但这样做极其危险。如果/etc/passwd文件出现损坏,系统就无法读取它的内容了,这样会导致用户无法正常登录(即便是root用户)。用标准的Linux用户管理工具去执行这些用户管理功能就会安全许多。
/etc/shadow文件
/etc/shadow文件对Linux系统密码管理提供了更多的控制。只有root用户才能访问/etc/shadow文件,这让它比起/etc/passwd安全许多。
/etc/shadow文件为系统上的每个用户账户都保存了一条记录。记录就像下面这样:
[root@localhost tmp]# cat /etc/shadow
root:$6$Ey4l/mJXzc7QRd./$QnD9WQYpZ1i98dduoD00kZ8Jzr6ojyL8gnQW.S2U6SwZmzDc8MXoSKJvFbYRj7igNfA0loLBj7VC1tokthMfu/::0:99999:7:::
bin:*:17834:0:99999:7:::
daemon:*:17834:0:99999:7:::
adm:*:17834:0:99999:7:::
lp:*:17834:0:99999:7:::
sync:*:17834:0:99999:7:::
shutdown:*:17834:0:99999:7:::
halt:*:17834:0:99999:7:::
mail:*:17834:0:99999:7:::
operator:*:17834:0:99999:7:::
games:*:17834:0:99999:7:::
ftp:*:17834:0:99999:7:::
nobody:*:17834:0:99999:7:::
systemd-network:!!:18241::::::
dbus:!!:18241::::::
polkitd:!!:18241::::::
libstoragemgmt:!!:18241::::::
abrt:!!:18241::::::
rpc:!!:18241:0:99999:7:::
sshd:!!:18241::::::
postfix:!!:18241::::::
ntp:!!:18241::::::
chrony:!!:18241::::::
tcpdump:!!:18241::::::
/etc/shadow文件包含了9个字段的信息,每个信息之间用:隔开,具体的信息含义如下:
-
与/etc/passwd文件中的登录名字段对应的登录名
-
加密后的密码
-
自上次修改密码后过去的天数密码(自1970年1月1日开始计算)
-
多少天后才能更改密码
-
多少天后必须更改密码
-
密码过期前提前多少天提醒用户更改密码
-
密码过期后多少天禁用用户账户
-
用户账户被禁用的日期(用自1970年1月1日到当天的天数表示)
-
预留字段给将来使用
使用shadow密码系统后,Linux系统可以更好地控制用户密码。它可以控制用户多久更改一
次密码,以及什么时候禁用该用户账户,如果密码未更新的话。
添加新用户
用来向Linux系统添加新用户的主要工具是 useradd 。这个命令简单快捷,可以一次性创建新用户账户及设置用户HOME目录结构。 useradd 命令使用系统的默认值以及命令行参数来设置用户账户。系统默认值被设置在/etc/default/useradd文件中。可以使用加入了 -D 选项的 useradd命令查看所用Linux系统中的这些默认值。
[root@localhost ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
说明 一些Linux发行版会把Linux用户和组工具放在/usr/sbin目录下,这个目录可能不在 PATH 环境变量里。如果你的Linux系统是这样的话,可以将这个目录添加进 PATH 环境变量,或者用绝对文件路径名来使用这些工具。
在创建新用户时,如果你不在命令行中指定具体的值, useradd 命令就会使用 -D 选项所显示的那些默认值。这个例子列出的默认值如下:
-
新用户会被添加到GID为 100 的公共组;
-
新用户的HOME目录将会位于/home/loginname;
-
新用户账户密码在过期后不会被禁用;
-
新用户账户未被设置过期日期;
-
新用户账户将bash shell作为默认shell;
-
系统会将/etc/skel目录下的内容复制到用户的HOME目录下;
-
系统为该用户账户在mail目录下创建一个用于接收邮件的文件。
倒数第二个值很有意思。 useradd 命令允许管理员创建一份默认的HOME目录配置,然后把它作为创建新用户HOME目录的模板。这样就能自动在每个新用户的HOME目录里放置默认的系统文件。
使用默认系统参数创建一个新用户账户,然后检查所创建的用户HOME目录。
[root@localhost ~]# useradd -m root1
[root@localhost ~]# ls -al /home/root1/
总用量 20
drwx------. 2 root1 root1 4096 1月 12 23:01 .
drwxr-xr-x. 3 root root 4096 1月 12 23:01 ..
-rw-r--r--. 1 root1 root1 18 10月 31 2018 .bash_logout
-rw-r--r--. 1 root1 root1 193 10月 31 2018 .bash_profile
-rw-r--r--. 1 root1 root1 231 10月 31 2018 .bashrc
默认情况下, useradd 命令不会创建HOME目录,但是 -m 命令行选项会使其创建HOME目录。你能在此例中看到, useradd 命令创建了新HOME目录,并将/etc/skel目录中的文件复制了过来。记得及时使用man useradd 或者 info useradd命令查看操作。
删除用户
如果你想从系统中删除用户, userdel 可以满足这个需求。默认情况下, userdel 命令会只删除/etc/passwd文件中的用户信息,而不会删除系统中属于该账户的任何文件。
如果加上 -r 参数, userdel 会删除用户的HOME目录以及邮件目录。然而,系统上仍可能存有已删除用户的其他文件。这在有些环境中会造成问题。
[root@localhost ~]# userdel -r root1(用户名称)
警告 在有大量用户的环境中使用 -r 参数时要特别小心。你永远不知道用户是否在其HOME目录下存放了其他用户或其他程序要使用的重要文件。记住,在删除用户的HOME目录之前一定要检查清楚!
修改用户
Linux提供了一些不同的工具来修改已有用户账户的信息。
命令 | 描述 |
---|---|
usermod | 修改用户账户的字段,还可以指定主要组以及附加组的所属关系 |
passwd | 修改已有用户的密码 |
chpasswd | 从文件中读取登录名密码对,并更新密码 |
chage | 修改密码的过期日期 |
chfn | 修改用户账户的备注信息 |
chsh | 修改用户账户的默认登录shell |
usermod
usermod 命令是用户账户修改工具中最强大的一个。它能用来修改/etc/passwd文件中的大部分字段,只需用与想修改的字段对应的命令行参数就可以了。参数大部分跟 useradd 命令的参数一样(比如, -c 修改备注字段, -e 修改过期日期, -g 修改默认的登录组)。除此之外,还有另外一些可能派上用场的选项。
-
-l 修改用户账户的登录名。
-
-L 锁定账户,使用户无法登录。
-
-p 修改账户的密码。
-
-U 解除锁定,使用户能够登录。
-L 选项尤其实用。它可以将账户锁定,使用户无法登录,同时无需删除账户和用户的数据。
要让账户恢复正常,只要用 -U 选项就行了。
passwd 和 chpasswd
改变用户密码的一个简便方法就是用 passwd 命令。
如果只用 passwd 命令,它会改你自己的密码。系统上的任何用户都能改自己的密码,但只有root用户才有权限改别人的密码。
-e 选项能强制用户下次登录时修改密码。你可以先给用户设置一个简单的密码,之后再强制在下次登录时改成他们能记住的更复杂的密码。
如果需要为系统中的大量用户修改密码, chpasswd 命令可以事半功倍。 chpasswd 命令能从标准输入自动读取登录名和密码对(由冒号分割)列表,给密码加密,然后为用户账户设置。你也可以用重定向命令来将含有 userid:passwd 对的文件重定向给该命令。
chsh 、 chfn 和 chage
chsh 、 chfn 和 chage 工具专门用来修改特定的账户信息。 chsh 命令用来快速修改默认的用户登录shell。使用时必须用shell的全路径名作为参数,不能只用shell名。
chfn 命令提供了在/etc/passwd文件的备注字段中存储信息的标准方法。 chfn 命令会将用于Unix的 finger 命令的信息存进备注字段,而不是简单地存入一些随机文本(比如名字或昵称之类的),或是将备注字段留空。 finger 命令可以非常方便地查看Linux系统上的用户信息。
[root@localhost ~]# finger rich
Login: rich Name: Rich Blum
Directory: /home/rich Shell: /bin/bash
On since Thu Sep 20 18:03 (EDT) on pts/0 from 192.168.1.2
No mail.
No Plan.
说明 出于安全性考虑,很多Linux系统管理员会在系统上禁用 finger 命令,不少Linux发行版甚至都没有默认安装该命令。
linux组
/etc/group文件
与用户账户类似,组信息也保存在系统的一个文件中。/etc/group文件包含系统上用到的每个组的信息。下面是一些来自Linux系统上/etc/group文件中的典型例子。
[root@localhost ~]# cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:
cdrom:x:11:
mail:x:12:postfix
和UID一样,GID在分配时也采用了特定的格式。系统账户用的组通常会分配低于500的GID值,而用户组的GID则会从500开始分配。/etc/group文件有4个字段:
-
组名
-
组密码
-
GID
-
属于该组的用户列表
组密码允许非组内成员通过它临时成为该组成员。这个功能并不很普遍,但确实存在。
千万不能通过直接修改/etc/group文件来添加用户到一个组,要用 usermod 命令。在添加用户到不同的组之前,首先得创建组。
创建组
groupadd 命令可在系统上创建新组。
[root@localhost ~]# groupadd shared
在创建新组时,默认没有用户被分配到该组。 groupadd 命令没有提供将用户添加到组中的选项,但可以用 usermod 命令来弥补这一点。
[root@localhost ~]# usermod -G shared shared01
说明如果更改了已登录系统账户所属的用户组,该用户必须登出系统后再登录,组关系的更改才能生效。
警告为用户账户分配组时要格外小心。如果加了 -g 选项,指定的组名会替换掉该账户的默认组。 -G 选项则将该组添加到用户的属组的列表里,不会影响默认组。
修改组
在/etc/group文件中可以看到,需要修改的组信息并不多。 groupmod 命令可以修改已有组的GID(加 -g 选项)。
文件权限
文件权限符
[root@localhost /]# ll
总用量 60
lrwxrwxrwx. 1 root root 7 12月 12 08:36 bin -> usr/bin
dr-xr-xr-x. 6 root root 4096 12月 12 08:43 boot
drwxr-xr-x. 19 root root 3200 1月 12 22:39 dev
drwxr-xr-x. 84 root root 4096 1月 12 23:22 etc
drwxr-xr-x. 3 root root 4096 1月 12 23:22 home
lrwxrwxrwx. 1 root root 7 12月 12 08:36 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 12月 12 08:36 lib64 -> usr/lib64
drwx------. 2 root root 16384 12月 12 08:36 lost+found
drwxr-xr-x. 2 root root 4096 4月 11 2018 media
drwxr-xr-x. 2 root root 4096 4月 11 2018 mnt
drwxr-xr-x. 3 root root 4096 12月 12 08:38 opt
dr-xr-xr-x. 101 root root 0 1月 12 22:39 proc
dr-xr-x---. 4 root root 4096 1月 12 21:23 root
drwxr-xr-x. 29 root root 880 1月 12 22:39 run
lrwxrwxrwx. 1 root root 8 12月 12 08:36 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 4月 11 2018 srv
dr-xr-xr-x. 13 root root 0 1月 12 22:39 sys
drwxrwxrwt. 15 root root 4096 1月 12 23:23 tmp
drwxr-xr-x. 13 root root 4096 12月 12 08:36 usr
drwxr-xr-x. 20 root root 4096 12月 12 08:50 var
输出结果的第一个字段就是描述文件和目录权限的编码。这个字段的第一个字符代表了对象
的类型:
-
- 代表文件
-
d 代表目录
-
l 代表链接
-
c 代表字符型设备
-
b 代表块设备
-
n 代表网络设备
之后有3组三字符的编码。每一组定义了3种访问权限:
-
r 代表对象是可读的
-
w 代表对象是可写的
-
x 代表对象是可执行的
若没有某种权限,在该权限位会出现单破折线。这3组权限分别对应对象的3个安全级别:
-
对象的属主
-
对象的属组
-
系统其他用户
默认文件权限
你可能会问这些文件权限从何而来,答案是 umask 。 umask 命令用来设置所创建文件和目录的默认权限。
[root@localhost ~]# touch newfile
[root@localhost ~]# ll | grep newfile
-rw-r--r--. 1 root root 0 1月 12 23:29 newfile
touch 命令用分配给我的用户账户的默认权限创建了这个文件。 umask 命令可以显示和设置这个默认权限。
[root@localhost ~]# umask
0022
第一位代表了一项特别的安全特性,叫作粘着位(sticky bit)。后面的3位表示文件或目录对应的 umask 八进制值。要理解 umask 是怎么工作的,得先理解八进制模式的安全性设置。
八进制模式的安全性设置先获取这3个 rwx 权限的值,然后将其转换成3位二进制值,用一个八进制值来表示。在这个二进制表示中,每个位置代表一个二进制位。因此,如果读权限是唯一置位的权限,权限值就是 r-- ,转换成二进制值就是 100 ,代表的八进制值是 4 。
了解八进制模式权限是怎么工作的之后, umask 值反而更叫人困惑了。我的Linux系统上默认的八进制的 umask 值是 0022 ,而我所创建的文件的八进制权限却是 644 ,这是如何得来的呢?
umask 值只是个掩码。它会屏蔽掉不想授予该安全级别的权限。接下来我们还得再多进行一些八进制运算才能搞明白来龙去脉。
要把 umask 值从对象的全权限值中减掉。对文件来说,全权限的值是 666 (所有用户都有读和写的权限);而对目录来说,则是 777 (所有用户都有读、写、执行权限)。
所以在上例中,文件一开始的权限是 666 ,减去 umask 值 022 之后,剩下的文件权限就成了 644 。
安全性设置
权限 | 二进制值 | 八进制值 | 描述 |
---|---|---|---|
— | 000 | 0 | 没有任何权限 |
–x | 001 | 1 | 只有执行权限 |
-w- | 010 | 2 | 只有写入权限 |
-wx | 011 | 3 | 有写入和执行权限 |
r– | 100 | 4 | 只有读取权限 |
r-x | 101 | 5 | 有读取和执行权限 |
rw- | 110 | 6 | 有读取和写入权限 |
rwx | 111 | 7 | 有全部权限 |
改变权限
chmod 命令用来改变文件和目录的安全性设置。该命令的格式如下:
chmod options mode file
mode 参数可以使用八进制模式或符号模式进行安全性设置。八进制模式设置非常直观,直接用期望赋予文件的标准3位八进制权限码即可。
[root@localhost ~]# chmod 666 newfile
[root@localhost ~]# ll
总用量 8
-rw-rw-rw-. 1 root root 0 1月 12 23:29 newfile
改变文件所属关系
有时你需要改变文件的属主,比如有人离职或开发人员创建了一个在产品环境中需要归属在
系统账户下的应用。Linux提供了两个命令来实现这个功能: chown 命令用来改变文件的属主,chgrp 命令用来改变文件的默认属组。
chown 命令的格式如下。
chown options owner[.group] file
[root@localhost ~]# ll
总用量 8
-rw-rw-rw-. 1 root root 0 1月 12 23:29 newfile
[root@localhost ~]# chown shared01 newfile
[root@localhost ~]# ll
总用量 8
-rw-rw-rw-. 1 shared01 root 0 1月 12 23:29 newfile
[root@localhost ~]#
chown 命令也支持同时改变文件的属主和属组。
[root@localhost ~]# chown shared01.shared newfile
[root@localhost ~]# ll
总用量 8
-rw-------. 1 root root 1289 12月 12 08:43 anaconda-ks.cfg
-rw-------. 1 root root 1575 1月 12 21:23 anaconda-ks.cfg.bak
-rw-rw-rw-. 1 shared01 shared 0 1月 12 23:29 newfile
[root@localhost ~]#