本章内容
- 理解Linux的安全性
- 解码文件权限
- 操作Linux组
缺乏安全的系统不是完整的系统。系统上必须要有一套保护文件不被非授权用户访问或
修改的机制。Linux沿用了Unix文件权限的办法,即允许用户和组基于每个文件和目录的
一组安全性设置访问文件。本章将介绍如何用Linux文件安全系统来在需要时共享数据和保护
数据。
6.1 Linux的安全性
Linux安全系统的核心是用户账户。每个能进入Linux系统的用户都会被分配一个唯一的用户
账户。用户对系统上对象的访问权限取决于他们登录系统时用的账户。
Linux系统使用特定的文件和工具来跟踪和管理系统上的用户账户。在我们讨论文件权限之前,
先来看一下Linux是怎样处理用户账户的。本节会介绍管理用户账户需要的文件和工具,这样
在处理文件权限问题时,你就知道如何使用它们了。
6.1.1 /etc/passwd文件
Linux 系统使用一个专门的文件来将用户的登录名匹配到对应的UID值。这个文件就是
/etc/passwd文件,它包含了一些与用户有关的信息。下面是Linux系统上典型的/etc/passwd文件的一个
例子:
[jingpan@localhost ~]$ 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 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin haldaemon:x:68:68:HAL daemon:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin saslauth:x:498:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin jingpan:x:500:500::/home/jingpan:/bin/bash radvd:x:75:75:radvd user:/:/sbin/nologin qemu:x:107:107:qemu user:/:/sbin/nologin nignx:x:501:502::/home/nignx:/sbin/nologin nginx:x:502:503::/home/nginx:/sbin/nologin
root用户账户是Linux系统的管理员,通常分配给它的UID是0。就像上便中显示的,Linux系统会为各种各样的功能创建
不同的用户账户,而这些账户并不是真的用户。这些账户称作系统账户,是系统上运行的各种服务进程访问资源用的特殊
账户。所有运行在后台的服务都需要用一个系统账户登录到Linux系统。
在安全成为一个问题之前,这些服务经常会用根账户登录。遗憾的是,如果有非授权的用户攻入了这些服务中的一上,他就能
作为root用户进入整个系统了。为了防止这种情况发生,现在几乎每个Linux服务器上后台运行的服务都有自己的用户账户。这样,即使有人攻入了某个服务,他也无法访问整个系统。
Linux为系统账户预留了500以下的UID值。有些服务甚至要用特定的UID才能正常工作。为普通用户创建账户时,
大多数Linux系统会将500起始的第一个可用UID分配给这个账户(这未必适用所有的Linux发行版)。
你可能已经注意到/etc/passwd文件还有很多用户登录名和UID之外的信息。/etc/passwd文件的字段包含离如下 信息"
- 登录用户名;
- 用户密码;
- 用户账户的UID;
- 用户账户的文本描述(称为备注字段);
- 用户HOME目录的位置;
- 用户的默认shell。
/etc/passwd文件中的密码字段都被设置成了x,这并不是说所有的账户都用相同的密码。
在早期的Linux上,/etc/passwd文件里有加密后的用户密码。但鉴于很多程序都需要访问/etc/passwd文件获取用户
信息,这就成了一个安全隐患。随着用来破解加密过的密码的工具的不断演进,用心不良的人开始忙于破解存储在
/etc/passwd文件中的密码。Linux开发人员需要生新构思这个策略。
现在,Linux系统将用户密码保存在另一个单独的文件中(称为shadow文件,位置在/etc/shadow)。只有特定的程序
才能访问这个文件,比如登录程序。
你已经看到了,/etc/passwd是标准的文本文件。你可以用任何文本编辑器来直接手动的在/etc/passwd文件里进行用户管理,
比如添加、修改或删除用户账户。但这样做极其危险,如果/etc/passwd文件损坏了,系统就无法读取它的内容了,这样用户就
无法正常登录了,甚至边root用户也会无法登录。用标准的Linux用户管理工具去执行这些用户管理功能就会安全许多。
6.1.2 /etc/shadow文件
/etc/shadow文件为系统上的每个用户保存了一条记录。记录就像下面这样:
jingpan:$6$j9ozJNNtxlogC/dq$/kQG9DOUIjLZHFKJfR5TTmFg88iA3qphdkmOOhZlixywruYwbrvKs/Uf1httIEecB/EMsQ7ChJCHHOfuLRzG/0:17476:0:99999:7:::
在/etc/shadow文件的每条记录中有9个字段:
- 与/etc/passwd文件中的登录名对应的登录名:
- 加密后的密码;
- 自1970年1月1日(上次修改密码的日期)到当天的天数;
- 多少天后才能更改密码;
- 多少天后必须更改密码;
- 密码过期前提前多少天提醒用户更改密码;
- 密码过期后多少天禁用用户账户;
- 用户账户被禁用的日期,用自1970年1月1日到当月天的天数表示;
- 预留字段,给将来使用。
使用shadow密码后,Linux系统可以更好地控制用户密码了。它可以控制用户多久更改
一次密码,以及密码未更新的话多久后禁用该用户账户。
6.1.3 添加新用户
添加新用户到Linux系统的工具是useradd。 这个命令提供了一次性创建新用户及设置用户HOME目录结构的简便方法。
可以用useradd 命令加-D参数来查看你的Linux系统的默认值:
[root@localhost jingpan]# useradd -D GROUP=100 HOME=/home INACTIVE=-1 EXPIRE= SHELL=/bin/bash SKEL=/etc/skel CREATE_MAIL_SPOOL=yes
-D 参数显示了在创建新用户时如果你不在命令行指定的话useradd命令将使用的默认值。这个例子列出了这些默认修士:
- 新用户会被添加到GID为100的公共组;
- 新用户的HOME目录将会位于/home/loginname;
- 新用户账户密码在过期后不会被禁用;
- 新用户账户未被设置为某个日期后就过期;
- 新用户账户将bash shell作为默认shell;
- 系统会将/etc/skel目录下的内容复制到用户的HOME目录下;
- 系统为该用户账户在mail目录下创建一个用于接收邮件的文件。
[root@localhost jingpan]# ls -al /etc/skel/ 总用量 36 drwxr-xr-x. 4 root root 4096 11月 8 08:47 . drwxr-xr-x. 121 root root 12288 3月 15 15:40 .. -rw-r--r-- 1 root root 18 3月 23 2017 .bash_logout -rw-r--r-- 1 root root 176 3月 23 2017 .bash_profile -rw-r--r-- 1 root root 124 3月 23 2017 .bashrc drwxr-xr-x. 2 root root 4096 11月 12 2010 .gnome2 drwxr-xr-x. 4 root root 4096 11月 6 11:36 .mozilla
这些文件是bash shell环境的标准启动文件。系统会自动将这些默认文件复制到你创建的每个用户的HOME目录。
你可以用默认系统参数创建一个新用户账户试一下,并检查一下新用户的HOME目录:
[root@localhost jingpan]# useradd -m test [root@localhost jingpan]# ls -al /home/test/ 总用量 28 drwx------ 4 test test 4096 3月 15 15:59 . drwxr-xr-x. 5 root root 4096 3月 15 15:59 .. -rw-r--r-- 1 test test 18 3月 23 2017 .bash_logout -rw-r--r-- 1 test test 176 3月 23 2017 .bash_profile -rw-r--r-- 1 test test 124 3月 23 2017 .bashrc drwxr-xr-x 2 test test 4096 11月 12 2010 .gnome2 drwxr-xr-x 4 test test 4096 11月 6 11:36 .mozilla
默认情况下,useradd命令不会创建HOME目录,但是-m命令行选项会叫它创建HOME目录。
你能在例子中看到。useradd 命令创建了新的HOME目录,并将/etc/skel目录中的文件复制了过来。
你可以用-D参数后跟一个代表要修改的值的参数,来修改系统默认的新用户值。
更改默认值非常简单:
[root@localhost jingpan]# useradd -D -s /bin/tsch [root@localhost jingpan]# useradd -D GROUP=100 HOME=/home INACTIVE=-1 EXPIRE= SHELL=/bin/tsch SKEL=/etc/skel CREATE_MAIL_SPOOL=yes
6.1.4 删除用户
如果你想从系统中删除用户,userdel可以满足这个需求。默认情况下,userdel命令会只删除/etc/passwd文件中
的用户信息,而不会删除系统中属于该 账户的任何文件。
如果加上-r参数,userdel会删除用户的HOME目录以及mail目录。然而,系统上仍可能存有归已删除用户所有的其他文件。
这在有些环境中会造成问题。
下面是用userdel命令删除已有用户账户的一个例子:
[root@localhost jingpan]# userdel -r test [root@localhost jingpan]# ls -al /home/test ls: 无法访问/home/test: 没有那个文件或目录 [root@localhost jingpan]#
加了-r参数后,用户之前的那个/home/test目录已经不存在了。
_____________________________________________________________________________________________________
警告:在有大量用户的环境中使用-r参数时要特别小心。你永远不知道用户是否在他的HOME目录下存放了
其他用户或其他程序要使用的重要文件。记住在删除用户的HOME目录之前一定要检查清楚!
——————————————————————————————————————————————
6.1.5 修改用户
Linux提供了一些不同的工具来修改已有用户账户信息。表6-3列出了这些工具。
命令 描述
usermod 修改用户账户的字段,并可以指定主要组以及附加组的所属关系
passwd 修改已有用户的密码
chpasswd 从文件中读取登录名密码对,并更新密码
chage 修改密码的过期日期
chfn 修改用户账户的备注信息
chsh 修改用户账户的默认登录shell
1.usermod
usermod命令是用户账户修改工具中最强大的一个。它能用来修改/etc/passwd文件中的大部分字段,只需用与想修改的字段对应的命令行参数就可以了。参数大部分跟useradd命令的参数一样,比如-c用来修改备注字段,-e用来修改过期日期,-g用来修改默认的登录组。但还有一些实用的额外参数:
-L用来锁定账户,这样用户就无法登录了;
-U用来解除锁定,解除后用户就能登录了。
-L参数尤其实用。用这个参数就把账户锁定,用户就无法登录了,而不用删除账户和用户的数据。要让账户恢复正常,保要加-U参数就行了。
2.passwd和chpasswd
如果只用passwd命令,它会改变你自己的密码。系统上的任何用户都能改变他自己的密码,但只有root用户才有权限改变别人的密码。
-e选项能强制用户下次便当时修改密码。
chpasswd命令能让事情简单许多。chpasswd命令能从标准输入自动读取登录名和密码对(由冒号分割)列表,给密码加密,然后为用户账户设置。
3.chsh、chfn和chage工具专门用来修改特定的账户信息。chsh命令用来快速修改默认用户登录shell。使用时必须用shell的全路径名作为参数,不能只用shell名:
[root@localhost ~]# chsh -s /bin/bash test Changing shell for test. Shell changed.
chfn命令提供了在/etc/passwd文件的备注字段中存储信息的标准方法。chfn命令将Unix的finger命令用到
的信息存进备注字段,而不是简单地存入一些随机文本(比如昵称之类的),或是将字段留空。finger命令可以用来
简单地查看Linux系统上的用户信息:
[root@localhost ~]# finger jingpan Login: jingpan Name: Directory: /home/jingpan Shell: /bin/bash On since 五 3月 16 14:27 (CST) on pts/0 from 192.168.1.64 No mail. No Plan.
说明 出于安全性的考虑,很多Linux系统管理员在系统上禁用finger命令。
如在使用chfn命令时不加参数,它会向你询问要存进备注字段的恰当值:
[root@localhost ~]# chfn test Changing finger information for test. Name [test]: IMa Test Office [Director of Technology]: Office Phone [123456]: (123)555-1234 Home Phone [12345677]: (123)555-9876 Finger information changed. [root@localhost ~]# finger test Login: test Name: IMa Test Directory: /home/test Shell: /bin/bash Office: Director of Technology Office Phone: (123)555-1234 Home Phone: (123)555-9876 On since 五 3月 16 14:59 (CST) on pts/2 from 192.168.1.64 45 minutes 36 seconds idle No mail. No Plan. [root@localhost ~]#
查看/etc/passwd文件中的记录,你会看到下面这样的结果:
[root@localhost ~]# grep test /etc/passwd test:x:503:504:IMa Test,Director of Technology,(123)555-1234,(123)555-9876:/home/test:/bin/bash
最后 ,chage命令用来帮助管理用户账户的有效期。
chage命令的日期值可以用下面两种方式中的任意一种:
YYYY-MM-DD格式的日期;
代表从1970年1月1日起到该日期天数的数值。
chage命令中有个好用的功能是设置账户的过期日期。通过它,你就能创建临时用户了。设定的
日期一过,临时账户就会自动过期,而不需要记住在那天去删除这些账户。过期的账户跟锁定的
账户很相似: 账户仍然存在,但用户无法用它登录。
6.2 使用Linux组
用户账户在控制单个用户安全方面很惯用,但他们在允许一组用户共享资源时就捉襟见肘了。为了达到这个目的,Linux系统用了另外一给概念-----组(group)。
组权限允许多个用户共享一组共用的权限来访问系统上的对象,比如文件、目录或设备之类(会在6.3节中细述)。
每个组都有一个唯一的GID----跟UID类似,在系统上这是个唯一的数值。和GID一起的,每个给还有一个唯一的组名。Linux系统上有一些组工具可以用来创建和管理你自己的组。本节将细述组信息是如何保存的,以及如何用组工具来创建新组、修改已有的组。
6.2.1 /etc/group文件
类似于用户账户,组信息也保存在系统的一个文件中。/etc/group文件包含系统上用到的每个给信息。下面是一些来自Linux 系统上/etc/group文件中典型例子:
[jingpan@localhost ~]$ cat /etc/group root:x:0: bin:x:1:bin,daemon daemon:x:2:bin,daemon sys:x:3:bin,adm adm:x:4:adm,daemon tty:x:5: disk:x:6: lp:x:7:daemon mem:x:8: kmem:x:9: wheel:x:10: mail:x:12:mail,postfix uucp:x:14: man:x:15: games:x:20: gopher:x:30: video:x:39: dip:x:40: ftp:x:50: lock:x:54: audio:x:63: nobody:x:99: users:x:100: dbus:x:81: usbmuxd:x:113: rpc:x:32: utmp:x:22: utempter:x:35: rtkit:x:499: avahi-autoipd:x:170: desktop_admin_r:x:498: desktop_user_r:x:497: floppy:x:19: vcsa:x:69: abrt:x:173: cdrom:x:11: tape:x:33: dialout:x:18: wbpriv:x:88: rpcuser:x:29: nfsnobody:x:65534: haldaemon:x:68:haldaemon ntp:x:38: apache:x:48: saslauth:x:76: postdrop:x:90: postfix:x:89: gdm:x:42: pulse:x:496: pulse-access:x:495: fuse:x:494: sshd:x:74: slocate:x:21: stapusr:x:156: stapsys:x:157: stapdev:x:158: tcpdump:x:72: jingpan:x:500: cgred:x:493: radvd:x:75: kvm:x:36:qemu qemu:x:107: nogroup:x:501: nignx:x:502: nginx:x:503: test:x:504:
类似于UID,GID也是用特有的格式分配的。系统账户用的组通常会分配低于500的GID值,而用户组的GID会从500开始分配。/etc/group文件有4个字段:
组名;
组密码;
GID;
属于该给的用户列表。
组密码允许非组内成员通过它临时性地成为该组成员。这个功能并不是非常通用,但确实存在。
千万不能直接修改/etc/group文件来添加用户到一个组,而要用usermod命令(在6.1节中介绍过)来添加。在添加用户到不同
的组之前,首先得创建组。
———————————————————————————————————————
说明 用户账户列表某种意义上有些误导人。你会发现在列表中,有些组并没有列出用户。这并不是说,这些给没有成员。
当一个用户在/etc/passwd文件中指定某个给作为默认给时,用户账户不会作为该组成员再出现在/etc/group文件中。多年
来被这人问题难倒过的系统管理员可不是一个两个。
______________________________________________________________________________________________
6.2.2 创建新组
groupadd命令用来在系统上创建新组:
[root@localhost jingpan]# /usr/sbin/groupadd shared [root@localhost jingpan]# tail /etc/group jingpan:x:500: cgred:x:493: radvd:x:75: kvm:x:36:qemu qemu:x:107: nogroup:x:501: nignx:x:502: nginx:x:503: test:x:504: shared:x:505:
在创建新组时,默认没用用户属于该给成员。groupadd命令没有提供将用户添加到组的选项,
但可以用usermod命令添加用户到该组:
[root@localhost jingpan]# /usr/sbin/usermod -G shared rich [root@localhost jingpan]# /usr/sbin/usermod -G shared test [root@localhost jingpan]# tail /etc/group cgred:x:493: radvd:x:75: kvm:x:36:qemu qemu:x:107: nogroup:x:501: nignx:x:502: nginx:x:503: test:x:504: shared:x:505:test,rich rich:x:506: [root@localhost jingpan]#
shared组在有两个成员,test和rich。usermod命令的-G参数会把这个新组添加到用户账号的组列表里。
______________________________________________________________________________________________
说明 如果更改了已登录系统账户所属的用户组,该用户必须登出系统扣再登录,组关系的更改才能生效。
________________________________________________________________________________________
++++++++++++++++++++++++++++++++++++++++++++++++++++++
警告 在将组添加到用户账户时要格外小心。如果加了-g参数,指定的给名会替换掉该账户的默认组。-G参数则将该给添加到用户的属组的列表里,而不会影响默认组。
++++++++++++++++++++++++++++++++++++++++++++++++++++++
6.2.3 修改组
我们在/etc/group文件中看到,组信息并不多,也没什么可修改的。groupmod命令可以修改已有给的GID(加-g参数)或组名(加-n参数):
[root@localhost jingpan]# /usr/sbin/groupmod -n sharing shared [root@localhost jingpan]# tail /etc/group cgred:x:493: radvd:x:75: kvm:x:36:qemu qemu:x:107: nogroup:x:501: nignx:x:502: nginx:x:503: test:x:504: rich:x:506: sharing:x:505:test,rich [root@localhost jingpan]#
修改组名时,GID和组成员不会变,只有给名会改变。由于的有的安全权限都是基于GID的,
你可以随意改变组名而不会影响文件的安全性。
6.3 理解文件权限
现在你已经了解了用户和组,可以进一步了解ls命令时输出的神秘文件权限了。本节将会介绍如何对权限进行解码以及它们来来历。
6.3.1 使用文件权限符
如果你还记得第3章,那应该知道ls命令可以用来查看Linux系统上的文件、目录和设备的权限:
[root@localhost linux]# ls -l 总用量 496 drwxr-xr-x 2 root root 4096 2月 28 11:40 ch4 -rw-rw-r-- 1 jingpan jingpan 245760 2月 28 16:55 ch4.tar -rw-r--r-- 1 root root 230903 2月 28 11:32 ch4.zip drwxr-xr-x 2 root root 4096 3月 3 10:30 ch5 drwxrwxr-x 2 jingpan jingpan 4096 1月 30 15:06 dir1 drwxrwxr-x 2 jingpan jingpan 4096 1月 30 15:07 dir2 -rwxr-xr-x 1 root root 6469 3月 3 09:52 myprog -rw-rw-r-- 1 jingpan jingpan 11 1月 30 15:33 test1 -rw-rw-r-- 1 jingpan jingpan 0 1月 30 15:00 test2 -rw-rw-r-- 1 jingpan jingpan 0 1月 30 14:57 test3 -rw-rw-r-- 1 jingpan jingpan 0 1月 30 15:35 test4 lrwxrwxrwx 1 jingpan jingpan 5 1月 30 15:36 test5 -> test1 [root@localhost linux]#
输出结果的第一个字段是描述文件和目录权限的码。这个字段的第一个字符代表了对象的类型:
-代表文件;
d代表目录;
l代表链接;
c代表字符型设备;
b代表块设备
n代表网络设备。
之后有3组三字符的码。每一组三字符码表示三重访问权限:
r代表对象是可读的;
w代表对象是可写的;
x代表对象是可执行的。
如果没有某种权限,在该权限位会出现单破折线。这3组三字码分别对应对象的3个安全级别:
对象的属主;
对象的属组;
系统其他用户。
6.3.2 默认文件权限
[jingpan@localhost ~]$ touch newfile [jingpan@localhost ~]$ ls -al newfile -rw-rw-r-- 1 jingpan jingpan 0 3月 30 11:51 newfile [jingpan@localhost ~]$ umask 0002 [jingpan@localhost ~]$
文件,全权限的值是666(所用用户都有读和写的权限),而对于目录来说,是777(所有用户都有读、写、执行权限)。在上面的例子中,
文件一开始的权限是666,然后umask值002作用后,剩下的文件权限就成了664
umask值通常会在/etc/profile启动文件中设置,你可以用umask命令为默认umask设置指定一个新值:
[jingpan@localhost ch6]$ umask 026 [jingpan@localhost ch6]$ touch newfile2 [jingpan@localhost ch6]$ ls -l newfile2 -rw-r----- 1 jingpan jingpan 0 4月 4 08:38 newfile2
在把umask值设成026后,默认的文件权限变成了640,因此新文件现在对属组成员来说是只读的,而系统里的其他成员则没有任何权限。
umask值同样会作用在创建目录上:
[jingpan@localhost ch6]$ ls -l 总用量 4 drwxr-x--x 2 jingpan jingpan 4096 4月 4 08:48 newdir -rw-r----- 1 jingpan jingpan 0 4月 4 08:38 newfile2
由于目录的默认权限是777,umask作用后生成目录权限不同于生成的文件权限。umak会从777
中减去,留下来751作为目录权限设置。