学习bash第二版-第十章 bash管理

  系统管理员会使用shell完成两方面的工作:设置通用的用户环境和设置系统安全性。本章将探讨与这些工作相关的bash特性。本书假设读者已掌握UNIX系统管理基础。
**作为标准shell安装bash
  在系统定制的开头,需要强调的是:bash可以被安装成标准的Bourne shell(/bin/sh)。的确,在某些系统中是通过安装bash来替代Bourne shell,比如Linux。
  如果读者希望这样配置自己的系统,可以将原来的Bourne shell保存为另一个名称(在仍需要使用它的情况下),然后可以将bash作为位于/bin目录的sh,或者在/bin目录中安装bash,并且用命令ln -s /bin/bash /bin/sh创建一个由/bin/sh至/bin/bash的符号链接。由于当bash作为sh启动时,其行为稍有不同,故这里认为后一种安装方式更好,对此读者稍候就会明白。
  如同在附录A中所详述的,Bash对Bourne shell向后兼容,但是它不支持将^作为管道符|的替代字符。除非读者拥有一种古老的UNIX系统,或者拥有一些非常老的shell脚本,否则无需担心此问题。
  但是,如果要确保万无一失,只需在PATH的所有目录中搜索全部shell脚本。一种执行此搜索的简便方法是使用file命令,此命令在第五章和第九章中都曾介绍过。当给定一个脚本名称时,file输出“executable shell script”。下面是一个在PATH的每个目录查找^字符的脚本:
  IFS=:
  for d in $PATH; do
      echo checking $d:
      cd $d
      scripts=$(file * | grep 'shell script' | cut -d: -f1)
      for f in $scripts; do
          grep '\^' $f /dev/null
      done
  done
  此脚本的第一行确保能够在for循环中将$PATH用作一个项目列表。对于每一个目录,通过cd命令进入,并且通过管道将file命令的结果传递给grep命令。查找所有的shell脚本,然后,从查找结果中提取文件名传递给cut命令。接下来,对每一个shell脚本,查找^字符。
  如果运行此脚本,读者可能会查到几处^字符——但是,这些^符号应该在grep、sed或awk命令中的正则表达式中使用,而不是用作管道符。只要^字符不被用作管道符,则将bash安装为/bin/sh就是安全的。
  正如前面所述,如果bash作为sh启动(因为此可执行文件已被重命名为sh,或者存在一个由sh至bash的链接),其启动行为将会稍有不同,以便尽可能的模仿Bourne shell。对于登录shell而言,它只试图读/etc/profile和~/.profile文件,而忽略任何其他启动文件,如~/.bash_profile文件。对于交互式shell而言,它不读初始化文件~/.bashrc。
**POSIX模式
  除了其本地操作模式,bash也可以被切换至POSIX模式。如同在附录A中所详述的,POSIX(Portable Operating System Interface 可移植操作系统接口)标准定义了标准化UNIX的准则。POSIX标准的一部分涉及到了shell。
  本地模式的bash几乎与POSIX完全兼容。如果读者希望严格遵循POSIX,则既可以用-posix选项启动bash,也可以在shell中通过设置set -o posix实现。
  只有在极少的情况下才必须使用POSIX模式。如同在附录A中所列出的,此两种模式的差别不大,并且主要与命令查找顺序和如何处理函数相关。大多数bash用户也许一辈子都不需要使用此选项。
**命令行选项
  bash包含若干命令行选项,它们改变shell的行为并传递信息至shell。这些选项分为两类:类似于本书之前各章所介绍内容的单字符选项以及多字符选项,它们是对UNIX实用程序的相对较新的改进。表10-1列出了所有这些选项。
  
  表10-1  bash命令行选项
  选项            含义
  -c string       如果给出此选项,则命令是从string中读出的。string之后的任何参数都被解释为位置参数,并以$0开始。
  -D              在标准输出中输出一个全部由$开头的带双引号的字符串列表。在当前地区(locale)不为C或不为POSIX时,这些字符串是受制于语言转换的。此选项同时打开-n选项。
  -i              交互式shell,忽略TERM、INT和QUIT信号。在作业控制有效时,信号TTIN、TTOU和TSTP也被忽略。
  -o option       与set -o接受相同的参数。
  -s              从标准输入读命令。如果给bash提供一个参数,则此标记优先(即,参数将不被看作是脚本名,且标准输入将被读入)。
  -r              受限shell。本章稍后介绍。
  -               提示选项的结束,且禁止处理更多的选项。在此之后的任何选项均被视为文件名和参数。--与-同义。
  --dump-strings  同选项-D。
  --help          显示一条用法信息并退出。
  --login         使bash作为登录shell启动。
  --noediting     如果为交互式的,则不使用GNU的readline库读命令行。
  --noprofile     不读启动文件/etc/profile或任何个人的初始化文件。
  --norc          如果shell为交互式的,则不读初始化文件~/.bashrc。如果shell是作为sh启动的,则在默认情况下此选项为开状态。
  --posix         当bash的默认操作式不为POSIX时,改变bash的行为以更接近于POSIX准则。
  --quiet         不显示shell启动信息,此为默认值。
  --rcfile file   如果shell为交互式的,则执行从file中读入的命令,以代替读初始化文件~/.bashrc。
  --version       显示此shell实例的版本号,并退出。
  
  在命令行中,多字符选项必须出现在单字符选项之前。除此之外,任何set选项可以用于命令行。类似于shell内置功能,可以用+代替-来关闭一个选项。
  在这些选项中,最有用的是-i(交互)、-r(受限)、-s(从标准输入读)、-p(特权)和-m(支持作业控制)。登录shell通常在-i、-s和-n选项条件下运行。本章后面将讨论受限模式和特权模式。
**环境定制
  类似于Bourne shell,bash使用/etc/profile文件进行系统级的定制。当一个用户登录时,shell在运行用户的.bash_profile之前先读入并运行/etc/profile。
  本章没有介绍可用于/etc/profile文件的全部命令。但是,bash拥有几个与系统定制密切相关的独有特性;这里将讨论它们。
  这里首先介绍两个内置命令,读者可以在/etc/profile中将它们用于定制自己的用户环境,并且限制它们对系统资源的占用。用户也可以在自己的.bash_profile中或在任何其他时间使用这些命令覆盖默认设置。
**umask
  umask类似于在大多数其他shell中的相同命令,在创建文件时,它允许用户指定此文件的默认权限。它与chmod命令接受相同类型的参数,即绝对的(八进制数)或符号的权限值。
  当进程创建一个文件时,无论该进程指定的是什么权限,umask都包含在默认情况下禁止的权限。
  这里将使用八进制记数法说明其原理。读者可能知道,位于权限数值中的每位数字(从左至右)依次代表文件拥有者、拥有者组和所有其他用户的权限。每个数字又由三位构成,从左至右分别指定读、写和执行权限(如果一个文件代表的是目录,则“执行”权限变成“搜索”权限,即通过cd进入此目录和列表显示该目录所包含文件的权限等)。
  例如,八进制数640等价于二进制数110 100 000。如果一个文件拥有此权限,则其拥有者可以对其读写;属于拥有者组的用户则只能读该文件;其他的用户则对该文件不拥有任何权限。一个拥有权限755的文件授予其拥有者读、写和执行的权限,而其他所有人则拥有读和执行的权限(但不能写)。
  022是一个常用的umask值。这意味着当一个文件被创建时,最可能的权限是755——这正是一个由编译器创建的文件通常所拥有的权限。在另一方面,文本编辑器则可能创建一个权限为666的文件(所有人都可以读和写),但是,umask则强迫其权限为644。
**ulimit
  ulimit命令起初用于指定文件创建大小的限制。但是,bash版本的ulimit命令则拥有允许用户对几种不同系统资源实施限制的选项。表10-2列出了这些选项。
  
  表10-2  ulimit资源选项
  选项    受限的资源
  -a      全部限制(用来打印值)
  -c      Core文件大小(1Kb块)
  -d      进程数据段(Kb)
  -f      文件大小(1Kb块)
  -l      一个可以被锁定在内存中进程的最大大小(Kb)
  -m      最大驻留集大小
  -n      文件描述符
  -p      管道大小(512字节块)
  -s      进程堆栈段(Kb)
  -t      进程CPU时间(秒)
  -u      用户可用的最大进程数
  -v      虚拟内存(Kb)
  
  每个选项接受一个数值的参数,该数值指定限制值,单位在上表中给定。也可以赋予“unlimited”的参数值(它实际上可能表示某种物理限制),或者还可以忽略此参数,此时该命令将输出当前的限制。ulimit -a输出全部类型的限制(或“unlimited”)。一次只能指定一种类型的资源。在没有给定任何选项的情况下,将假定启用-f选项。
  某些选项依赖于较老版本的UNIX操作系统所不具备的功能。特别是,某些较老版本对每个进程的文件描述符固定限制为20个(导致-n无效),而有些则不支持虚拟内存(导致-v无效)。
  选项-d和-s必须处理动态内存分配,即进程在运行时向操作系统申请内存。对于普通用户而言,这些限制是不必要的,不过软件开发人员则希望能这样做,以便克服有缺陷的程序试图因死循环而无限制的申请内存。
  选项-v和-m选项是类似的,-v对使用的所有内存实施限制,而-m则限制允许一个进程所使用的物理内存量。除非系统对内存有严格的限制,或者为了避免系统失效而限制进程大小,否则无需这些限制。
  如果存在系统内存限制,或者希望禁止个别用户独占系统资源,选项-u就很有用。
  如果存在对磁盘空间的限制,也许希望指定对文件大小的限制(-f和-c)。有时用户确实想要创建巨大文件,但是,更常见的情形是,这种巨大文件是由于有缺陷程序进入死循环而导致的。使用类似于sdb、dbx和gdb的调试程序的软件开发人员不应该限制core文件的大小,因为调试时会有大量内存信息转储。
  选项-t提供了对死循环的另一种防护。不过,如果一个程序陷入死循环,但它不占用内存或写文件,则不是什么特别严重的问题;让此选项为“unlimited”,而由用户去去掉这种讨厌的程序也许更好。
  除了可以指定要限制的资源类型,ulimit命令还允许指定硬或软限制。硬限制可以被任何用户降低,但是只能由超级用户(root用户)提高;用户可以降低或者提高软限制——但不能高过该资源的硬限制。
  如果-H与上述选项中的一个(或多个)一同使用,ulimit命令将设置硬限制,-S选项则设置软限制。如果这两种选项都不被使用,ulimit则设置硬和软限制。例如,下面的命令将文件描述符的软限制设置为64,将硬限制设置为unlimited。
  ulimit -Sn 64
  ulimit -Hn unlimited
  当ulimit命令输出当前限制时,除非指定-H,否则它输出软限制。
**全局定制类型
  实施全局定制的最可行的途径在于系统级的环境文件,该文件与用户环境文件相隔离——如同/etc/profile与每个用户的.bash_profile隔离。遗憾的是,bash不具备此特性。
  但是,此shell提供了若干设置定制的方法,这些定制可以在任何时间为任何用户使用。环境变量是最显而易见的;系统的/etc/profile文件无疑包含了对其中几个环境变量的定义,包括PATH和TERM。
  当系统支持拨号网络时,变量TMOUT很有用。设置此变量为数字N,当用户在shell最近一次给出一个提示符之后,如果在N秒内没有输入一个命令,shell将终止。此特性有助于人们避免“独占”拨号线。
  也许读者希望包括某些涉及环境变量的更复杂定制,比如包含当前目录的提示字符串PS1(如同在第四章“基础shell编程”中所介绍的)。
  读者还可以打开选项,比如emacs或vi编辑模式,或者noclobber以避免无意中造成的文件覆盖。为通用目标而编写的任何shell脚本也都可用于定制。
  遗憾的是,不能创建一种全局的别名。可以在/etc/profile中定义别名,但是无法让它们成为环境的一部分,从而将它们的定义传递给子shell(与之相反,通过在~/.bashrc中给出它们的定义,用户可以定义全局别名)。
  然而,读者可以设置全局函数。这是一种定制自己系统环境的巧妙方法,因为函数是shell的一部分,而不是独力的进程。
**系统安全特性
  UNIX安全性是一种声名狼藉的传奇问题。几乎UNIX系统的每一个方面都存在相关的安全性问题,而且这就是系统管理员通常所要考虑的。
  bash具备解决此问题的两种特性:受限shell,它是有意成为“弱智型的”;以及特权模式,它用于处理shell脚本,如同用户为root一样。
**受限shell
  受限shell的设计意图是使用户进入一种环境,在该环境下他移动和写入文件的能力严格被限制。它通常用于“guest”账号。你可以通过在用户的/etc/passwd端口中加入rbash使他的登录shell成为受限的。
  受限shell强加的特定约束使用户不能做下列操作:
  ·改变工作目录:cd不起作用。如果你要使用它,会得到错误信息bash: cd: restricted。
  ·重定向到一个文件:重定向符>,>|,<>和>>不允许使用。
  ·对环境变量SHELL或PATH设置新值。
  ·指定其中带有斜线(/)的路径名。shell将当前目录外的这些文件看作“未找到”。
  ·使用exec内置命令。
  ·指定包含斜线(/)为.内置命令参数的文件名。
  ·在启动时从shell环境中导入函数定义。
  ·使用enable内置命令的-f和-d选项添加或删除内置命令。
  ·指定builtin命令的-p选项。
  ·使用set +r关闭受限模式。
  这些限制在用户的.bash_profile和环境文件运行时开始生效。另外,将用户的.bash_profile和.bashrc的所有者改为root,并使这些文件只读是很明智的。用户的主目录也应被设置为只读。
  这意味着受限shell用户的整个环境都被设置在/etc/profile和.bash_profile里。因为用户不能访问/etc/profile,也不能重写.bash_profile,只有系统管理员才能把环境配制成其所想要的形式。
  建立这种环境的两种常见方式是建立“安全”命令目录以及使该目录成为PATH里唯一的目录,并建立一个命令菜单,用户在不退出shell的情况下不能取消该菜单。
**系统入侵方案
  在介绍其他安全性特性前,先介绍理解系统安全性必要性的背景信息。
  许多UNIX安全问题都集中在一个称为suid(设置用户ID)位的UNIX文件属性。它类似于权限位(见前面umask):当可执行文件将其打开时,文件以等于文件所有者的有效用户ID运行,这些文件的所有者通常为root。有效用户ID与进程实际用户ID不同。
  此特性使管理员可以编写以一种被控制的方式且需要root权限才能执行某种操作的脚本。要设置一个文件的suid位,特权用户可以键入chmod 4755 文件名,4是suid位。
  现代系统管理员会认为创建suid shell脚本是很差的想法,在C shell下尤其如此。因为它的.cshrc环境文件造成了无数被入侵的机会。bash的环境文件特性也有类似的安全漏洞,虽然我们介绍的安全特性会使该问题的严重性降低。
  下面说明为什么设置脚本的suid位是危险的。在第三章中曾提到,把自己的bin目录放在PATH的前面是不恰当的。以下方案显示了该位置如何结合suid shell脚本以形成安全漏洞:臭名昭著的“特洛伊木马”的变体。首先,计算机黑客必须找到系统上使用了suid shell脚本的一个用户。另外,该用户必须在PATH中有其自己的bin目录,且在公共bin目录前列出。黑客必须对用户的bin目录具有写权限。
  一旦黑客发现具备这些条件的用户,他可执行如下步骤:
  ·查看suid脚本,并找到一种可进行查看的常见工具,这里假设是grep。
  ·创建“特洛伊木马”,它是一个shell脚本,在用户的bin目录下,名字为grep。脚本如下:
    cp /bin/bash filename
    chown root filename
    chmod 4755 filename
    /bin/grep "$@"
    rm ~/bin/grep
    filename为一个目录下具有公开读和执行权限的不显著文件名,这些目录如/bin或/usr/bin。创建该文件后,将成为最可恶的安全漏洞:一个suid交互式shell。
  ·等待该用户运行suid shell脚本——它调用了“特洛伊木马”,依此创建suid shell,然后自动销毁。
  ·运行suid shell,创建破坏程序。
**特权模式
  防备“特洛伊木马”的一种方式是特权模式。这是一个set -o选项(set -o privileged或set -p),但shell在执行设置了suid位的脚本时自动进入该特权模式。
  在特权模式里,当调用一个suid bash shell脚本时,shell不会运行用户的环境文件,即它不会扩展该用户的BASH_ENV环境变量。
  因为特权模式是一个选项,可使用命令set +o privileged(或set +p)将之关闭。但这不会有助于潜在的系统黑客:shell会自动将其有效用户ID改为与实际的用户ID一样——即如果你关闭了特权模式,也就关闭了suid。
  特权模式是一种很优秀的安全特性;它解决了环境文件的想法第一次出现在C shell里时所产生的问题。
  然而,我们仍强烈建议不要创建suid shell脚本,这里介绍了bash如何防备一种特定形式下的入侵行为,但这当然不能说明bash在任何情况下都是“安全”的。如果你必须有一个suid脚本,就得仔细考虑所有相关的安全性问题。
  最后,如果你要学习更多关于UNIX安全的知识,可以参阅《Practical UNIX and Internet Security》一书,作者是Gene Spafford和Simson Garfinkel(O'Reilly & Associates)。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值