Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1351721
  • 博文数量: 245
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3094
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-12 14:51
文章存档

2011年(2)

2009年(152)

2008年(91)

我的朋友

分类: LINUX

2009-01-20 14:31:23

  特殊档案与程序:
  我们在 档案与目录管理当中的 SUID/SGID/SBIT 提到这一些奇怪的特殊权限的档案,这些档案到底是怎么产生特殊权限的行程?还有, 在磁碟挂载的时候,有时老是出现‘ device is busy ’的字样,真麻烦~到底是怎么回事啊? 我们底下就来谈一谈。

  SUID/SGID/SBIT 的概念
  虽然已经在前面的章节提过 SUID/SGID 等等的特殊权限,但是到底他是如何产生的? 首先,我们以条列式的方法列出使用者是否能够操作 SUID/SGID 的指令吧!

  * 关于 SUID 的执行:
  o Set UID 的权限设定值,仅对 binary file 有效;
  o 程式操作者必须要拥有该 binary file 的可执行权限 (x) ;
  o 当程式操作者执行该具有 SUID 的 binary file 时,该 binary file 所触发的程序中, 该程序的有效使用者 (effective user) 为该 binary file 的拥有者。

  很简单的概念吧!基本上,也就是说,使用者所触发的 SUID 的程序中, 有效使用者会变成该 SUID 指令的程式拥有者啦!我们以 pstree 配合 passwd 来做个实验好咯。 请您以 dmtsai 这个一般身份使用者登入后,执行 passwd ,但是先不要输入密码, 然后以另外一个终端机登入系统,使用 pstree -u 后,应该会看到如下的画面喔:

  init-+-atd
  |-.....省略的啦..........
  |-sshd---sshd---bash(dmtsai)---passwd(root)
  |-.....省略的啦..........
  `-xinetd

  看到了吧?虽然我是以 dmtsai 的身份启动 bash ,然后在 bash 当中执行 /usr/bin/passwd, 不过由于 passwd 拥有 SUID 的权限设定,所以,在 run-time 的过程当中,嘿嘿! 我这个 dmtsai 在该 process 内可是拥有 /usr/bin/passwd 的 owner (亦即是 root ) 的权限喔!这样够明白了吧?!

  那么既然 SUID/SGID 的权限是比较可怕的,您该如何查询整个系统的 SUID/SGID 的档案呢? 应该是还不会忘记吧?使用 find 即可啊!

  find / -perm +6000

  /proc/* 代表的意义:
  其实,我们之前提到的所谓的程序都是在记忆体当中嘛!而记忆体当中的资料又都是写入到 /proc/* 这个目录下的,所以啰,我们当然可以直接观察 /proc 这个目录当中的档案啊! 如果您观察过 /proc 这个目录的话,应该会发现他有点像这样:

  [root@linux ~]# ll /proc
  dr-xr-xr-x   5 root    root            0 Sep 12 14:12 1
  dr-xr-xr-x   5 root    root            0 Sep 15 12:01 10
  dr-xr-xr-x   5 dovecot dovecot         0 Sep 14 12:07 10487
  .....中间省略.....
  -r--r--r--   1 root    root            0 Sep 16 16:02 uptime
  -r--r--r--   1 root    root            0 Sep 16 16:02 version
  -r--r--r--   1 root    root            0 Sep 16 16:02 vmstat

  基本上,目前主机上面的各个程序的 PID 都是以目录的型态存在于 /proc 当中。 举例来说,我们开机所执行的第一支程式 init 他的 PID 是 1 , 这个 PID 的所有相关资讯都写入在 /proc/1/* 当中!若我们直接观察 PID 为 1 的资料好了, 他有点像这样:

  [root@linux ~]# ll /proc/1
  dr-xr-xr-x  2 root root 0 Sep 16 16:04 attr
  -r--------  1 root root 0 Sep 16 16:04 auxv
  -r--r--r--  1 root root 0 Sep 16 10:23 cmdline
  lrwxrwxrwx  1 root root 0 Sep 16 10:23 cwd -> /
  -r--------  1 root root 0 Sep 16 16:04 environ
  lrwxrwxrwx  1 root root 0 Sep 16 10:23 exe -> /sbin/init
  .....以下省略.....

  里面的资料还挺多的,不过,比较有趣的其实是两个档案,分别是:

  * cmdline:这个程序被启动的指令串;
  * environ:这个程序的环境变数内容。

  很有趣吧!如果你查阅一下 cmdline 的话,就会发现:

  [root@linux ~]# cat /proc/1/cmdline
  init [3]

  就是这个指令与参数启动 init 的啦!这还是跟某个特定的 PID 有关的内容呢,如果是针对整个 Linux 系统相关的参数呢?那就是在 /proc 目录底下的档案啦!相关的档案与对应的内容是这样的:

  档名    档案内容
  /proc/cmdline    载入 kernel 时所下达的相关参数!查阅此档案,可瞭解系统是如何启动的!
  /proc/cpuinfo    本机的 CPU 的相关资讯,包含时脉、类型与运算功能等
  /proc/devices    这个档案记录了系统各个主要装置的主要装置代号,与 mknod 有关呢!
  /proc/filesystems    目前系统已经载入的档案系统啰!
  /proc/interrupts    目前系统上面的 IRQ 分配状态。
  /proc/ioports    目前系统上面各个装置所配置的 I/O 位址。
  /proc/kcore    这个就是记忆体的大小啦!好大对吧!但是不要读他啦!
  /proc/loadavg    还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此!
  /proc/meminfo    使用 free 列出的记忆体资讯,嘿嘿!在这里也能够查阅到!
  /proc/modules    目前我们的 Linux 已经载入的模组列表,也可以想成是驱动程式啦!
  /proc/mounts    系统已经挂载的资料,就是用 mount 这个指令呼叫出来的资料啦!
  /proc/swaps    到底系统挂载入的记忆体在哪里?呵呵!使用掉的 partition 就记录在此啦!
  /proc/partitions    使用 fdisk -l 会出现目前所有的 partition 吧?在这个档案当中也有纪录喔!
  /proc/pci    在 PCI 汇流排上面,每个装置的详细情况!可用 lspci 来查阅!
  /proc/uptime    就是用 uptime 的时候,会出现的资讯啦!
  /proc/version    核心的版本,就是用 uname -a 显示的内容啦!
  /proc/bus/*    一些汇流排的装置,还有 USB 的装置也记录在此喔!

  其实,上面这些档案鸟哥在此建议您可以使用 cat 去查阅看看,不必深入瞭解, 不过,观看过档案内容后,毕竟会比较有感觉啦!如果未来您想要自行撰写某些工具软体, 那么这个目录底下的相关档案可能会对您有点帮助的喔!

  查询已开启档案或已执行程序开启之档案:

  其实还有一些与程序相关的指令可以值得参考与应用的,我们来谈一谈:

  # fuser
  如果当我们要卸载某个装置时,他老是告诉我们‘ device is busy ’, 那么到底是那个程序在使用这个装置呢?举例来说,当无法 umount /home 时, 该怎么办?此时我们可以使用 fuser 来帮忙啦!

  [root@linux ~]# fuser [-ki] [-signal] file/dir
  参数:
  -k  :找出使用该档案/目录的 PID ,并试图以 SIGKILL 这个讯号给予该 PID;
  -i  :必须与 -k 配合,在删除 PID 之前会先询问使用者意愿!
  -signal:例如 -1 -15 等等,若不加的话,预设是 SIGKILL (-9) 啰!
  范例:

  范例一:找出目前所在目录的使用 PID 为何?
  [root@linux ~]# fuser .
  .:                   18852c
  [root@linux ~]# ps aux | grep 18852
  root     18852  0.0  0.4   5396  1588 pts/0    SN   10:12   0:00 bash
  # 用这个方式就可以得到使用该目录的 PID 了。此外,为何使用 fuser
  # 的输出当中,在 PID 后面会有 c 呢?他代表的意义为:
  # c :在当前的目录下;
  # e :可以被执行的;
  # f :是一个被开启的档案
  # r :代表 root directory

  范例二:找到 /var 底下属于 FIFO 类型的档案,并且找出存取该档案的程序
  [root@linux ~]# find /var -type p
  /var/spool/postfix/public/qmgr
  /var/spool/postfix/public/pickup
  [root@linux ~]# fuser /var/spool/postfix/public/qmgr
  /var/spool/postfix/public/qmgr:  1666  1675
  [root@linux ~]# ps aux | egrep '(1666|1675)'
  root    1666 0.0 0.3 5640 1516 ?  Ss Jul25  0:01 /usr/libexec/postfix/master
  postfix 1675 0.0 0.4 5744 1604 ?  S  Jul25  0:00 qmgr -l -t fifo -u

  范例三:同范例二,但试图删除该 PID?
  [root@linux ~]# fuser -ki /var/spool/postfix/public/qmgr
  /var/spool/postfix/public/qmgr:  1666  1675
  Kill process 1666 ? (y/N) n
  Kill process 1675 ? (y/N) n

  如何?很有趣的一个指令吧!透过这个 fuser 我们可以找出使用该档案、 目录的程序,藉以观察的啦!

  # lsof
  相对于 fuser 是由档案或者装置去找出使用该档案或装置的程序,反过来说, 如何查出某个程序开启或者使用的档案与装置呢?呼呼!那就是使用 lsof 啰~

  [root@linux ~]# lsof [-Uu] [+d]
  参数:
  -a  :多项资料需要‘同时成立’才显示出结果时!
  -U  :仅列出 Unix like 系统的 socket 档案类型;
  -u  :后面接 username,列出该使用者相关程序所开启的档案;
  +d  :后面接目录,亦即找出某个目录底下已经被开启的档案!
  范例:

  范例一:列出目前系统上面所有已经被开启的档案与装置:
  [root@linux ~]# lsof
  COMMAND PID USER  FD  TYPE  DEVICE   SIZE    NODE NAME
  init      1 root cwd   DIR     3,1   4096       2 /
  init      1 root rtd   DIR     3,1   4096       2 /
  init      1 root txt   REG     3,1  34352  883193 /sbin/init
  .....底下省略.....
  # 注意到了吗?是的,在预设的情况下, lsof 会将目前系统上面已经开启的
  # 档案全部列出来~所以,画面多的吓人啊!您可以注意到,第一个档案 init 执行的
  # 地方就在根目录,而根目录,嘿嘿!所在的 inode 也有显示出来喔!

  范例二:仅列出关于 root 的所有程序开启的 socket 档案
  [root@linux ~]# lsof -u root -a -U
  COMMAND     PID USER   FD   TYPE     DEVICE SIZE   NODE NAME
  kmodule     793 root    4u  unix 0xd744b700        3549 socket
  udevd       801 root    5u  unix 0xd744bb40        3561 socket
  syslogd    1539 root    0u  unix 0xd75946e0        4870 /dev/log
  # 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥资讯?
  # 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!
  # -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^

  范例三:请列出目前系统上面所有的被启动的周边装置
  [root@linux ~]# lsof +d /dev
  COMMAND     PID    USER   FD   TYPE     DEVICE SIZE NODE NAME
  init          1    root   10u  FIFO       0,13      1834 /dev/initctl
  kmodule     793    root    2u   CHR        1,3      2135 /dev/null
  kmodule     793    root    3u   CHR        5,1      2134 /dev/console
  udevd       801    root    2u   CHR        1,3      2135 /dev/null
  syslogd    1539    root    0u  unix 0xd75946e0      4870 /dev/log
  xinetd     1589    root    1r   CHR        1,3      2135 /dev/null
  #看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!

  范例四:秀出属于 root 的 bash 这支程式所开启的档案
  [root@linux ~]# lsof -u root | grep bash
  bash   26199 root  cwd   DIR   3,2   4096   159875 /root
  bash   26199 root  rtd   DIR   3,1   4096        2 /
  bash   26199 root  txt   REG   3,1 686520   294425 /bin/bash
  bash   26199 root  mem   REG   3,1  83160    32932 /usr/lib/gconv/BIG5.so
  bash   26199 root  mem   REG   3,1  46552   915764 /lib/libnss_files-2.3.5.so
  .....底下省略.....

  这个指令可以找出您想要知道的某个程序是否有启用哪些资讯? 例如上头提到的范例四的执行结果呢! ^_^

  # pidof

  [root@linux ~]# pidof [-sx] program_name
  参数:
  -s  :仅列出一个 PID 而不列出所有的 PID
  -x  :同时列出该 program name 可能的 PPID 那个程序的 PID
  范例:

  范例一:列出目前系统上面 init 以及 syslogd 这两个程式的 PID
  [root@linux ~]# pidof init syslogd
  1 2546
  # 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。
  # 分别是 init 及 syslogd 这两支程式的 PID 啦。

  范例二:找出 bash 即以 bash 为 PPID 的几个主要的 PID
  [root@linux ~]# pidof -x bash
  2961 2959 338
  # 因为我的系统被我登入之后,我就会主动取得一个 bash 的程序,所以啰,
  # 很自然就会拥有一个 PID 啊。只要我再以底下的方式,就可以取得我所想要的 PID 内容。
  [root@linux ~]# ps aux | egrep '(2961|2959|338)'
  dmtsai   338  0.0  0.1  6024 1536 pts/0    Ss   16:43   0:00 -bash
  kiki    2961  0.0  0.1  6025 1526 pts/0    Ss   17:43   0:00 -bash
  .....以下省略......

  很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法, 就可以很轻易的找到您所想要的程序内容了呢。

阅读(1416) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~