第 7 章 系统配置 系统配置: 日志、系统时间、批处理任务和用户

When you first look in the /etc directory, you might feel a bit overwhelmed. Although most of the files that you see affect a system’s operations to some extent, a few are fundamental.

当你第一次查看/etc目录时,可能会感到有点不知所措。

尽管你看到的大部分文件都对系统的运行产生一定的影响,但其中有一些是基础的。

The subject material in this chapter covers the parts of the system that make the infrastructure discussed in Chapter 4 available to the user-level tools covered in Chapter 2. In particular, we’re going to look at the following:

本章的主题材料涵盖了使第4章讨论的基础设施对第2章涵盖的用户级工具可用的系统部分。

特别是,我们将看以下内容:

o Configuration files that the system libraries access to get server and user information
o Server programs (sometimes called daemons) that run when the system boots
o Configuration utilities that can be used to tweak the server programs and configuration files
o Administration utilities

  • 系统库访问的配置文件,用于获取服务器和用户信息
  • 系统启动时运行的服务器程序(有时称为守护进程)
  • 可用于调整服务器程序和配置文件的配置工具
  • 管理工具

As in previous chapters, there is virtually no networking material here because the network is a separate building block of the system. In Chapter 9, you’ll see where the network fits in.

与前几章一样,这里几乎没有涉及网络内容,因为网络是系统的一个独立构建块。

在第9章中,你将看到网络的位置。

7.1 The Structure of /etc(/etc 的结构)

Most system configuration files on a Linux system are found in /etc. Historically, each program had one or more configuration files there, and because there are so many packages on a Unix system, /etc would accumulate files quickly.

Linux系统上的大多数系统配置文件都存放在/etc目录下。

从历史上看,每个程序都有一个或多个配置文件存放在这里,由于Unix系统上有很多软件包,/etc目录下的文件会很快积累起来。

There were two problems with this approach: It was hard to find particular configuration files on a running system, and it was difficult to maintain a system configured this way. For example, if you wanted to change the system logger configuration, you’d have to edit /etc/syslog.conf. But after your change, an upgrade to your distribution could wipe out your customizations.

这种方法存在两个问题:在运行中很难找到特定的配置文件,而且以这种方式配置系统也很难维护。

例如,如果你想要更改系统日志记录器的配置,你需要编辑/etc/syslog.conf。但是,在你进行更改后,系统升级可能会覆盖你的自定义配置。

The trend for many years now has been to place system configuration files into subdirectories under /etc, as you’ve already seen for the boot directories (/etc/init for Upstart and /etc/systemd for systemd). There are still a few individual configuration files in /etc, but for the most part, if you run ls -F /etc, you’ll see that most of the items there are now subdirectories.

多年来的趋势是将系统配置文件放在/etc的子目录下,就像你已经在引导目录(/etc/init用于Upstart和/etc/systemd用于systemd)中看到的那样。尽管/etc目录下仍然有一些个别的配置文件,但大部分情况下,如果你运行ls -F /etc命令,你会发现大部分项目都是子目录。

To solve the problem of overwriting configuration files, you can now place customizations in separate files in the configuration subdirectories, such as the ones in /etc/grub.d.

为了解决配置文件被覆盖的问题,现在你可以将自定义配置放在配置子目录中的单独文件中,比如/etc/grub.d目录中的文件。

What kind of configuration files are found in /etc? The basic guideline is that customizable configurations for a single machine, such as user information (/etc/passwd) and network details (/etc/network), go into /etc. However, general application details, such as a distribution’s defaults for a user interface, don’t belong in /etc. And you’ll often find that noncustomizable system configuration files may be found elsewhere, as with the prepackaged systemd unit files in /usr/lib/systemd.

/etc目录下有哪些类型的配置文件?

基本准则是,适用于单台机器的可定制配置,比如用户信息(/etc/passwd)和网络详细信息(/etc/network),应该放在/etc目录下。

然而,一般的应用程序细节,比如用户界面的发行版默认设置,不应该放在/etc目录下。

而且你经常会发现,不可定制的系统配置文件可能会出现在其他地方,比如/usr/lib/systemd目录下的预打包的systemd单元文件。

You’ve already seen some of the configuration files that pertain to booting. Now we’ll look at a typical system service and how to view and specify its configuration.

你已经看到了一些与引导相关的配置文件。

现在我们将看一下典型的系统服务以及如何查看和指定其配置。

7.2 System Logging(系统日志)

Most system programs write their diagnostic output to the syslog service. The traditional syslogd daemon waits for messages and, depending on the type of message received, funnels the output to a file, the screen, users, or some combination of these, or just ignores it.

大多数系统程序将其诊断输出写入syslog服务。

传统的syslogd守护程序等待消息,并根据接收到的消息类型,将输出导向文件、屏幕、用户或其组合,或者仅忽略它。

7.2.1 The System Logger(系统日志记录器)

The system logger is one of the most important parts of the system. When something goes wrong and you don’t know where to start, check the system log files first. Here is a sample log file message:

系统日志记录器是系统中最重要的部分之一。

当出现问题并且不知道从何处开始时,请首先检查系统日志文件。以下是一个示例日志文件消息:

Aug 19 17:59:48 duplex sshd[484]: Server listening on 0.0.0.0 port 22.

Most Linux distributions run a new version of syslogd called rsyslogd that does much more than simply write log messages to files. For example, you can use it to load a module to send log messages to a database. But when starting out with system logs, it’s easiest to start with the log files normally stored in /var/log. Check out some log files—once you know what they look like, you’ll be ready to find out how they got there.

大多数Linux发行版运行名为rsyslogd的新版本syslogd,它不仅仅将日志消息写入文件。

例如,您可以使用它加载模块将日志消息发送到数据库。

但是,在开始使用系统日志时,最简单的方法是从通常存储在/var/log中的日志文件开始。

查看一些日志文件 - 一旦您知道它们的外观,您就可以准备好了解它们是如何产生的。

Many of the files in /var/log aren’t maintained by the system logger. The only way to know for sure which ones belong to rsyslogd is to look at its configuration file.

/var/log中的许多文件不是由系统日志记录器维护的。

唯一确定属于rsyslogd的文件的方法是查看其配置文件。

7.2.2 Configuration Files(配置文件)

The base rsyslogd configuration file is /etc/rsyslog.conf, but you’ll find certain configurations in other directories, such as /etc/rsyslog.d. The configuration format is a blend of traditional rules and rsyslogspecific extensions. One rule of thumb is that anything beginning with a dollar sign ($) is an extension.

基本的rsyslogd配置文件是/etc/rsyslog.conf,但你会在其他目录中找到特定的配置,比如/etc/rsyslog.d。

配置格式是传统规则和rsyslog特定扩展的混合。

一个经验法则是,以美元符号($)开头的任何内容都是扩展。

A traditional rule has a selector and an action to show how to catch logs and where to send them, respectively. For example:

传统规则有一个选择器和一个动作,用于指示如何捕获日志和将其发送到何处。

例如:

Example 7-1. syslog rules
kern.* /dev/console
*.info;authpriv.none➊ /var/log/messages
authpriv.* /var/log/secure,root
mail.* /var/log/maillog
cron.* /var/log/cron
*.emerg *➋
local7.* /var/log/boot.log

The selector is on the left. It’s the type of information to be logged. The list on the right is the action: where to send the log. Most actions in Example 7-1 are normal files, with some exceptions. For example, /dev/console refers to a special device for the system console, root means send a message to the superuser if that user is logged in, and * means message all users currently on the system. You can also send messages to another network host with @host.

选择器在左边:它是要记录的信息类型。

右边的列表是动作:将日志发送到哪里。

示例7-1中的大多数动作都是普通文件,但也有一些例外情况。

例如,/dev/console指的是系统控制台的特殊设备,root表示如果超级用户已登录,则向超级用户发送消息,而 * 表示向当前系统上的所有用户发送消息。

你还可以使用@host将消息发送到另一台网络主机。

Facility and Priority(设施和优先权)

The selector is a pattern that matches the facility and priority of log messages. The facility is a general category of message. (See rsyslog.conf(5) for a list of all facilities.)

选择器是一个匹配日志消息的设施和优先级的模式。

设施是一种消息的通用类别。

(请参阅rsyslog.conf(5)获取所有设施的列表。)

The function of most facilities will be fairly obvious from their name. For example, the configuration file in Example 7-1 catches messages carrying the kern, authpriv, mail, cron, and local7 facilities. In this same listing, the asterisk at ➋ is a wildcard that catches output related to all facilities.

大多数设施的功能从它们的名称中就可以很明显地看出来。

例如,示例7-1中的配置文件捕捉到了携带kern、authpriv、mail、cron和local7设施的消息

在同一列表中,➋处的星号是一个通配符,可以捕捉到与所有设施相关的输出。

The priority follows the dot (.) after the facility. The order of priorities from lowest to highest is debug, info, notice, warning, err, crit, alert, or emerg.

优先级紧跟在设施后面的点(.)之后。

从最低到最高的优先级顺序是debug、info、notice、warning、err、crit、alert或emerg。

NOTE To exclude log messages from a facility in rsyslog.conf, specify a priority of none, as shown at ➊ in Example 7-1.

注意:要在rsyslog.conf中排除某个设施的日志消息,请指定为none的优先级,如示例7-1中的➊所示。

When you put a specific priority in a selector, rsyslogd sends messages with that priority and all higher priorities to the destination on that line. Therefore, in Example 7-1, the *.info for the line at ➊ actually catches most log messages and puts them into /var/log/messages because info is a relatively low priority.

当您在选择器中放入一个特定的优先级时,rsyslogd会将具有该优先级及更高优先级的消息发送到该行上的目的地。

因此,在示例7-1中,位于➊处的 *.info 实际上捕捉到了大多数日志消息,并将它们放入到/var/log/messages中,因为info是一个相对较低的优先级。

Extended Syntax(扩展语法)

As previously mentioned, the syntax of rsyslogd extends the traditional syslogd syntax. The configuration extensions are called directives and usually begin with a $. One of the most common extensions allows you to load additional configuration files. Check your rsyslog.conf file for a directive like this, which causes rsyslogd to load all .conf files in /etc/rsyslog.d into the configuration:

如前所述,rsyslogd的语法扩展了传统syslogd的语法。

配置扩展被称为指令,通常以$符号开头。

其中最常见的扩展之一允许您加载额外的配置文件。

请检查您的rsyslog.conf文件,查找类似以下指令的内容,它会导致rsyslogd将/etc/rsyslog.d目录中的所有.conf文件加载到配置中:

$IncludeConfig /etc/rsyslog.d/*.conf

Most of the other extended directives are fairly self-explanatory. For example, these directives deal with users and permissions:

其他大多数扩展指令都相当直观。

例如,以下指令处理用户和权限:

$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022

NOTE Additional rsyslogd configuration file extensions define output templates and channels. If you need to use them, the rsyslogd(5) manual page is fairly comprehensive, but the web-based documentation is more complete.

注意:额外的rsyslogd配置文件扩展定义了输出模板和通道。

如果您需要使用它们,rsyslogd(5)手册页面非常详尽,但基于网络的文档更完整。

Troubleshooting(故障排除)

One of the easiest ways to test the system logger is to send a log message manually with the logger command, as shown here:

测试系统日志记录器最简单的方法之一是使用logger命令手动发送日志消息,如下所示:

$ logger -p daemon.info something bad just happened

Very little can go wrong with rsyslogd. The most common problems occur when a configuration doesn’t catch a certain facility or priority or when log files fill their disk partitions. Most distributions automatically trim the files in /var/log with automatic invocations of logrotate or a similar utility, but if too many messages arrive in a brief period, you can still fill the disk or end up with a high system load.

rsyslogd很少出现问题。

最常见的问题是配置未捕获特定的设施或优先级,或者日志文件填满了磁盘分区。

大多数发行版会自动使用logrotate或类似实用程序来修剪/var/log中的文件,但如果在短时间内收到太多消息,仍然可能会填满磁盘或导致系统负载过高。

NOTE The logs caught by rsyslogd are not the only ones recorded by various pieces of the system. We discussed the startup log messages captured by systemd and Upstart in Chapter 6, but you’ll find many other sources, such as the Apache Web server, which normally records its own access and error logs. To find those logs, see the server configuration.

注意:rsyslogd捕获的日志不是系统中各个组件记录的唯一日志。

我们在第6章中讨论了systemd和Upstart捕获的启动日志消息,但您还会找到许多其他来源,例如通常会记录自己的访问和错误日志的Apache Web服务器。

要找到这些日志,请参阅服务器配置。

Logging: Past and Future(日志记录:过去与未来)

The syslog service has evolved over time. For example, there was once a daemon called klogd that trapped kernel diagnostic messages for syslogd. (These messages are the ones you see with the dmesg command.) This capability has been folded into rsyslogd.

syslog服务随着时间的推移发生了变化。

例如,曾经有一个名为klogd的守护程序,用于捕获用于syslogd的内核诊断消息。

(这些消息是您使用dmesg命令看到的消息。)这个功能已经合并到rsyslogd中。

It’s a near certainty that Linux system logging will change in the future. Unix system logging has never had a true standard, but efforts are underway to change that.

可以几乎确定,Linux系统日志记录将来会发生变化。

Unix系统日志记录从来没有真正的标准,但正在进行努力来改变这一点。

7.3 User Management Files(用户管理文件)

Unix systems allow for multiple independent users. At the kernel level, users are simply numbers (user IDs), but because it’s much easier to remember a name than a number, you’ll normally work with usernames (or login names) instead of user IDs when managing Linux. Usernames exist only in user space, so any program that works with a username generally needs to be able to map the username to a user ID if it wants to refer to a user when talking to the kernel.

Unix系统允许多个独立用户。

在内核级别上,用户仅仅是一个数字(用户ID),但是因为记住名字比数字更容易,所以在管理Linux时通常使用用户名(或登录名)而不是用户ID。

用户名只存在于用户空间中,因此任何与用户名相关的程序如果想要与内核交流时引用用户,通常需要能够将用户名映射到用户ID。

7.3.1 The /etc/passwd File(/etc/passwd 文件)

The plaintext file /etc/passwd maps usernames to user IDs. It looks something like this:

明文文件 /etc/passwd 将用户名映射到用户 ID。它看起来像这样

Example 7-2. A list of users in /etc/passwd

例 7-2. /etc/passwd 中的用户列表

root:x:0:0:Superuser:/root:/bin/sh
daemon:*:1:1:daemon:/usr/sbin:/bin/sh
bin:*:2:2:bin:/bin:/bin/sh
sys:*:3:3:sys:/dev:/bin/sh
nobody:*:65534:65534:nobody:/home:/bin/false
juser:x:3119:1000:J. Random User:/home/juser:/bin/bash
beazley:x:143:1000:David Beazley:/home/beazley:/bin/bash

Each line represents one user and has seven fields separated by colons. The fields are as follows:

每一行代表一个用户,由冒号分隔的七个字段组成。字段如下:

o The username.
o The user’s encrypted password. On most Linux systems, the password is not actually stored in the passwd file, but rather, in the shadow file (see 7.3.3 The /etc/shadow File). The shadow file format is similar to that
of passwd, but normal users do not have read permission for shadow. The second field in passwd or shadow is the encrypted password, and it looks like a bunch of unreadable garbage, such as d1CVEWiB/oppc. (Unix passwords are never stored as clear text.) An x in the second passwd file field indicates that the encrypted password is stored in the shadow file. A star
(*) indicates that the user cannot log in, and if the field is blank (that is, you see two colons in a row, like ::), no password is required to log in. (Beware of blank passwords. You should never have a user without a password.) o The user ID (UID), which is the user’s representation in the kernel. You can have two entries with the same user ID, but doing this will confuse you, and your software may mix them up as well. Keep the user ID unique.
o The group ID (GID). This should be one of the numbered entries in the /etc/group file. Groups determine file permissions and little else. This group is also called the user’s primary group.
o The user’s real name (often called the GECOS field). You’ll sometimes find commas in this field, denoting room and telephone numbers.
o The user’s home directory.
o The user’s shell (the program that runs when the user runs a terminal session).

o 用户名。

o 用户的加密密码。在大多数Linux系统中,密码实际上并不存储在passwd文件中,而是存储在shadow文件中(参见7.3.3节“/etc/shadow文件”)。

shadow文件的格式与passwd类似,但普通用户没有对shadow的读取权限。

passwd或shadow文件的第二个字段是加密密码,它看起来像一堆无法读取的垃圾,例如d1CVEWiB/oppc

(Unix密码从不以明文形式存储。)在第二个passwd文件字段中的x表示加密密码存储在shadow文件中。星号(*)表示用户无法登录,如果字段为空(即连续两个冒号,如::),则登录时不需要密码。

(注意空密码。您永远不应该有一个没有密码的用户。)

o 用户ID(UID),它是用户在内核中的表示。您可以有两个具有相同用户ID的条目,但这样做会使您混淆,并且您的软件也可能混淆它们。保持用户ID唯一。

o 组ID(GID)。这应该是/etc/group文件中的一个编号条目。组确定文件权限,除此之外几乎没有其他作用。这个组也被称为用户的主要组。

o 用户的真实姓名(通常称为GECOS字段)。您有时会在该字段中找到逗号,表示房间号码和电话号码。

o 用户的主目录。

o 用户的shell(当用户运行终端会话时运行的程序)。

Figure 7-1 identifies the various fields in one of the entries in Example 7-2.

图7-1标识了示例7-2中一个条目中的各个字段。

Figure 7-1. An entry in the password file

Figure 7-1. An entry in the password file

图 7-1. 密码文件中的条目

The /etc/passwd file syntax is fairly strict, allowing for no comments or blank lines.

/etc/passwd 文件语法相当严格,不允许有注释或空行。

NOTE A user in /etc/passwd and a corresponding home directory are collectively known as an account.

注意 /etc/passwd 中的用户和相应的主目录统称为账户。

7.3.2 Special Users(特殊用户)

You will find a few special users in /etc/passwd. The superuser (root) always has UID 0 and GID 0, as in Example 7-2. Some users, such as daemon, have no login privileges. The nobody user is an underprivileged user. Some processes run as nobody because the nobody user cannot write to anything on the system.

在/etc/passwd文件中,您会发现一些特殊用户。

超级用户(root)的UID和GID始终为0,就像示例7-2中一样。

一些用户,比如daemon,没有登录权限。

nobody用户是一个非特权用户。

一些进程以nobody身份运行,因为nobody用户无法对系统上的任何内容进行写操作。

The users that cannot log in are called pseudo-users. Although they can’t log in, the system can start processes with their user IDs. Pseudo-users such as nobody are usually created for security reasons.

无法登录的用户被称为伪用户。

虽然他们无法登录,但系统可以使用他们的用户ID启动进程。

通常出于安全原因,会创建伪用户,比如nobody。

7.3.3 The /etc/shadow File(/etc/shadow文件)

The shadow password file (/etc/shadow) on a Linux system normally contains user authentication information, including the encrypted passwords and password expiration information that correspond to the users in /etc/passwd.

Linux系统上的阴影密码文件(/etc/shadow)通常包含用户认证信息,包括与/etc/passwd中的用户对应的加密密码和密码过期信息。

The shadow file was introduced to provide a more flexible (and more secure) way of storing passwords. It included a suite of libraries and utilities, many of which were soon replaced by pieces of PAM (see 7.10 PAM). Rather than introduce an entirely new set of files for Linux, PAM uses /etc/shadow, but not certain corresponding configuration files such as /etc/login.defs.

阴影文件的引入提供了一种更灵活(且更安全)的密码存储方式。

它包含了一套库和实用程序,其中许多很快被PAM的一些组件所取代(参见7.10 PAM)。

为了不引入全新的文件集合到Linux中,PAM使用了/etc/shadow,但并不使用一些对应的配置文件,比如/etc/login.defs。

7.3.4 Manipulating Users and Passwords(操作用户和密码)

Regular users interact with /etc/passwd using the passwd command. By default, passwd changes the user’s password, but you can also use -f to change the user’s real name or -s to change the user’s shell to one listed in /etc/shells. (You can also use the commands chfn and chsh to change the real name and shell.) The passwd command is an suid-root program, because only the superuser can change the /etc/passwd file.

普通用户通过使用passwd命令与/etc/passwd进行交互。

默认情况下,passwd命令用于更改用户的密码,但您也可以使用-f选项来更改用户的真实姓名,或者使用-s选项将用户的shell更改为/etc/shells中列出的shell之一。

(您还可以使用chfn和chsh命令来更改真实姓名和shell。)passwd命令是一个suid-root程序,因为只有超级用户才能更改/etc/passwd文件。

Changing /etc/passwd as the Superuser(以超级用户身份更改 /etc/passwd)

Because /etc/passwd is plaintext, the superuser may use any text editor to make changes. To add a user, simply add an appropriate line and create a home directory for the user; to delete, do the opposite. However, to edit the file, you’ll most likely want to use the vipw program, which backs up and locks /etc/passwd while you’re editing it as an added precaution. To edit /etc/shadow instead of /etc/passwd, use vipw -s. (You’ll likely never need to do this, though.)

因为/etc/passwd是明文文件,超级用户可以使用任何文本编辑器进行更改。

要添加用户,只需添加一行适当的内容并为用户创建一个主目录;要删除用户,执行相反的操作。

然而,要编辑该文件,您最可能想使用vipw程序,它在您编辑时备份并锁定/etc/passwd作为额外的预防措施。

要编辑/etc/shadow而不是/etc/passwd,请使用vipw -s。

(尽管您可能永远不需要这样做。)

Most organizations frown on editing passwd directly because it’s too easy to make a mistake. It’s much easier (and safer) to make changes to users using separate commands available from the terminal or through the GUI. For example, to set a user’s password, run passwd user as the superuser. Use adduser and userdel to add and remove users.

大多数组织不赞成直接编辑passwd,因为很容易出错。

使用终端或图形界面提供的单独命令进行用户更改要容易得多(也更安全)。

例如,要设置用户的密码,请以超级用户身份运行passwd user命令。

使用adduser和userdel命令来添加和删除用户。

7.3.5 Working with Groups(与小组合作)

Groups in Unix offer a way to share files with certain users but deny access to all others. The idea is that you can set read or write permission bits for a particular group, excluding everyone else. This feature was once important because many users shared one machine, but it’s become less significant in recent years as workstations are shared less often.

The /etc/group file defines the group IDs (such as the ones found in the /etc/passwd file). Example 7-3 is an example.

Example 7-3. A sample /etc/group file

Unix中的组提供了一种与特定用户共享文件但拒绝其他用户访问的方式。

其思想是您可以为特定组设置读取或写入权限位,排除其他所有人。

这个功能曾经非常重要,因为许多用户共享一台机器,但随着工作站共享的减少,它在近年来变得不那么重要了。

/etc/group文件定义了组ID(例如在/etc/passwd文件中找到的组ID)。示例7-3是一个示例。

示例7-3. 一个示例的/etc/group文件

root:*:0:juser
daemon:*:1:
bin:*:2:
sys:*:3:
adm:*:4:
disk:*:6:juser,beazley
nogroup:*:65534:
user:*:1000:

Like the /etc/passwd file, each line in /etc/group is a set of fields separated by colons. The fields in each entry are as follows, from left to right:

o The group name. This appears when you run a command like ls -l.
o The group password. This is hardly ever used, nor should you use it (use sudo instead). Use * or any other default value.
o The group ID (a number). The GID must be unique within the group file. This number goes into a user’s group field in that user’s /etc/passwd entry.
o An optional list of users that belong to the group. In addition to the users listed here, users with the corresponding group ID in their passwd file entries also belong to the group.

Figure 7-2 identifies the fields in a group file entry.

与/etc/passwd文件类似,/etc/group中的每一行都是由冒号分隔的一组字段。每个条目中的字段从左到右依次是:

o 组名。当您运行类似ls -l的命令时会显示该组名。

o 组密码。几乎不会使用,也不应该使用(应使用sudo代替)。

可以使用*或任何其他默认值。

o 组ID(一个数字)。组ID必须在组文件中是唯一的。

此数字会填入用户的组字段中,该字段位于用户的/etc/passwd条目中。

o 可选的属于该组的用户列表。除了在此处列出的用户之外,具有相应组ID的用户也属于该组。

图7-2标识了组文件条目中的字段。

Figure 7-2. An entry in the group file

Figure 7-2. An entry in the group file

图7-2. 组文件中的一个条目

To see the groups you belong to, run groups.

要查看您所属的组,请运行groups命令。

NOTE Linux distributions often create a new group for each new user added, with the same name as the user.

注意:Linux发行版通常会为每个新添加的用户创建一个与用户名相同的新组。

7.4 getty and login(获取并登录)

getty is a program that attaches to terminals and displays a login prompt. On most Linux systems, getty is uncomplicated because the system only uses it for logins on virtual terminals. In a process listing, it usually looks something like this (for example, when running on /dev/tty1):

getty是一个程序,它连接到终端并显示登录提示符。

在大多数Linux系统中,getty非常简单,因为系统只在虚拟终端上使用它进行登录。

在进程列表中,它通常看起来像这样(例如,在/dev/tty1上运行时):

$ ps ao args | grep getty
/sbin/getty 38400 tty1

In this example, 38400 is the baud rate. Some getty programs don’t need the baud rate setting. (Virtual terminals ignore the baud rate; it’s only there for backward compatibility with software that connects to real serial lines.)

在这个例子中,38400是波特率。

有些getty程序不需要波特率设(虚拟终端忽略波特率;它只是为了向连接到真实串行线路的软件提供向后兼容性。)

After you enter your login name, getty replaces itself with the login program, which asks for your password. If you enter the correct password, login replaces itself (using exec()) with your shell. Otherwise, you get a “Login incorrect” message.

在输入登录名后,getty会用登录程序替换自己,该程序会要求您输入密码。

如果您输入正确的密码,登录程序会用您的shell替换自己(使用exec())。

否则,您会收到“登录失败”的消息。

You now know what getty and login do, but you’ll probably never need to configure or change them. In fact, you’ll rarely even use them, because most users now log in either through a graphical interface such as gdm or remotely with SSH, neither of which uses getty or login. Much of the login program’s real authentication work is handled by PAM (see 7.10 PAM).

现在您知道getty和login的作用了,但您可能永远不需要配置或更改它们。

实际上,您很少使用它们,因为大多数用户现在通过图形界面(如gdm)或通过SSH远程登录,这两种方式都不使用getty或login。

登录程序的大部分身份验证工作都由PAM处理(参见7.10 PAM)。

7.5 Setting the Time(设置时间)

Unix machines depend on accurate timekeeping. The kernel maintains the system clock, which is the clock that is consulted when you run commands like date. You can also set the system clock using the date command, but it’s usually a bad idea to do so because you’ll never get the time exactly right. Your system clock should be as close to the correct time as possible.

Unix机器依赖准确的时间记录。内核维护着系统时钟,当你运行像date这样的命令时会查询该时钟。

你也可以使用date命令设置系统时钟,但通常这样做是不明智的,因为你永远无法完全准确地获得时间。你的系统时钟应尽可能接近正确的时间。

PC hardware has a battery-backed real-time clock (RTC). The RTC isn’t the best clock in the world, but it’s better than nothing. The kernel usually sets its time based on the RTC at boot time, and you can reset the system clock to the current hardware time with hwclock. Keep your hardware clock in Universal Coordinated Time (UTC) in order to avoid any trouble with time zone or daylight savings time corrections. You can set the RTC to your kernel’s UTC clock using this command:

PC硬件有一个带有电池备份的实时时钟(RTC)。

RTC并不是世界上最好的时钟,但总比没有好。

内核通常在启动时根据RTC设置时间,并且你可以使用hwclock将系统时钟重置为当前硬件时间。

为了避免与时区或夏令时校正引起的任何问题,你应将硬件时钟设置为协调世界时(UTC)。

你可以使用以下命令将RTC设置为内核的UTC时钟:

# hwclock --hctosys --utc

Unfortunately, the kernel is even worse at keeping time than the RTC, and because Unix machines often stay up for months or years on a single boot, they tend to develop time drift. Time drift is the current difference between the kernel time and the true time (as defined by an atomic clock or another very accurate clock).

不幸的是,内核在时间保持方面甚至比RTC更差,因为Unix机器通常在单次启动上运行数月或数年,它们往往会出现时间漂移。

时间漂移是内核时间与真实时间(由原子钟或其他非常准确的时钟定义)之间的差异。

You should not try to fix the drift with hwclock because time-based system events can get lost or mangled. You could run a utility like adjtimex to smoothly update the clock, but usually it’s best to keep your system time correct with a network time daemon (see 7.5.2 Network Time).

你不应该尝试使用hwclock来修复漂移,因为基于时间的系统事件可能会丢失或损坏。

补充(来自网络):

实际上,linux系统有两个时钟:一个是由主板电池驱动的“Real Time Clock”也叫做RTC或者叫CMOS时钟,硬件时钟。当操作系统关机的时候,用这个来记录时间,但是对于运行的系统是不用这个时间的。

另一个时间是 “System clock”也叫内核时钟或者软件时钟,是由软件根据时间中断来进行计数的,内核时钟在系统关机的情况下是不存在的,所以,当操作系统启动的时候,内核时 钟是要读取RTC时间来进行时间同步(有些情况下,内核时钟也可以通过ntp服务器来读取时间)

这两个时钟通常会有一些误差,所以长时间可以导致 这两个时钟偏离的比较多,最简单的保持两个时间同步的方法是用软件测出他们之间的误差率,然后用软件进行修正。在每次重新启动系统的时候,系统都会用 hwclock命令对时间进行同步。如果内核时钟在每一个时间中断都快或者慢的话,可以用adjtimex命令进行调整,使得RTC和内核时间走的快慢一 致。

linux的内核时间实际上是记录从1970年1月1日距离现在的秒数,并且以GMT(格林尼治时间)(或者叫UTC- Coordinated Universal Time)为标准,UTC是不随着DST(夏令时)变换,需要有变化的是由应用程序自身来完成时间的转换。

通常,本地时间=UTC时间+时区在安装linux系统的时候,可能正确设置了时区,但由于某些原因需要调整的时候,请参考以下方法利用tzselect命令可以修改系统的当前时区,配置文件储存在/etc/sysconfig/clock文件中(Redhat As3)

你可以运行像adjtimex这样的实用程序来平滑更新时钟,但通常最好使用网络时间守护程序来保持系统时间准确(参见7.5.2 网络时间)。

7.5.1 Kernel Time Representation and Time Zones(内核时间表示法和时区)

The kernel’s system clock represents the current time as the number of seconds since 12:00 midnight on January 1, 1970, UTC. To see this number at the moment, run:

内核的系统时钟将当前时间表示为自1970年1月1日午夜12:00以来的秒数,以协调世界时(UTC)为准。要立即查看此数字,请运行:

$ date +%s

To convert this number into something that humans can read, user-space programs change it to local time and compensate for daylight savings time and any other strange circumstances (such as living in Indiana). The local time zone is controlled by the file /etc/localtime. (Don’t bother trying to look at it; it’s a binary file.)

为了将这个数字转换成人类可读的形式,用户空间程序将其转换为本地时间,并补偿夏令时和其他奇怪的情况(比如生活在印第安纳州)。

本地时区由文件/etc/localtime控制。(不要费心去查看它;它是一个二进制文件。)

The time zone files on your system are in /usr/share/zoneinfo. You’ll find that this directory contains a lot of time zones and a lot of aliases for time zones. To set your system’s time zone manually, either copy one of the files in /usr/share/zoneinfo to /etc/localtime (or make a symbolic link) or change it with your distribution’s time zone tool. (The command-line program tzselect may help you identify a time zone file.)

您系统上的时区文件位于/usr/share/zoneinfo。

您会发现这个目录包含许多时区和许多时区的别名。

要手动设置系统的时区,可以将/usr/share/zoneinfo中的一个文件复制到/etc/localtime(或创建一个符号链接),或者使用您发行版的时区工具进行更改。

(命令行程序tzselect可能会帮助您识别一个时区文件。)

To use a time zone other than the system default for just one shell session, set the TZ environment variable to the name of a file in /usr/share/ zoneinfo and test the change, like this:

要在仅对一个shell会话使用非系统默认时区,请将TZ环境变量设置为/usr/share/zoneinfo中的文件名,并测试更改,如下所示:

$ export TZ=US/Central
$ date

As with other environment variables, you can also set the time zone for the duration of a single command like this:

与其他环境变量一样,您也可以像这样为单个命令的持续时间设置时区:

$ TZ=US/Central date

7.5.2 Network Time(网络时间)

If your machine is permanently connected to the Internet, you can run a Network Time Protocol (NTP) daemon to maintain the time using a remote server. Many distributions have built-in support for an NTP daemon, but it may not be enabled by default. You might need to install an ntpd package to get it to work.

如果您的机器长期连接到互联网,您可以运行一个网络时间协议(NTP)守护进程,使用远程服务器来维护时间。

许多发行版都内置了对NTP守护进程的支持,但默认情况下可能未启用。

您可能需要安装一个ntpd软件包才能使其正常工作。

If you need to do the configuration by hand, you’ll find help on the main NTP web page at http://www.ntp.org/, but if you’d rather not read through the mounds of documentation there, do this:

如果您需要手动进行配置,您可以在主NTP网页 上找到帮助,但如果您不想阅读那里的大量文档,可以按照以下步骤操作:

  1. Find the closest NTP time server from your ISP or from the ntp.org web page.
  2. Put that time server in /etc/ntpd.conf.
  3. Run ntpdate server at boot time.
  4. Run ntpd at boot time, after the ntpdate command.
  5. 从您的ISP或ntp.org网页上找到最近的NTP时间服务器。
  6. 将该时间服务器放入/etc/ntpd.conf文件中。
  7. 在启动时运行ntpdate服务器。
  8. 在启动时运行ntpd命令,该命令在ntpdate命令之后运行。

If your machine doesn’t have a permanent Internet connection, you can use a daemon like chronyd to maintain the time during disconnections.

如果您的机器没有长期的互联网连接,您可以使用像chronyd这样的守护进程来在断开连接期间维护时间。

You can also set your hardware clock based on the network time in order to help your system maintain time coherency when it reboots. (Many distributions do this automatically.) To do so, set your system time from the network with ntpdate (or ntpd), then run the command you saw back in Note:

您还可以根据网络时间设置您的硬件时钟,以帮助系统在重新启动时保持时间的一致性。

(许多发行版会自动执行此操作。)

要这样做,请使用ntpdate(或ntpd)从网络设置系统时间,然后运行您在注释中看到的命令。

# hwclock --systohc –-utc

7.6 Scheduling Recurring Tasks with cron(使用 cron 调度循环任务)

The Unix cron service runs programs repeatedly on a fixed schedule. Most experienced administrators consider cron to be vital to the system because it can perform automatic system maintenance. For example, cron runs log file rotation utilities to ensure that your hard drive doesn’t fill up with old log files. You should know how to use cron because it’s just plain useful.

Unix cron服务按固定的时间表重复运行程序。

大多数经验丰富的管理员认为cron对系统至关重要,因为它可以执行自动系统维护。

例如,cron运行日志文件轮转工具,以确保您的硬盘不会被旧日志文件填满。

您应该知道如何使用cron,因为它非常实用。

You can run any program with cron at whatever times suit you. The program running through cron is called a cron job. To install a cron job, you’ll create an entry line in your crontab file, usually by running the crontab command. For example, the crontab entry schedules the /home/juser/bin/spmake command daily at 9:15 AM:

您可以在cron中根据自己的时间安排运行任何程序。

通过cron运行的程序称为cron作业。

要安装cron作业,您需要在crontab文件中创建一个条目行,通常通过运行crontab命令来完成。

例如,以下crontab条目将在每天上午9:15运行/home/juser/bin/spmake命令:

15 09 * * * /home/juser/bin/spmake

The five fields at the beginning of this line, delimited by whitespace, specify the scheduled time (see also Figure 7-3). The fields are as follows, in order:

此行开头的五个字段由空格分隔,指定了计划的时间(另请参见图7-3)。

字段依次为:

o Minute (0 through 59). The cron job above is set for minute 15.
o Hour (0 through 23). The job above is set for the ninth hour.
o Day of month (1 through 31).
o Month (1 through 12).
o Day of week (0 through 7). The numbers 0 and 7 are Sunday

o 分钟(0到59)。上述cron作业设置为15分钟。
o 小时(0到23)。上述作业设置为第9小时。
o 日期(1到31)。
o 月份(1到12)。
o 星期几(0到7)。数字0和7表示星期天。

Figure 7-3. An entry in the crontab file

Figure 7-3. An entry in the crontab file

图7-3. crontab文件中的一个条目

A star (*) in any field means to match every value. The preceding example runs spmake daily because the day of month, month, and day of week fields are all filled with stars, which cron reads as “run this job every day, of every month, of every week.”

在任何字段中的星号(*)表示匹配每个值。

前面的示例中,spmake每天运行一次,因为月份、星期和日期字段都填满了星号,cron将其解读为“每天,每月,每周运行此作业”。

To run spmake only on the 14th day of each month, you would use this crontab line:

要仅在每月的第14天运行spmake,您可以使用以下crontab行:

15 09 14 * * /home/juser/bin/spmake

You can select more than one time for each field. For example, to run the program on the 5th and the 14th day of each month, you could enter 5,14 in the third field:

您可以为每个字段选择多个时间。例如,要在每月的 5 日和 14 日运行程序,您可以在第三个字段中输入 5、14:

15 09 5,14 * * /home/juser/bin/spmake

NOTE If the cron job generates standard output or an error or exits abnormally, cron should mail this information to you. Redirect the output to /dev/null or some other log file if you find the email annoying.

注意:如果cron作业生成标准输出、错误信息或异常退出,cron应该将这些信息发送给您。

如果您觉得邮件很烦人,请将输出重定向到/dev/null或其他日志文件。

The crontab(5) manual page provides complete information on the crontab format.

crontab(5)手册页面提供了关于crontab格式的完整信息。

7.6.1 Installing Crontab Files(安装 Crontab 文件)

Each user can have his or her own crontab file, which means that every system may have multiple crontabs, usually found in /var/spool/cron/crontabs. Normal users can’t write to this directory; the crontab command installs, lists, edits, and removes a user’s crontab.

每个用户都可以拥有自己的crontab文件,这意味着每个系统可能有多个crontab文件,通常存放在/var/spool/cron/crontabs目录中。

普通用户无法写入该目录;crontab命令用于安装、列出、编辑和删除用户的crontab。

The easiest way to install a crontab is to put your crontab entries into a file and then use crontab file to install file as your current crontab. The crontab command checks the file format to make sure that you haven’t made any mistakes. To list your cron jobs, run crontab -l. To remove the crontab, use crontab -r.

安装crontab的最简单方法是将crontab条目放入一个文件中,然后使用crontab file命令将该文件安装为当前的crontab。

crontab命令会检查文件格式,以确保没有发生任何错误。

要列出cron作业,请运行crontab -l命令。要删除crontab,请使用crontab -r命令。

However, after you’ve created your initial crontab, it can be a bit messy to use temporary files to make further edits. Instead, you can edit and install your crontab in one step with the crontab -e command. If you make a mistake, crontab should tell you where the mistake is and ask if you want to try editing again.

然而,在创建了初始的crontab之后,使用临时文件进行进一步编辑可能会有些混乱。

相反,您可以使用crontab -e命令一次性编辑和安装您的crontab。

如果出现错误,crontab会告诉您错误的位置,并询问是否要重新编辑。

7.6.2 System Crontab Files(系统 Crontab 文件)

Rather than use the superuser’s crontab to schedule recurring system tasks, Linux distributions normally have an /etc/crontab file. Don’t use crontab to edit this file, because this version has an additional field inserted before the command to run—the user that should run the job. For example, this cron job defined in /etc/crontab runs at 6:42 AM as the superuser (root, shown at ➊):

与其使用超级用户的crontab来安排定期系统任务,Linux发行版通常会有一个/etc/crontab文件。

不要使用crontab来编辑此文件,因为这个版本在要运行的命令之前插入了一个额外的字段——应该运行该作业的用户。

例如,在/etc/crontab中定义的这个cron作业将以超级用户(root,在➊处显示)身份在上午6:42运行:

42 6 * * * root➊ /usr/local/bin/cleansystem > /dev/null 2>&1

NOTE Some distributions store system crontab files in the /etc/cron.d directory. These files may have any name, but they have the same format as /etc/crontab.

注意:一些发行版将系统crontab文件存储在/etc/cron.d目录中。这些文件可以有任何名称,但格式与/etc/crontab相同。

7.6.3 The Future of cron(cron 的未来)

The cron utility is one of the oldest components of a Linux system; it’s been around for decades (predating Linux itself), and its configuration format hasn’t changed much for many years. When something gets to be this old, it becomes fodder for replacement, and there are efforts underway to do exactly that.

cron实用程序是Linux系统中最古老的组件之一;它已经存在了几十年(早于Linux本身),其配置格式多年来几乎没有改变。

当一样东西变得如此古老时,它就成为替代的素材,目前正在进行相关工作。

The proposed replacements are actually just parts of the newer versions of init: For systemd, there are timer units, and for Upstart, the idea is to be able to create recurring events to trigger jobs. After all, both versions of init can run tasks as any user, and they offer certain advantages, such as custom logging.

提议的替代方案实际上只是较新版本的init的一部分:对于systemd,有定时器单元;对于Upstart,想法是能够创建定期事件来触发作业。

毕竟,两个版本的init都可以以任何用户身份运行任务,并且它们提供了某些优势,如自定义日志记录。

However, the reality is that neither systemd nor Upstart currently has all of the capabilities of cron. Furthermore, when they do become capable, backward compatibility will be necessary to support everything that relies on cron. For these reasons, it’s unlikely that the cron format will go away anytime soon.

然而,事实是,无论是systemd还是Upstart目前都没有cron的所有功能。

此外,当它们确实具备这些功能时,向后兼容性将是必要的,以支持依赖于cron的所有内容。

出于这些原因,cron格式不太可能很快消失。

7.7 Scheduling One-Time Tasks with at(安排一次性任务)

To run a job once in the future without using cron, use the at service. For example, to run myjob at 10:30 PM, enter this command:

要在将来的某个时间运行一次作业而不使用cron,请使用at服务。

例如,要在晚上10:30运行myjob,请输入以下命令:

$ at 22:30
at> myjob

End the input with CTRL-D. (The at utility reads the commands from the standard input.)

使用CTRL-D结束输入。

(at实用程序从标准输入读取命令。)

To check that the job has been scheduled, use atq. To remove it, use atrm. You can also schedule jobs days into the future by adding the date in DD.MM.YY format, for example, at 22:30 30.09.15.

要检查作业是否已计划,请使用atq。

要删除作业,请使用atrm。

您还可以通过在DD.MM.YY格式中添加日期来安排未来几天的作业,例如at 22:30 30.09.15。

There isn’t much else to the at command. Though at isn’t used that often, it can be handy for that odd time when you need to tell the system to shut down in the future.

at命令没有太多其他用途。虽然at并不经常使用,但在需要告诉系统在将来关闭的奇怪时间时,它可能会很方便。

7.8 Understanding User IDs and User Switching(了解用户 ID 和用户切换)

We’ve discussed how setuid programs such as sudo and su allow you to change users, and we’ve mentioned system components like login that control user access. Perhaps you’re wondering how these pieces work and what role the kernel plays in user switching

我们已经讨论了像sudo和su这样的setuid程序如何允许您更改用户,并提到了控制用户访问的登录等系统组件。

也许您想知道这些部分是如何工作的,内核在用户切换中扮演了什么角色。

There are two ways to change a user ID, and the kernel handles both. The first is with a setuid executable, which is covered in 2.17 File Modes and Permissions. The second is through the setuid() family of system calls. There are a few different versions of this system call to accommodate the various user IDs associated with a process, as you’ll learn in 7.8.1 Process Ownership, Effective UID, Real UID, and Saved UID.

有两种方法可以更改用户ID,内核处理这两种方法。

第一种是使用setuid可执行文件,这在2.17文件模式和权限中有介绍。

第二种是通过setuid()系统调用系列。

有几个不同版本的这个系统调用来适应与进程关联的各种用户ID,您将在7.8.1进程所有权、有效UID、真实UID和保存UID中了解到。

The kernel has basic rules about what a process can or can’t do, but here are the three basics:

内核对进程能够做什么或不能做什么有基本规则,但以下是三个基本原则:

o A process running as root (userid 0) can use setuid() to become any other user.
o A process not running as root has severe restrictions on how it may use setuid(); in most cases, it
cannot.
o Any process can execute a setuid program as long as it has adequate file permissions.

o 以root(用户ID为0)身份运行的进程可以使用setuid()成为任何其他用户。

o 非以root身份运行的进程在使用setuid()时有严格的限制;在大多数情况下,它是不允许的。

o 只要具有足够的文件权限,任何进程都可以执行setuid程序。

NOTE User switching has nothing to do with passwords or usernames. Those are strictly user-space concepts, as you first saw in the /etc/passwd file in 7.3.1 The /etc/passwd File. You’ll learn more details about how this works in 7.9.1 Using Libraries for User Information.

注意用户切换与密码或用户名无关。

这些严格来说是用户空间的概念,正如您在7.3.1 /etc/passwd文件中首次看到的那样。

您将在7.9.1使用库获取用户信息中了解更多详细信息。

7.8.1 Process Ownership, Effective UID, Real UID, and Saved UID

Our discussion of user IDs so far has been simplified. In reality, every process has more than one user ID. We’ve described the effective user ID (euid), which defines the access rights for a process. A second user ID, the real user ID (ruid), indicates who initiated a process. When you run a setuid program, Linux sets the effective user ID to the program’s owner during execution, but it keeps your original user ID in the real user ID.

我们之前对用户ID的讨论已经进行了简化。

实际上,每个进程都有多个用户ID。

我们已经描述了有效用户ID(euid),它定义了进程的访问权限。

第二个用户ID,真实用户ID(ruid),表示启动进程的用户。

当您运行一个setuid程序时,Linux在执行过程中将有效用户ID设置为程序的所有者,但保留您的原始用户ID作为真实用户ID。

On modern systems, the difference between the effective and real user IDs is confusing, so much so that a lot of documentation regarding process ownership is incorrect.

在现代系统中,有效用户ID和真实用户ID之间的区别很令人困惑,以至于关于进程所有权的很多文档都是错误的。

Think of the effective user ID as the actor and the real user ID as the owner. The real user ID defines the user that can interact with the running process—most significantly, which user can kill and send signals to a process. For example, if user A starts a new process that runs as user B (based on setuid permissions), user A still owns the process and can kill it.

将有效用户ID视为演员,将真实用户ID视为所有者。

真实用户ID定义了可以与运行中的进程交互的用户,最重要的是,哪个用户可以终止进程和发送信号给进程。

例如,如果用户A启动一个以用户B身份运行的新进程(基于setuid权限),用户A仍然拥有该进程并可以终止它。

On normal Linux systems, most processes have the same effective user ID and real user ID. By default, ps and other system diagnostic programs show the effective user ID. To view both the effective and real user IDs on your system, try this, but don’t be surprised if you find that the two user ID columns are identical for all processes on your system:

在正常的Linux系统中,大多数进程的有效用户ID和真实用户ID相同。

默认情况下,ps和其他系统诊断程序显示有效用户ID。

要在您的系统上查看有效用户ID和真实用户ID,请尝试以下操作,但如果您发现所有进程的两个用户ID列相同,也不要感到惊讶:

$ ps -eo pid,euser,ruser,comm

To create an exception just so that you can see different values in the columns, try experimenting by creating a setuid copy of the sleep command, running the copy for a few seconds, and then running the preceding ps command in another window before the copy terminates.

为了在列中看到不同的值,可以尝试创建一个setuid的sleep命令的副本,并在副本运行几秒钟后,在另一个窗口中运行前面的ps命令,然后再副本终止之前。

To add to the confusion, in addition to the real and effective user IDs, there is also a saved user ID (which is usually not abbreviated). A process can switch its effective user ID to the real or saved user ID during execution. (To make things even more complicated, Linux has yet another user ID: the file system user ID [fsuid], which defines the user accessing the filesystem but is rarely used.)

为了增加混淆,除了真实用户ID和有效用户ID之外,还有一个保存的用户ID(通常不缩写)。

进程可以在执行过程中将其有效用户ID切换为真实用户ID或保存的用户ID。

(为了让事情更加复杂,Linux还有另一个用户ID:文件系统用户ID [fsuid],它定义了访问文件系统的用户,但很少使用。)

Typical Setuid Program Behavior(典型的 Setuid 程序行为)

The idea of the real user ID might contradict your previous experience. Why don’t you have to deal with the other user IDs very frequently? For example, after starting a process with sudo, if you want to kill it, you still use sudo; you can’t kill it as your own regular user. Shouldn’t your regular user be the real user ID in this case, giving you the correct permissions?

真实用户ID的概念可能与您之前的经验相矛盾。为什么您不经常处理其他用户ID呢?

例如,在使用sudo启动进程后,如果您想要终止它,您仍然需要使用sudo;您不能使用您自己的普通用户身份终止它。

在这种情况下,您的普通用户不应该是真实用户ID吗?从而给您正确的权限?

The cause of this behavior is that sudo and many other setuid programs explicitly change the effective and real user IDs with one of the setuid() system calls. These programs do so because there are often unintended side effects and access problems when all of the user IDs do not match.

这种行为的原因是sudo和许多其他setuid程序使用setuid()系统调用明确地更改有效和真实用户ID。

这些程序这样做是因为当所有用户ID不匹配时,往往会出现意外的副作用和访问问题。

NOTE If you’re interested in the details and rules regarding user ID switching, read the setuid(2) manual page and check the other manual pages listed in the SEE ALSO section. There are many different system calls for diverse situations.

注意:如果您对用户ID切换的细节和规则感兴趣,请阅读setuid(2)手册页,并检查SEE ALSO部分列出的其他手册页。有许多不同的系统调用适用于不同的情况。

Some programs don’t like to have a real user ID of root. To prevent sudo from changing the real user ID, add this line to your /etc/sudoers file (and beware of side effects on other programs you want to run as root!):

有些程序不喜欢具有root的真实用户ID。为了防止sudo更改真实用户ID,请将以下行添加到您的/etc/sudoers文件中(并注意对您希望以root身份运行的其他程序可能产生的副作用!):

Defaults stay_setuid
Security Implications(对安全的影响)

Because the Linux kernel handles all user switches (and as a result, file access permissions) through setuid programs and subsequent system calls, systems developers and administrators must be extremely careful with two things:

因为Linux内核通过setuid程序和随后的系统调用来处理所有用户切换(以及文件访问权限),所以系统开发人员和管理员必须非常小心处理两个方面:

o The programs that have setuid permissions
o What those programs do

o 具有setuid权限的程序

o 这些程序的功能

If you make a copy of the bash shell that is setuid root, any local user can execute it and have complete run of the system. It’s really that simple. Furthermore, even a special-purpose program that is setuid root can pose a danger if it has bugs. Exploiting weaknesses in programs running as root is a primary method of systems intrusion, and there are too many such exploits to count.

如果你复制了一个设置了setuid root权限的bash shell,任何本地用户都可以执行它并完全控制系统。

就是这么简单。

此外,即使是设置了setuid root权限的特定目的程序,如果存在漏洞,也可能构成危险。

利用以root身份运行的程序中的弱点是系统入侵的主要方法,而此类漏洞利用的数量多得无法计数。

Because there are so many ways to break into a system, preventing intrusion is a multifaceted affair. One of the most essential ways to keep unwanted activity off your system is to enforce user authentication with usernames and passwords.

由于有很多方法可以侵入系统,防止入侵是一项多方面的工作。

保证用户身份验证使用用户名和密码是保持系统不受非法活动侵扰的最基本方式之一。

7.9 User Identification and Authentication(用户识别和认证)

A multiuser system must provide basic support for user security in terms of identification and authentication. The identification portion of security answers the question of who users are. The authentication piece asks users to prove that they are who they say they are. Finally, authorization is used to define and limit what users are allowed to do.

一个多用户系统必须在身份识别和认证方面为用户提供基本的安全支持。

安全的身份识别部分回答了用户是谁的问题。认证部分要求用户证明他们是他们所声称的人。

最后,授权用于定义和限制用户被允许做什么。

When it comes to user identification, the Linux kernel knows only the numeric user IDs for process and file ownership. The kernel knows authorization rules for how to run setuid executables and how user IDs may run the setuid() family of system calls to change from one user to another. However, the kernel does not know anything about authentication: usernames, passwords, and so on. Practically everything related to authentication happens in user space.

当涉及到用户身份识别时,Linux内核只知道进程和文件所有权的数字用户ID。

内核知道如何运行setuid可执行文件的授权规则,以及用户ID如何运行setuid()系统调用来从一个用户切换到另一个用户。

然而,内核对认证方面一无所知:用户名、密码等等。

实际上,与认证相关的几乎所有事情都发生在用户空间。

We discussed the mapping between user IDs and passwords in 7.3.1 The /etc/passwd File; now we’ll explain how user processes access this mapping. We’ll begin with an oversimplified case, in which a user process wants to know its username (the name corresponding to the effective user ID). On a traditional Unix system, a process could do something like this to get its username:

我们在7.3.1节“/etc/passwd文件”中讨论了用户ID和密码之间的映射;现在我们将解释用户进程如何访问这个映射。

我们将从一个过于简化的情况开始,即一个用户进程想要知道它的用户名(对应有效用户ID的名称)。

在传统的Unix系统上,一个进程可以通过以下方式获取它的用户名:

  1. The process asks the kernel for its effective user ID with the geteuid() system call.
  2. The process opens the /etc/passwd file and starts reading at the beginning.
  3. The process reads a line of the /etc/passwd file. If there’s nothing left to read, the process has failed to find the username.
  4. The process parses the line into fields (breaking out everything between the colons). The third field is the user ID for the current line.
  5. The process compares the ID from Step 4 to the ID from Step 1. If they’re identical, the first field in Step 4 is the desired username, and the process can stop searching and use this name.
  6. The process moves on to the next line in /etc/passwd and goes back to Step 3.
  7. 进程使用geteuid()系统调用询问内核它的有效用户ID。
  8. 进程打开/etc/passwd文件并从开头开始读取。
  9. 进程读取/etc/passwd文件的一行。如果没有剩下的内容可读,进程将无法找到用户名。
  10. 进程将该行解析为字段(将冒号之间的内容分隔出来)。第三个字段是当前行的用户ID。
  11. 进程将步骤4中的ID与步骤1中的ID进行比较。如果它们相同,步骤4中的第一个字段就是所需的用户名,进程可以停止搜索并使用这个名称。
  12. 进程继续读取/etc/passwd中的下一行,并回到步骤3。

This is a long procedure that’s usually much more complicated in reality.

这是一个通常在现实中更加复杂的过程。

7.9.1 Using Libraries for User Information(利用图书馆获取用户信息)

If every developer who needed to know the current username had to write all of the code you’ve just seen, the system would be a horrifyingly disjointed, buggy, bloated, and unmaintainable mess. Fortunately, we can use standard libraries to perform repetitive tasks, so all you’d normally need to do to get a username is call a function like getpwuid() in the standard library after you have the answer from geteuid(). (See the manual pages for these calls for more on how they work.)

如果每个需要知道当前用户名的开发者都必须编写你刚才看到的所有代码,那么系统将变得非常不连贯、有错误、臃肿且难以维护。

幸运的是,我们可以使用标准库来执行重复的任务,所以通常你只需要在从geteuid()获取答案后调用一个像getpwuid()这样的函数就可以获得用户名。

(有关这些调用的更多信息,请参阅相关手册页。)

When the standard library is shared, you can make significant changes to the implementation without changing any other program. For example, you can move away from using /etc/passwd for your users and use a network service such as LDAP instead.

当共享标准库时,你可以对实现进行重大更改,而不会影响其他任何程序。

例如,你可以放弃使用/etc/passwd作为用户的存储方式,而改用网络服务,如LDAP。

This approach has worked well for identifying usernames associated with user IDs, but passwords have proven more troublesome. 7.3.1 The /etc/passwd File describes how, traditionally, the encrypted password was part of /etc/passwd, so if you wanted to verify a password that a user entered, you’d encrypt whatever the user typed and compare it to the contents of the /etc/passwd file.

这种方法在识别与用户ID相关联的用户名方面效果很好,但密码的处理则更加麻烦。

7.3.1节“/etc/passwd文件”描述了传统上,加密密码是/etc/passwd文件的一部分,因此如果你想要验证用户输入的密码,你需要加密用户输入的内容并将其与/etc/passwd文件中的内容进行比较。

This traditional implementation has the following limitations:

这种传统实现有以下限制:

o It doesn’t set a system-wide standard for the encryption protocol.
o It assumes that you have access to the encrypted password.
o It assumes that you want to prompt the user for a password every time the user wants to access something that requires authentication (which gets annoying).
o It assumes that you want to use passwords. If you want to use one-time tokens, smart cards, biometrics, or some other form of user authentication, you have to add that support yourself.

  • 它没有为加密协议设定系统范围的标准。
  • 它假设你可以访问加密密码。
  • 它假设每次用户想要访问需要身份验证的内容时,你都要提示用户输入密码(这很烦人)。
  • 它假设你想要使用密码。如果你想要使用一次性令牌、智能卡、生物识别或其他形式的用户认证,你必须自行添加支持。

Some of these limitations contributed to the development of the shadow password package discussed in 7.3.3 The /etc/shadow File, which took the first step in allowing system-wide password configuration. But the solution to the bulk of the problems came with the design and implementation of PAM.

其中一些限制促使我们开发了7.3.3节“/etc/shadow文件”中讨论的阴影密码包,它迈出了实现系统范围密码配置的第一步。

但是,解决大部分问题的方案是通过设计和实现PAM来实现的。

7.10 PAM

To accommodate flexibility in user authentication, in 1995 Sun Microsystems proposed a new standard called Pluggable Authentication Modules (PAM), a system of shared libraries for authentication (Open Source Software Foundation RFC 86.0, October 1995). To authenticate a user, an application hands the user to PAM to determine whether the user can successfully identify itself. This way, it’s relatively easy to add support for additional authentication techniques, such as two-factor and physical keys. In addition to authentication mechanism support, PAM also provides a limited amount of authorization control for services (for example, if you’d like to deny a service like cron to certain users).

为了适应用户认证的灵活性,Sun Microsystems在1995年提出了一个名为可插拔认证模块(PAM)的新标准,它是一个用于认证的共享库系统(开放源代码软件基金会RFC 86.0,1995年10月)。

为了验证用户身份,应用程序将用户交给PAM来确定用户是否能成功地进行身份验证。

这样,相对容易地添加对其他身份验证技术的支持,比如双因素认证和物理密钥。

除了认证机制的支持,PAM还为服务提供了有限的授权控制(例如,如果您想要拒绝某些用户使用cron这样的服务)。

Because there are many kinds of authentication scenarios, PAM employs a number of dynamically loadable authentication modules. Each module performs a specific task; for example, the pam_unix.so module can check a user’s password.

由于存在许多种认证场景,PAM使用了许多可动态加载的认证模块。

每个模块执行特定的任务;例如,pam_unix.so模块可以检查用户的密码。

This is tricky business, to say the least. The programming interface isn’t easy, and it’s not clear that PAM actually solves all of the existing problems. Nevertheless, PAM support is in nearly every program that requires authentication on a Linux system, and most distributions use PAM. And because it works on top of the existing Unix authentication API, integrating support into a client requires little, if any, extra work.

这是一项相当棘手的工作,可以说至少如此。

编程接口并不简单,而且并不清楚PAM是否真正解决了所有现有的问题。

尽管如此,几乎在每个需要在Linux系统上进行身份验证的程序中都有PAM支持,并且大多数发行版都使用PAM。由于它建立在现有的Unix认证API之上,将支持集成到客户端中几乎不需要额外的工作。

7.10.1 PAM Configuration(PAM 配置)

We’ll explore the basics of how PAM works by examining its configuration. You’ll normally find PAM’s application configuration files in the /etc/pam.d directory (older systems may use a single /etc/pam.conf file). Most installations include many files, so you may not know where to start. Some filenames should correspond to parts of the system that you know already, such as cron and passwd.

我们将通过检查其配置来了解 PAM 的基本工作原理。

通常,您会在 /etc/pam.d 目录中找到 PAM 的应用程序配置文件(旧系统可能使用单个 /etc/pam.conf 文件)。

大多数安装包含许多文件,所以您可能不知道从哪里开始。

一些文件名应该对应于您已经了解的系统部分,例如 cron 和 passwd。

Because the specific configuration in these files varies significantly between distributions, it can be difficult to find a common example. We’ll look at an example configuration line that you might find for chsh (the change shell program):

由于这些文件中的具体配置在不同的发行版之间有很大差异,因此很难找到一个通用的示例。

我们来看一个可能在 chsh(更改 shell 程序)中找到的示例配置行:

auth requisite pam_shells.so

This line says that the user’s shell must be in /etc/shells in order for the user to successfully authenticate with the chsh program. Let’s see how. Each configuration line has three fields: a function type, control argument, and module, in that order. Here’s what they mean for this example:

这行表示用户的 shell 必须在 /etc/shells 中,才能成功使用 chsh 程序进行身份验证。

让我们看看具体是如何工作的。每个配置行有三个字段:函数类型、控制参数和模块,依次排列。

对于这个示例,它们的含义如下:

o Function type. The function that a user application asks PAM to perform. Here, it’s auth, the task of authenticating the user.
o Control argument. This setting controls what PAM does after success or failure of its action for the current line (requisite in this example). We’ll get to this shortly.
o Module. The authentication module that runs for this line, determining what the line actually does. Here, the pam_shells.so module checks to see whether the user’s current shell is listed in /etc/shells.

o 函数类型。用户应用程序要求 PAM 执行的功能。在这里,它是 auth,即用户身份验证的任务。
o 控制参数。此设置控制 PAM 在当前行的操作成功或失败后要执行的操作(在此示例中为 requisite)。我们马上会讲到这个。
o 模块。在此行运行的身份验证模块,确定行的实际功能。在这里,pam_shells.so 模块会检查用户当前的 shell 是否在 /etc/shells 中列出。

PAM configuration is detailed on the pam.conf(5) manual page. Let’s look at a few of the essentials.

有关 PAM 配置的详细信息,请参阅 pam.conf(5) 手册页。

我们来看一些基本要点。

Function Types(功能类型)

A user application can ask PAM to perform one of the following four functions:

用户应用程序可以要求PAM执行以下四种功能之一:

o auth Authenticate a user (see if the user is who they say they are).
o account Check user account status (whether the user is authorized to do something, for example).
o session Perform something only for the user’s current session (such as displaying a message of the day).
o password Change a user’s password or other credentials.

o auth 验证用户身份(查看用户是否是他们声称的人)。
o account 检查用户账户状态(例如,用户是否被授权执行某些操作)。
o session 仅为用户的当前会话执行某些操作(例如,显示每日消息)。
o password 更改用户的密码或其他凭据。

For any configuration line, the module and function together determine PAM’s action. A module can have more than one function type, so when determining the purpose of a configuration line, always remember to consider the function and module as a pair. For example, the pam_unix.so module checks a password when performing the auth function, but it sets a password when performing the password function.

对于任何配置行,模块和功能一起确定PAM的操作。

一个模块可以有多个功能类型,因此在确定配置行的目的时,始终要将功能和模块视为一对。

例如,pam_unix.so模块在执行auth功能时检查密码,但在执行password功能时设置密码。

Control Arguments and Stacked Rules(控制参数和堆叠规则)

One important feature of PAM is that the rules specified by its configuration lines stack, meaning that you can apply many rules when performing a function. This is why the control argument is important: The success or failure of an action in one line can impact following lines or cause the entire function to succeed or fail.

PAM的一个重要特性是其配置行指定的规则会叠加,这意味着在执行函数时可以应用多个规则。

这就是为什么控制参数很重要:一行中的动作成功或失败会影响后续的行,甚至可能导致整个函数的成功或失败。

There are two kinds of control arguments: the simple syntax and a more advanced syntax. Here are the three major simple syntax control arguments that you’ll find in a rule:

控制参数有两种类型:简单语法和更高级的语法。下面是在规则中常见的三个主要的简单语法控制参数:

o sufficient If this rule succeeds, the authentication is successful, and PAM does not need to look at any more rules. If the rule fails, PAM proceeds to additional rules.
o requisite If this rule succeeds, PAM proceeds to additional rules. If the rule fails, the authentication is unsuccessful, and PAM does not need to look at any more rules.
o required If this rule succeeds, PAM proceeds to additional rules. If the rule fails, PAM proceeds to
additional rules but will always return an unsuccessful authentication regardless of the end result of the additional rules.

  • sufficient:如果此规则成功,认证成功,PAM不需要再查看其他规则。如果此规则失败,PAM继续执行其他规则。
  • requisite:如果此规则成功,PAM继续执行其他规则。如果此规则失败,认证失败,PAM不需要再查看其他规则。
  • required:如果此规则成功,PAM继续执行其他规则。如果此规则失败,PAM会继续执行其他规则,但无论其他规则的最终结果如何,都会返回认证失败。

Continuing with the preceding example, here is an example stack for the chsh authentication function:

继续以上面的例子为例,这是用于chsh认证函数的一个示例堆栈:

auth sufficient pam_rootok.so
auth requisite pam_shells.so
auth sufficient pam_unix.so
auth required pam_deny.so

With this configuration, when the chsh command asks PAM to perform the authentication function, PAM does the following (see Figure 7-4 for a flowchart):

使用这个配置时,当chsh命令要求PAM执行身份验证功能时,PAM会执行以下操作(请参见图7-4的流程图):

  1. The pam_rootok.so module checks to see if the root user is the one trying to authenticate. If so, it immediately succeeds and attempts no further authentication. This works because the control argument is set to sufficient, meaning that success from this action is good enough for PAM to immediately report success back to chsh. Otherwise, it proceeds to Step 2.
  2. The pam_shells.so module checks to see if the user’s shell is in /etc/shells. If the shell is not there, the module returns failure, and the requisite control argument indicates that PAM must immediately report this failure back to chsh and attempt no further authentication. Otherwise, the shell is in /etc/shells, so the module returns success and fulfills the control flag of required; proceed to Step 3.
  3. The pam_unix.so module asks the user for the user’s password and checks it. The control argument is set to sufficient, so success from this module (a correct password) is enough for PAM to report success to chsh. If the password is incorrect, PAM continues to Step 4.
  4. The pam_deny.so module always fails, and because the required control argument is present, PAM reports failure back to chsh. This is a default for when there’s nothing left to try. (Note that a required control argument does not cause PAM to fail its function immediately—it will run any lines left on its stack—but the report back to the application will always be of failure.)
  5. pam_rootok.so模块检查是否是root用户尝试进行身份验证。如果是,则立即成功并不再进行进一步的身份验证。

    • 这是因为控制参数设置为sufficient,意味着这个操作的成功足以让PAM立即向chsh报告成功。
    • 否则,继续进行第2步。
  6. pam_shells.so模块检查用户的shell是否在/etc/shells中。如果shell不在其中,该模块返回失败,并且必需的控制参数指示PAM必须立即向chsh报告此失败,并且不再进行进一步的身份验证。

    • 否则,shell在/etc/shells中,所以该模块返回成功,并满足required的控制标志;继续进行第3步。
  7. pam_unix.so模块要求用户输入密码并进行检查。控制参数设置为sufficient,因此该模块的成功(正确的密码)足以让PAM向chsh报告成功。

    • 如果密码不正确,则PAM继续进行第4步。
  8. pam_deny.so模块始终失败,并且由于存在required的控制参数,PAM向chsh报告失败。这是当没有其他尝试时的默认行为。

    • (请注意,required的控制参数不会立即导致PAM失败其功能-它将运行其堆栈上剩余的任何行-但向应用程序的报告将始终是失败。)

Figure 7-4. PAM rule execution flow

Figure 7-4. PAM rule execution flow

图7-4. PAM规则执行流程

NOTE Don’t confuse the terms function and action when working with PAM. The function is the high-level goal: what the user application wants PAM to do (authenticate a user, for example). An action is a specific step that PAM takes in order to reach that goal. Just remember that the user application invokes the function first and that PAM takes care of the particulars with actions.

注意,在使用PAM时不要混淆函数和操作这两个术语。

函数是高层目标:用户应用程序希望PAM执行的操作(例如身份验证用户)。

操作是PAM为达到该目标而采取的具体步骤。

只需记住用户应用程序首先调用函数,而PAM负责处理具体的操作细节。

The advanced control argument syntax, denoted inside square brackets ([]), allows you to manually control a reaction based on the specific return value of the module (not just success or failure). For details, see the pam.conf(5) manual page; when you understand the simple syntax, you’ll have no trouble with the advanced syntax.

高级控制参数语法,用方括号([])表示,允许您根据模块的具体返回值手动控制反应(不仅仅是成功或失败)。

有关详细信息,请参阅pam.conf(5)手册页;当您理解简单语法后,就不会遇到高级语法的困扰。

Module Arguments(模块参数)

PAM modules can take arguments after the module name. You’ll often encounter this example with the pam_unix.so module:

PAM模块可以在模块名称后面接受参数。

您经常会在pam_unix.so模块中遇到以下示例:

auth sufficient pam_unix.so nullok

The nullok argument here says that the user can have no password (the default would be fail if the user has no password).

这里的nullok参数表示用户可以没有密码(如果用户没有密码,默认情况下会失败)。

7.10.2 Notes on PAM(关于 PAM 的说明)

Due to its control flow capability and module argument syntax, the PAM configuration syntax has many features of a programming language and a certain degree of power. We’ve only scratched the surface so far, but here are a few more tips on PAM:

由于其控制流能力和模块参数语法,PAM配置语法具有许多编程语言的特性和一定的功能。

到目前为止,我们只是浅尝辄止,但以下是关于PAM的一些建议:

o To find out which PAM modules are present on your system, try man -k pam_ (note the underscore). It can be difficult to track down the location of modules. Try the locate unix_pam.so command and see where that leads you.
o The manual pages contain the functions and arguments for each module.
o Many distributions automatically generate certain PAM configuration files, so it may not be wise to change them directly in /etc/pam.d. Read the comments in your /etc/pam.d files before editing them; if they’re generated files, the comments will tell you where they came from.
o The /etc/pam.d/other configuration file defines the default configuration for any application that lacks its own configuration file. The default is often to deny everything.
o There are different ways to include additional configuration files in a PAM configuration file. The
@include syntax loads an entire configuration file, but you can also use a control argument to load only the configuration for a particular function. The usage varies among distributions.
o PAM configuration doesn’t end with module arguments. Some modules can access additional files in /etc/security, usually to configure per-user restrictions.

o 要查找系统上存在哪些PAM模块,可以尝试使用man -k pam_命令(注意下划线)。追踪模块的位置可能有些困难。尝试使用locate unix_pam.so命令并查看结果。

o 手册页包含每个模块的函数和参数信息。

o 许多发行版会自动生成某些PAM配置文件,因此直接在/etc/pam.d中更改它们可能不明智。在编辑这些文件之前,请阅读/etc/pam.d文件中的注释;如果它们是生成的文件,注释将告诉您它们的来源。

o /etc/pam.d/other配置文件定义了缺乏自己配置文件的任何应用程序的默认配置。默认情况下通常是拒绝所有操作。

o 在PAM配置文件中,有多种方法可以包含其他配置文件。@include语法可以加载整个配置文件,但您也可以使用控制参数仅加载特定功能的配置。具体用法因发行版而异。 o PAM配置不仅仅限于模块参数。一些模块可以访问/etc/security中的其他文件,通常用于配置每个用户的限制。

7.10.3 PAM and Passwords(PAM 和密码)

Due to the evolution of Linux password verification over the years, a number of password configuration artifacts remain that can cause confusion at times. The first to be aware of is the file /etc/login.defs. This is the configuration file for the original shadow password suite. It contains information about the encryption algorithm used for the shadow password file, but it’s rarely used on a modern system with PAM installed, because the PAM configuration contains this information. This said, the encryption algorithm in /etc/login.defs should match the PAM configuration in the rare case that you run into an application that doesn’t support PAM.

由于Linux密码验证多年来的演变,一些密码配置遗留物可能会导致时而混淆。

首先要了解的是文件/etc/login.defs。这是原始影子密码套件的配置文件。

它包含有关用于影子密码文件的加密算法的信息,但在安装了PAM的现代系统上很少使用,因为PAM配置包含了这些信息。

也就是说,在极少数情况下,如果遇到不支持PAM的应用程序,/etc/login.defs中的加密算法应与PAM配置相匹配。

Where does PAM get its information about the password encryption scheme? Recall that there are two ways for PAM to interact with passwords: the auth function (for verifying a password) and the password function (for setting a password). It’s easiest to track down the password-setting parameter. The best way is probably just to grep it:

PAM从哪里获取有关密码加密方案的信息呢?

请回想一下,PAM与密码交互有两种方式:auth函数(用于验证密码)和password函数(用于设置密码)。

最容易找到设置密码参数的方法可能就是使用grep命令:

$ grep password.*unix /etc/pam.d/*

The matching lines should contain pam_unix.so and look something like this:

匹配的行应包含 pam_unix.so,并看起来像这样:

password sufficient pam_unix.so obscure sha512

The arguments obscure and sha512 tell PAM what to do when setting a password. First, PAM checks to see if the password is “obscure” enough (that is, the password isn’t too similar to the old password, among other things), and then PAM uses the SHA512 algorithm to encrypt the new password.

参数"obscure"和"sha512"告诉PAM在设置密码时要做什么。

首先,PAM会检查密码是否足够"obscure"(也就是说,密码与旧密码不太相似,还有其他条件),然后PAM使用SHA512算法对新密码进行加密。

But this happens only when a user sets a password, not when PAM is verifying a password. So how does PAM know which algorithm to use when authenticating? Unfortunately, the configuration won’t tell you anything; there are no encryption arguments for pam_unix.so for the auth function. The manual pages also tell you nothing.

但是,这只在用户设置密码时发生,而不是在PAM验证密码时发生。那么PAM在进行身份验证时如何知道要使用哪个算法呢?

不幸的是,配置文件不会告诉你任何信息;对于auth函数,pam_unix.so没有加密参数。

手册页也没有提供任何信息。

It turns out that (as of this writing) pam_unix.so simply tries to guess the algorithm, usually by asking the libcrypt library to do the dirty work of trying a whole bunch of things until something works or there’s nothing left to try. Therefore, you normally don’t have to worry about the verification encryption algorithm.

事实证明,(截至本文写作时),pam_unix.so只是尝试猜测算法,通常是通过请求libcrypt库来完成尝试一系列可能的算法,直到找到有效的或者没有其他尝试的算法为止。

因此,通常你不需要担心验证加密算法。

7.11 Looking Forward(展望未来)

We’re now at about the midpoint in our progression through this book, having covered many of the vital building blocks of a Linux system. The discussion of logging and users on a Linux system has introduced you to what makes it possible to divide services and tasks into small, independent chunks that still know how to interact to a certain extent.

我们现在正处于本书的中点,已经了解了 Linux 系统的许多重要组成部分。

关于 Linux 系统中的日志和用户的讨论已经向你介绍了如何将服务和任务划分为独立的小块,并在一定程度上进行交互。

This chapter dealt almost exclusively with user space, and we now need to refine our view of user-space processes and the resources they consume. To do so, we’ll go back into the kernel in Chapter 8

本章几乎只讨论了用户空间,现在我们需要完善我们对用户空间进程及其所消耗资源的看法。

为此,我们将在第 8 章中回到内核中去。


Xander
198 声望51 粉丝