第八章 登录与退出

 

“我并不关心能接收象我这样的人作为会员的俱乐部。”(Groucho Marx

本章描述了当一个用户登录或退出时会发生些什么。对于后台进程的各种交互作用、log文件、配置文件等等也进行了一定的叙述。

 

从终端登录

8-1显示出通过终端登录是如何进行的。首先,init确信对于终端连接(或控制台)有一个对应的getty程序。getty在终端上侦听并且等待用户通告他已准备好登录(这通常意味着用户必须键入些什么)。当它注意到一个用户,getty输出一段欢迎消息(存储于/etc/issue),提示输入用户名,并且最终运行login程序。login将用户名作为参数,提示用户输入口令。如果这些都匹配的话,login开始运行为该用户配置的shell;否则的话,它就退出并终止该进程(也许是在给用户另一个输入用户名和口令的机会以后)。init注意到这个进程终止以后,就开始为该终端运行一个新的getty程序。

8-1. 从终端登录:initgettylogin以及shell的交互作用

注意唯一的新进程是由init创建的(使用fork系统调用);gettylogin仅仅替换运行在进程中的程序(使用exec系统调用)。

对于串行线路需要一个独立的程序来检测一个用户,因为要知道一个终端已成为活动终端是比较复杂的(传统上是这样的)。getty也同样会适应于连接的速度和其它的设置,这对于拨入连接尤其重要,因为对于各个拨入呼叫的参数常常是不一样的。

现在有几种gettyinit的版本供使用,它们各有优缺点。好好弄懂你的系统上的版本以及其它的版本(你可以使用Linux软件Map来搜寻它们)是有益处的。如果你没有拨入连接,就无需关心getty,但是init仍然是很重要的。

 

通过网络登录

在同一个网络中的两台计算机通常由单根电缆相连接。当它们在网络上互相通信时,各台计算机中参与通信的程序通过一个虚拟连接(virtual connection)连在了一起,一种想象中的电缆。就虚拟连接两端的程序而言,它们各自主宰着自己的电缆。然而,由于这是一种想象中的电缆而非真实的电缆,两台计算机的操作系统可以有几条虚拟连接,这些虚拟连接共享同一物理电缆。这样,仅使用单根电缆,几个程序就能同时通信而无需知道或关心其它的通信。这甚至使得几台计算机使用同一根电缆的情况成为可能;虚拟连接存在于两台计算机之间,其它的计算机会忽略这些没有参与的连接。

那是很复杂的,是对现实的一种极其抽象的描述。然而,也许这已够理解为什么从网络登录与常规的登录有所不同的重要原因了。不同计算机上的两个程序想要进行通信时就会建立虚拟连接。由于从原理上讲,从网络中的任何一台计算机都可以登录进网络中的任何其它计算机中,就会存在大量的潜在的虚拟通信。由于这个原因,为每个潜在的登录运行一个getty是不现实的。

有一个单个进程inetd(对应于getty)用来处理所有的网络登录。当它注意到进来一个网络登录(也即,它注意到它有了一条到其它计算机的虚拟连接),它就启动一个新进程来处理那个登录。原始的进程仍然继续侦听新的登录请求。

让问题变得更为复杂的是,对于网络登录有不止一种的通信协议存在。最为重要的两种是telnetrlogin。除了登录以外,还可能建立许多其它的虚拟连接(用于FTPGopherHTTP等其它网络服务)。针对各种类型的连接使用不同的进程将是低效的,所以取而代之的是只存在一个侦听进程,它可以识别出连接的类型并且能启动相应的程序来提供服务。这个单个侦听者称为\cmd{inetd};详细信息请参见Linux网络管理员手册

 

Login做些什么

login程序用于验证用户(确信用户名和口令是匹配的)、通过设置串行线路的许可来为用户设置一个初始环境、开始运行shell

初始设置的一部分是用于输出/etc/motd文件的内容(当天的短讯)以及检查电子邮件。这可以通过在用户主目录中建立一个称为.hushlogin的文件来取消这些操作。

如果文件/etc/nologin存在,登录的功能就被取消。通常,这个文件是由shutdown以及其它相应操作产生的。login会检查这个文件,如果该文件存在的话就会拒绝登录,login会在其退出前将该文件的内容显示在用户终端上。

login在一个系统日志文件中记录所有失败的登录企图(通过syslog)。它也记录所有的root登录。这些对于跟踪入侵者来说是很有用的。

当前已登录的人被列于文件/var/run/utmp中。这个文件在系统重新启动或关闭之前一直是有效的;当系统引导完成后,这个文件是空的。该文件列出了每个用户和他使用的终端(或网络连接)以及其它一些有用信息。whow以及其它一些类似命令查询utmp来看谁已登录系统。

所有成功的登录都被记录进/var/log/wtmp。这个文件会越来越大,没有限制,所以有必要定期对它清理,例如通过一个以一星期为周期的cron作业。[1] last命令用于浏览wtmp文件。

utmpwtmp两者均是二进制格式(见utmpmanual page);很不幸,不用专用程序不能查看到它们的内容。

 

X以及xdm

XXX X通过xdm实现登录;同样也可用:xterm –ls

 

访问控制

传统上,用户数据库包含在/etc/passwd文件中。有些系统使用影子口令(shadow passwords),并且将口令移入了/etc/shadow。有许多有共享帐号的计算机的站点使用NIS或一些其它方法来存储用户数据;它们通常可以自动地从某个中央位置将数据库拷贝到所有其它计算机中。

用户数据库不但包含有口令,而且还包括一些其它的有关用户的信息,比如他们的真实名称、主目录和登录shells。这些其它信息需要是公用的,这样任何人都可以阅读它。因此口令是加密存储的。这的确有不足之处,能够访问加密了的口令的任何人可以使用各种口令工具来猜测它,而无需实际地试着登录计算机中。影子口令试图避免这个缺点,做法是将口令移入另一个文件,这个文件只有root用户可以读取(口令仍然是加密存储的)。然而,以后在一个不支持影子口令的系统上安装影子口令有可能很困难。

不管口令怎样,确信一个系统上的所有口令是否都健全是很重要的,也即,不容易被猜测出来。crack程序可用来破解口令;它所能猜测出的任何口令都不算是好口令。虽然系统入侵者能够使用crack程序,系统管理员同样也可以使用它来避免不好的口令。passwd程序也能够增强口令的不易猜测性;实际上更有效的是在于CPU周期上,因为破解口令需要大量的计算。

用户组数据库在/etc/group文件中;对于有影子口令的系统,可能存在一个/etc/shadow.group文件。

root用户通常不能够在大多数终端或网络上登录,只能在列于/etc/securetty文件中的终端上登录。这使得必须直接访问这些物理终端之一。然而,可以以任何其它用户在任何终端上登录,并使用su命令来成为root用户。

 

shell的启动

当一个交互式的登录shell启动时,它自动执行一个或多个预定义的文件。不同的shells执行不同的文件;详细信息参见各种shell的文档。

大多数shells首先运行一些全局文件,例如,Bourne shell/bin/sh)以及它的派生者执行/etc/profile文件;它还执行用户主目录中的.profile文件。/etc/profile允许系统管理员设置一个公共的用户环境,特别是除了一般的目录,可以通过设置PATH来包括当地命令目录。另外,如果需要的话,.profile文件允许用户覆盖profile定义的缺省环境,以定制自己的使用环境以适合自己的口味。

 

注释

  1. 好的Linux发行版在箱外做这事。