Product SiteDocumentation Site

第 9 章 Unix サービス

9.1. システム起動
9.1.1. systemd init システム
9.1.2. System V init システム
9.2. リモートログイン
9.2.1. 安全なリモートログイン、SSH
9.2.2. リモートグラフィカルデスクトップの利用
9.3. 権限の管理
9.3.1. Owners and Permissions
9.3.2. ACLs - Access Control Lists
9.4. 管理インターフェース
9.4.1. ウェブインターフェースを使った管理、webmin
9.4.2. パッケージの設定、debconf
9.5. syslog システムイベント
9.5.1. 原理とメカニズム
9.5.2. 設定ファイル
9.6. inetd スーパーサーバ
9.7. cronatd を使ったスケジューリングタスク
9.7.1. crontab ファイルの書式
9.7.2. at コマンドの利用
9.8. 非同期タスクのスケジューリング、anacron
9.9. クォータ
9.10. バックアップ
9.10.1. rsync を使ったバックアップ
9.10.2. バックアップなしのマシンの復元
9.11. ホットプラグ機能、hotplug
9.11.1. 前書き
9.11.2. 命名問題
9.11.3. udev の動作原理
9.11.4. 具体例
9.12. 電源管理、Advanced Configuration and Power Interface (ACPI)
この章では、多くの Unix システムに共通する数多くの基本的なサービスをカバーします。すべての管理者はこれらの基本的なサービスに精通しているべきです。

9.1. システム起動

コンピュータを起動する際、コンソール画面にスクロールされる多くのメッセージには、実行されている多くの自動初期化と自動設定に関する情報が表示されます。この段階の挙動を少し変えたいと思うことがあるかもしれません。これは起動処理をよく理解する必要があることを意味しています。この節の目的は起動処理をよく理解することにあります。
On systems with a BIOS, first, the BIOS takes control of the computer, initializes the controllers and hardware, detects the disks, and bridges everything together. Then it looks up the Master Boot Record (MBR) of the first disk in the boot order and loads the code stored there (first stage). This code then launches the second stage and finally executes the bootloader.
In contrast to the BIOS, UEFI is more sophisticated, it knows filesystems and can read the partition tables. The interface searches the system storage for a partition labeled with a specific globally unique identifier (GUID) that marks it as the EFI System Partition (ESP), where the bootloaders, boot managers, UEFI shell, etc., are located, and launches the desired bootloader. If Secure Boot is enabled, the boot process will verify authenticity of the EFI binaries there by signature (thus grub-efi-arch-signed is required in this case). The UEFI specification also defines support for booting in legacy BIOS mode. This is called the Compatibility Support Module (CSM). If CSM is enabled, it will attempt to boot from a drive's MBR. However, many new systems do no longer support the CSM mode.
In both cases then the actual bootloader takes over, finds either a chained bootloader or the kernel on the disk, loads, and executes it. The kernel is then initialized, and starts to search for and mount the partition containing the root filesystem, and finally executes the first program — init. Frequently, this “root partition” and this init are, in fact, located in a virtual filesystem that only exists in RAM (hence its name, “initramfs”, formerly called “initrd” for “initialization RAM disk”). This filesystem is loaded in memory by the bootloader, often from a file on a hard drive or from the network. It contains the bare minimum required by the kernel to load the “true” root filesystem: this may be driver modules for the hard drive, or other devices without which the system cannot boot, or, more frequently, initialization scripts and modules for assembling RAID arrays, opening encrypted partitions, activating LVM volumes, etc. Once the root partition is mounted, the initramfs hands over control to the real init, and the machine goes back to the standard boot process.

9.1.1. systemd init システム

「init の実体」は現在 systemd によって提供されています。この節ではこの init システムに関して説明します。
systemd を使う Linux の動くコンピュータの起動シーケンス

図 9.1 systemd を使う Linux の動くコンピュータの起動シーケンス

Systemd executes several processes, in charge of setting up the system: keyboard, drivers, filesystems, network, services. It does this while keeping a global view of the system as a whole, and the requirements of the components. Each component is described by a “unit file” (sometimes more); the general syntax is derived from the widely-used “*.ini files“ syntax, with key = value pairs grouped between [section] headers. Unit files are stored under /lib/systemd/system/ and /etc/systemd/system/; they come in several flavors, but we will focus on “services” and “targets” here.
A systemd “.service file” describes a process managed by systemd. It contains roughly the same information as old-style init-scripts, but expressed in a declaratory (and much more concise) way. Systemd handles the bulk of the repetitive tasks (starting and stopping the process, checking its status, logging, dropping privileges, and so on), and the service file only needs to fill in the specifics of the process. For instance, here is the service file for SSH:
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service
The [Unit] section contains generic information about the service, like its description and manual page resources, as well as relations (dependency and order) to other services. The [Service] part contains the declarations related to the service execution (starting, stopping, killing, restarting), directories and configuration file(s) used. The last section, [Install], again carries generic information into which targets to install the service and, in this case, the alias that can be used instead of the service name. As you can see, there is very little code in there, only declarations. Systemd takes care of displaying progress reports, keeping track of the processes, and even restarting them when needed. The syntax of these files is fully described in several manual pages (e.g. systemd.service(5), systemd.unit(5), systemd.exec(5), etc.).
A systemd “.target file” describes a state of the system where a set of services are known to be operational. It can be thought of as an equivalent of the old-style runlevel. One of the pre-defined targets is local-fs.target; when it is reached, the rest of the system can assume that all local filesystems are mounted and accessible. Other targets include network-online.target and sound.target (for a full list of special targets see systemd.special(7)). The dependencies of a target can be listed either within the target file (in the Requires= line), or using a symbolic link to a service file in the /lib/systemd/system/targetname.target.wants/ directory. For instance, /etc/systemd/system/printer.target.wants/ contains a link to /lib/systemd/system/cups.service; systemd will therefore ensure CUPS is running in order to reach printer.target.
ユニットファイルは宣言型の設定ファイルでありスクリプトやプログラムではないため、ユニットファイルを直接実行することは不可能で、ユニットファイルは systemd によってのみ解釈されます。いくつかのユーティリティを使うことで、管理者は systemd と情報をやり取りして、システムおよびシステム部品の状態を制御することが可能です。
systemd と情報をやり取りする 1 番目のユーティリティとして systemctl が挙げられます。systemctl を引数なしで実行した場合、systemd が把握しているすべてのユニットファイル (無効化されているものを除きます) およびその状態が表示されます。systemctl status を使うことで、サービスおよび関連するプロセスをよりわかりやすく表示することが可能です。サービスの名前を指定した場合 (systemctl status ntp.service のように指定した場合)、systemctl はさらに詳しい情報および指定したサービスに関連するログの最後の数行を表示します (後から詳しく説明します)。
手作業でサービスを開始するのは簡単で、systemctl start servicename.service を実行するだけです。予想通り、サービスを停止するには systemctl stop servicename.service を使います。また、他のサブコマンドには reloadrestart があります。
サービスを有効化するには (たとえば起動時に自動的にサービスを開始するには)、systemctl enable servicename.service を使います (無効化するには disable を使います)。is-enabled を使えば、サービスの状態を確認することが可能です。
An interesting feature of systemd is that it includes a logging component named journald. It comes as a complement to more traditional logging systems such as syslogd, but it adds interesting features such as a formal link between a service and the messages it generates, and the ability to capture error messages generated by its initialization sequence. The messages can be displayed later on, with a little help from the journalctl command. Without any arguments, it simply spews all log messages that occurred since system boot; it will rarely be used in such a manner. Most of the time, it will be used with a service identifier:
# journalctl -u ssh.service
-- Logs begin at 火 2015-03-31 17:08:49 JST, end at 水 2015-04-01 00:06:02 JST. --
 3月 31 17:08:55 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
 3月 31 17:08:55 mirtuel sshd[430]: Server listening on :: port 22.
 3月 31 17:09:00 mirtuel sshd[430]: Received SIGHUP; restarting.
 3月 31 17:09:00 mirtuel sshd[430]: Server listening on 0.0.0.0 port 22.
 3月 31 17:09:00 mirtuel sshd[430]: Server listening on :: port 22.
 3月 31 17:09:32 mirtuel sshd[1151]: Accepted password for roland from 192.168.1.129 port 53394 ssh2
 3月 31 17:09:32 mirtuel sshd[1151]: pam_unix(sshd:session): session opened for user roland by (uid=0)
その他の役に立つコマンドラインオプションとして -f が挙げられます。これを使った場合、journalctl は新しいメッセージを受け取ったらそのメッセージを表示し続けます (これは tail -f file とほぼ同じやり方です)。
サービスが期待通りに動いていないように見える場合、問題解決に向けて手始めに systemctl status を実行し、今現在サービスが動いているか否かを確認します。サービスが実行されておらず、systemctl status の表示したメッセージが問題の原因を解明するのに十分でない場合、journald が収集したサービスに関連するログを確認します。たとえば、SSH サービスが動いていないと仮定すると、以下の手順で状況を確認します。
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: failed (Result: start-limit) since 水 2015-04-01 00:30:36 JST; 1s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 1188 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=255)
 Main PID: 1188 (code=exited, status=255)

 4月  1 00:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
 4月  1 00:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
 4月  1 00:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# journalctl -u ssh.service
-- Logs begin at 水 2015-04-01 00:29:27 JST, end at 水 2015-04-01 00:30:36 JST. --
 4月  1 00:29:27 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
 4月  1 00:29:27 mirtuel sshd[424]: Server listening on :: port 22.
 4月  1 00:29:29 mirtuel sshd[424]: Received SIGHUP; restarting.
 4月  1 00:29:29 mirtuel sshd[424]: Server listening on 0.0.0.0 port 22.
 4月  1 00:29:29 mirtuel sshd[424]: Server listening on :: port 22.
 4月  1 00:30:10 mirtuel sshd[1147]: Accepted password for roland from 192.168.1.129 port 38742 ssh2
 4月  1 00:30:10 mirtuel sshd[1147]: pam_unix(sshd:session): session opened for user roland by (uid=0)
 4月  1 00:30:35 mirtuel sshd[1180]: /etc/ssh/sshd_config line 28: unsupported option "yess".
 4月  1 00:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:35 mirtuel sshd[1182]: /etc/ssh/sshd_config line 28: unsupported option "yess".
 4月  1 00:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:35 mirtuel sshd[1184]: /etc/ssh/sshd_config line 28: unsupported option "yess".
 4月  1 00:30:35 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:35 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:36 mirtuel sshd[1186]: /etc/ssh/sshd_config line 28: unsupported option "yess".
 4月  1 00:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:36 mirtuel sshd[1188]: /etc/ssh/sshd_config line 28: unsupported option "yess".
 4月  1 00:30:36 mirtuel systemd[1]: ssh.service: main process exited, code=exited, status=255/n/a
 4月  1 00:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
 4月  1 00:30:36 mirtuel systemd[1]: ssh.service start request repeated too quickly, refusing to start.
 4月  1 00:30:36 mirtuel systemd[1]: Failed to start OpenBSD Secure Shell server.
 4月  1 00:30:36 mirtuel systemd[1]: Unit ssh.service entered failed state.
# vi /etc/ssh/sshd_config
# systemctl start ssh.service
# systemctl status ssh.service
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: active (running) since 水 2015-04-01 00:31:09 JST; 2s ago
  Process: 1023 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 1222 (sshd)
   CGroup: /system.slice/ssh.service
           └─1222 /usr/sbin/sshd -D
# 
ここでは SSH サービスの状態が失敗状態であることを確認した後、ログの確認作業に進みました。その結果、ログは設定ファイル内にエラーがあることを示しています。そこで設定ファイルを編集してエラーを修正した後、SSH サービスを再起動し、SSH サービスが本当に動いていることを確認しました。

9.1.2. System V init システム

The System V init system (which we'll call init for brevity) executes several processes, following instructions from the /etc/inittab file. The first program that is executed (which corresponds to the sysinit step) is /etc/init.d/rcS, a script that executes all of the programs in the /etc/rcS.d/ directory.
/etc/rcS.d/ ディレクトリに含まれるスクリプトは特に以下の点を担当します。
  • コンソールキーボードの設定。
  • ドライバの読み込み。ほとんどのカーネルモジュールはハードウェアを検出した時にカーネル自身によって読み込まれます。追加のドライバはそれに対応するモジュールが /etc/modules にリストされている場合に読み込まれます。
  • ファイルシステムの整合性確認。
  • ローカルパーティションのマウント。
  • ネットワークの設定。
  • ネットワークファイルシステム (NFS) のマウント。
/etc/init.d/rcS の完了後、init が起動処理を引き継いで、デフォルトランレベル (通常ランレベル 2) で有効化されたプログラムを起動します。init/etc/init.d/rc 2 を実行します。これは /etc/rc2.d/ に置かれて「S」で始まる名前のすべてのサービスを開始するコマンドです。歴史的なことを言えば、「S」の後に続く 2 桁の数字は起動するサービスの順番を定義するために使われていました。しかし現在では、デフォルトの起動システムは insserv を使ってスクリプト同士の依存関係に従った起動順を自動的に決定します。このため、各起動スクリプトはサービスを起動または終了させる時に満足しなければいけない条件を宣言します (たとえば、あるサービスは他のサービスの前または後に起動しなければいけないなどの条件を宣言します)。そして、init は条件を満足するようにサービスを起動します。このため、スクリプトの静的な番号付けはもはや考慮されません (しかしスクリプトの名前は必ず「S」で始まり、その後ろに 2 桁の番号と条件を宣言する際に使われる実際のスクリプトの名前を付けなければいけません)。一般に、基盤サービス (ログ記録を担当している rsyslog やポート割り当てを担当している portmap) が最初に起動され、その後に標準的なサービスとグラフィカルインターフェース (gdm3) が起動されます。
この依存関係に基づく起動システムのおかげで、起動順を自動的に再定義することが可能になります。これは手作業でやるにはちょっと退屈な作業で、人的ミスの危険性があります。なぜなら、起動順は宣言された依存関係に従って定義されるからです。他の長所として、他のサービスに依存しないサービスは並列して開始できるという点があります。このことにより、起動処理を加速できます。
init はランレベルを見分けて処理を分岐させます。ランレベルを切り替えるには telinit new-level コマンドを使います。このコマンドを実行すると init は即座に新しいランレベルを引数にして /etc/init.d/rc を再実行します。/etc/init.d/rc は欠けているサービスを開始し、既に不要となったサービスを停止します。これを行うために、/etc/init.d/rc/etc/rcX.d ディレクトリの内容を参照します (ここで X は新しいランレベルです)。このディレクトリに含まれる (「Start」の)「S」で始まるスクリプトは開始されるサービスで、(「Kill」の)「K」で始まるスクリプトは停止されるサービスです。/etc/init.d/rc は切り替え前のランレベルで既に起動されているサービスは開始しません。
デフォルトで、Debian の System V init は 4 種類のランレベルを使います。
  • レベル 0。これはコンピュータの電源を切る際に一時的に使われるだけです。このため「K」スクリプトしか含まれません。
  • レベル 1。これはシングルユーザモードとしても知られ、システムの機能抑制モードに相当します。このモードは基本的なサービスだけを提供し、一般ユーザがマシンを利用していないメンテナンスの際に使われることを意図しています。
  • レベル 2。これは通常動作用のモードで、ネットワークサービス、グラフィカルインターフェース、ユーザログインなどの機能を使うことが可能です。
  • レベル 6。これはレベル 0 と似ていますが、再起動前のシャットダウン段階中に使われる点が異なります。
その他のレベル。レベル 3 からレベル 5 までも存在します。デフォルトでこれらのランレベルはレベル 2 と同様に動作しますが、管理者はこれらのレベルを特定の要求に順応させるためのレベルに書き換えることが可能です (ランレベルに対応する /etc/rcX.d ディレクトリにスクリプトを追加したりおよび削除したりする必要があります)。
System V init を使う Linux の動くコンピュータの起動シーケンス

図 9.2 System V init を使う Linux の動くコンピュータの起動シーケンス

All the scripts contained in the various /etc/rcX.d directories are really only symbolic links — created upon package installation by the update-rc.d program — pointing to the actual scripts which are stored in /etc/init.d/. The administrator can fine tune the services available in each runlevel by re-running update-rc.d with adjusted parameters. The update-rc.d(1) manual page describes the syntax in detail. Please note that removing all symbolic links (with the remove parameter) is not a good method to disable a service. Instead you should simply configure it to not start in the desired runlevel (while preserving the corresponding calls to stop it in the event that the service runs in the previous runlevel). Since update-rc.d has a somewhat convoluted interface, you may prefer using rcconf (from the rcconf package) which provides a more user-friendly interface.
最後に、init はさまざまな仮想コンソール用の制御プログラム (getty) を開始します。getty はプロンプトを表示し、ユーザ名の入力を待ち、セッションを開始するために login user を実行します。