linux系统内有档案有三种身份 u:拥有者 g:群组 o:其他人
r: 读权限,用户可以读取文档的内容,如用cat,more查看
w: 写权限,用户可以编辑文档
x: 该目录具有可以被系统执行的权限
x权限说明:
如果目录具有 x 权限,例如 drwx–x–x,则所属组和其它用户都可以进入该目录,并可以查看该目录下的文件的内容,但是不能使用ls命令查看该目录下的内容,不能在该目录下创建文件或目录:
先来看看几个特殊的文件与目录
[root@yufei ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 26968 Jan 29 2010 /usr/bin/passwd
[root@yufei ~]# ls -l /usr/bin/wall
-r-xr-sr-x. 1 root tty 10932 Apr 27 2010 /usr/bin/wall
[root@yufei ~]# ls -ld /tmp/
drwxrwxrwt. 7 root root 4096 Jan 20 11:00 /tmp/
这一个passwd命令在所有者的地方多了一个s,第二个wall命令在用户组的位置多了一个s,第三个tmp目录,多了一个t。
关于linux中 s、t权限的说明
LINUX中除了r w x 三个权限外(分别代表r 读,w 写,x 执行),其实还有两个特殊的权限s跟t
(除了读写执行权限外系统还支持强制位(setuid和setgid)和粘滞位(sticky))
setuid: 设置使文件在执行阶段具有文件拥有者的权限,相当于临时拥有文件拥有者的身份.
setgid:当s权限在文件组 x 权限上时,执行者在执行该文件时将具有该文件所属组的权限。
sticky背景:
要删除一个文档,您不一定要有这个文档的写权限,但您一定要有这个文档的上级目录的写权限。也就是说,您即使没有一个文档的写权限,但您有这个文档的上级目录的写权限,您也能够把这个文档给删除,而假如没有一个目录的写权限,也就不能在这个目录下创建文档。
sticky作用:
怎样才能使一个目录既能够让任何用户创建文档,又不让用户删除这个目录下他人的文档,sticky就是能起到这个作用。stciky一般只用在目录上,用在文档上起不到什么作用。
sticky:当t权限在other x权限上时,任何人都可以在目录内新增、修改文件,但是只有该文件或目录的建立者与root用户能够删除自己的文件或目录。
系统是这样规定的, 假如本来在该位上有x, 则这些特别标志 (suid, sgid, sticky) 显示为小写字母 (s, s, t).否则, 显示为大写字母 (S, S, T) 。
有时候的小s和小t变成了大S和大T了,为什么呢?因为他们这个位置没有了x权限,如果没有了x权限,其实,这个特殊的权限就相当于一个空的权限,没有意义。
对应指令:
SUID: chmod u+s 文件
SGID: chmod g+s 文件
SBIT: chmod o+t 目录
另外:
u+i:不可修改权限 例:chattr u+i filename 则filename文件就不可修改,无论任何人,如果需要修改需要先删除i权限,用chattr -i filename就可以了。查看文件是否设置了i权限用lsattr filename。
u+a:只追加权限, 对于日志系统很好用,这个权限让目标文件只能追加,不能删除,而且不能通过编辑器追加。可以使用chattr +a设置追加权限。
当s这个标志出现在文件拥有者的x权限上时,如/usr/bin/passwd这个文件的权限状态:“-rwsr-xr-x.”,此时就被称为Set UID,简称为SUID。
1、SUID权限仅对二进制程序(binary program)有效;
2、任何人对于该程序都具有x的可执行权限;
3、本权限仅在执行该程序的过程中有效(run-time);
SUID的目的就是:让本来没有相应权限的用户可以运行这个程序
注:SUID只能运行在二进制的程序上(系统中的一些命令),不能用在脚本上(script),因为脚本还是把很多的程序集合到一起来执行,而不是脚本自身在执行。同样,这个SUID也不能放到目录上,放上也是无效的。
passwd就是一个很鲜明的例子,下面我们就来了解一下这相passwd执行的过程。
我们知道,系统中的用户密码是保存在/etc/shadow中的,而这个文件的权限是———-. (有的系统是-r——–)。其实有没有r权限不重要,因为我们的root用户是拥有最高的权限,什么都能干了。关键是要把密码写入到/etc/shadow中。
我们知道,除了root用户能修改密码外,用户自己同样也能修改密码,为什么没有写入权限,还能修改密码,就是因为这个SUID功能。
passwd这个命令的执行过程如下:
1、因为/usr/bin/passwd的权限对任何的用户都是可以执行的,所以系统中每个用户都可以执行此命令。
2、而/usr/bin/passwd这个文件的拥有者是属于root的。
3、当某个用户执行/usr/bin/passwd命令的时候,就拥有了root的权限了。
4、于是某个用户就可以借助root用户的权力,来修改了/etc/shadow文件了。
5、最后,把密码修改成功。
看SUID的作用及设置
[root@yufei ~]# cd /tmp/
[root@yufei tmp]# cp /usr/bin/passwd ./
[root@yufei tmp]# mkdir testdir
上面两步是在/tmp目录下创建passwd文件和testdir目录
下面看看这两个的权限
注意:这里cp过来的passwd文件,其属性权限是变了的。
[root@yufei tmp]# ls -l passwd ; ls -ld testdir/
-rwxr-xr-x. 1 root root 26968 Jan 20 23:27 passwd
drwxr-xr-x. 2 root root 4096 Jan 20 19:25 testdir/
我们切换到yufei用户,然后修改自己的密码
[root@yufei tmp]# su yufei
[yufei@yufei tmp]$ ./passwd
Changing password for user yufei.
Changing password for yufei.
(current) UNIX password:
New password:
Retype new password:
passwd: Authentication token manipulation error
发现上面的yufei改不了自己的密码,为什么呢?
就是因为目录里的passwd文件是root用户的, yufei虽然有执行权限,但是该passwd需要写/etc/shadow文件, 而/etc/shadow文件属于root用户所有, yufei没有权限把密码写入到/etc/shadow中。想让普通用户能修改/etc/shadow的话,那就需要用到SUID了,让执行passwd文件的执行者瞬时有拥有者的权限。
[yufei@yufei tmp]$ su root
Password:
[root@yufei tmp]# chmod u+s passwd
[root@yufei tmp]# ls -l passwd
-rwsr-xr-x. 1 root root 26968 Jan 20 23:27 passwd
看到有SUID权限了,下面再来修改yufei自己的密码
[yufei@yufei tmp]$ ./passwd
Changing password for user yufei.
Changing password for yufei.
(current) UNIX password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
我们发现已经成功了。
我想这一下,你对SUID的作用已经了解了吧。
如果想把这个改回来(就是把SUID的权限去掉),我们用数字方式来设置
[root@yufei tmp]# chmod 0755 passwd
[root@yufei tmp]# ls -l passwd
-rwxr-xr-x. 1 root root 26968 Jan 20 23:27 passwd
注:在普通用户修改自己的密码是,密码要设置的复杂点,否则的话,通过不了认证,普通用户和root用户的权限是不同的。
把这个s放到文件的所属用户组x位置上的话,就是SGID。 即: 执行者在执行该文件时将具有该文件所属组的权限。
1、SGID对二进制程序有用;
2、程序执行者对于该程序来说,需具备x的权限;
应用: 同上面的SUID, 只不过这个SGID不是允许所有用户了, 仅是组内用户。
SBIT(Sticky Bit)目前只针对目录有效。
对于目录的作用是:当用户在该目录下建立文件或目录时,仅有自己与 root才有权力删除。
例如:
/tmp 本身权限是drwxrwxrwt,表示任何人都可以在/tmp目录内新增、修改文件,但是只有该文件或目录的建立都与root用户能够删除自己的文件或目录。
脚本 VS 编译语言:
使用脚本编程语言的好处是,它们多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象。缺点是:它们的效率通常不如编译型语言。不过权衡之下,通常使用脚本编程还是值得的:花一个小时写成的简单脚本,同样的功能用C或C++来编写实现,可能需要两天,而且一般来说,脚本执行的速度已经够快了,快到足以让人忽略它性能上的问题。
因为Shell似乎是各UNIX系统之间通用的功能,并且经过了POSIX的标准化。因此,Shell脚本只要“用心写”一次,即可应用到很多系统上。因此,之所以要使用Shell脚本是基于:
- 简单性:Shell是一个高级语言;通过它,你可以简洁地表达复杂的操作。
- 可移植性:使用POSIX所定义的功能,可以做到脚本无须修改就可在不同的系统上执行。
- 开发容易:可以在短时间内完成一个功能强大又妤用的脚本。
Linux文件目录/etc/init和/etc/init.d的前世今生
这段时间看linux内核启动过程,启动先要加载init进程(即1号进程),然后是按运行级别去执行相关脚本和配置。但是cd /etc目录后会发现两个和init相关的目录:/etc/init和/etc/init.d。很多文章都介绍了/etc/init/ 和 /etc/init.d/文件目录的区别,其实对它们的来源和实质并没有说清楚。看到下面这几段话,还是老外描述的比较清楚
/etc/init.d contains scripts used by the System V init tools (SysVinit). This is the traditional service management package for Linux, containing the init program (the first process that is run when the kernel has finished initializing) as well as some infrastructure to start and stop services and configure them. Specifically, files in /etc/init.d are shell scripts that respond to start, stop, restart, and (when supported) reload commands to manage a particular service. These scripts can be invoked directly or (most commonly) via some other trigger (typically the presence of a symbolic link in/etc/rc?.d/).
/etc/init.d里的shell脚本(SysVinit工具所包含的函数库)能够响应start,stop,restart,reload命令来管理某个具体的应用。比如经常看到的命令:
/etc/init.d/networking start
这些脚本也可被其他trigger直接激活执行,这些trigger被软连接在/etc/rcN.d/中。这些原理似乎可以用来写daemon(守护进程)程序,让某些程序在开关机时运行。
/etc/init contains configuration files used by Upstart. Upstart is a young service management package championed by Ubuntu. Files in /etc/init are configuration files telling Upstart how and when tostart, stop, reload the configuration, or query the status of a service. As of lucid(清楚的), Ubuntu is transitioning from SysVinit to Upstart , which explains why many services come with SysVinit scripts even though Upstart configuration files are preferred. In fact, the SysVinit scripts are processed by a compatibility layer in Upstart.
/etc/init包含的是Upstart(Sysinit的替代版本)的配置文件,和/etc/init.d的作用几乎差不多。这样似乎/etc/init可以看作/etc/init.d的演化版本。而SysVinit脚本是和新的Upstart兼容的。这就是这两个文件目录的来历和前世今生。
起名的讲究:Our ancestors
.d in directory names typically indicates a directory containing many configuration files or scripts for a particular situation . This structure is usually used when each entry in the directory is provided by a different source, so that each package can deposit(存放) its own plug-in without having to parse(分析) a single configuration file to reference itself. In this case, it just happens that “init” is a logical name for the directory, SysVinit came first and used init.d, and Upstart used plain init for a directory with a similar purpose (it would have been more “mainstream”(主流的?Chinglish?), and perhaps less arrogant(傲慢的), if they'd used /etc/upstart.d instead).
.d文件夹主要是为了方便和清楚的逻辑描述而命名成这样有点不伦不类的(在我看来)。在这里,init就是这个目录的逻辑名字。SysVinit came first and used init.d, and Upstart used plain init for a directory with a similar purpose。
至于最后一句,就是调侃了:关于版本变迁的傲慢与偏见。Or put it in other words, Our ancestors。