Solaris のシステム管理 (上級編)

第 19 章 システムアカウンティングの設定と管理 (手順)

この章では、システムアカウンティングを設定して維持する方法について説明します。

この章で説明する手順は次のとおりです。

この章の内容は以下のとおりです。

拡張アカウンティング機能の使い方については、『Solaris のシステム管理 (資源管理とネットワークサービス)』の「拡張アカウンティング」を参照してください。

システムアカウントのさまざまなレポートについては、第 20 章「システムアカウンティング (リファレンス)」を参照してください。

システムアカウンティング

SunOS 5.9 のシステムアカウンティングソフトウェアは、ユーザー接続時間、プロセスに使用された CPU 時間、およびディスク使用量についてのデータを収集および記録できるプログラム群です。一度このデータを収集すると、レポートを生成したり、システム使用に対して課金したりすることができます。

アカウンティングプログラムを使用すると、次の事項を行うことができます。

システムアカウンティングプログラムは、設定が済むと、ほとんどの場合自動的に実行されます。

システムアカウンティングの動作

自動アカウンティングは、まずアカウンティング起動スクリプトをルートの crontab ファイルに配置することによって設定します。すると、アカウンティング起動スクリプトが、cron コマンドによって自動的に起動されます。

次の概要は、システムアカウンティングのプロセスを示したものです。

  1. システムを起動してからシャットダウンするまでの間に、システムの利用に関する (ユーザーログイン、実行されたプロセス、データの格納などの) raw データがアカウンティングファイルに収集されます。

  2. 定期的に (通常 1 日に 1 回)、/usr/lib/acct/runacct スクリプトが各種のアカウンティングファイルを処理して、累積要約ファイルと日次アカウンティングレポートを生成します。次に、 /usr/lib/acct/prdaily スクリプトが日次レポートを印刷します。

    runacct スクリプトについては、runacct スクリプトを参照してください。

  3. 毎月、monacct スクリプトを実行することによって、 runacct 累積要約ファイルを処理して印刷します。monacct スクリプトによって生成される要約レポートは、月次またはその他の会計期間ベースのユーザーに対する効率的な課金手段になります。

システムアカウンティングのコンポーネント

アカウンティングユーティリティは、データから要約ファイルとレポートを生成する C 言語プログラムとシェルスクリプトを提供します。これらのプログラムは /usr/lib/acct ディレクトリにあります。アカウンティングレポートは、/var/adm/acct ディレクトリにあります。

日次アカウンティングによって、次の 4 種類の監査を行うことができます。

接続アカウンティング

接続アカウンティングでは、次のデータを調べることができます。

この情報を提供するために、システムは次のデータを格納します。

これらのレコード (dateinitloginttymonacctwtmp などのシステムプログラムの出力によって生成されます) は /var/adm/wtmpx ファイルに格納されます。wtmpx ファイルのエントリには、次の情報を入れることができます。

プロセスアカウンティング

プロセスアカウンティングでは、システムで実行される各プロセスに関する次のようなデータを追跡できます。

プロセスが終了するたびに、exit プログラムは上記のデータを収集し、/var/adm/pacct ファイルに書き込みます。

ディスクアカウンティング

ディスクアカウンティングでは、各ユーザーがディスク上にもっているファイルについて次のデータを収集し、それらを整形できます。

これらのデータはシェルスクリプト /usr/lib/acct/dodisk によって収集されますが、収集周期は /var/spool/cron/crontabs/root ファイルに追加する cron コマンドによって決定されます。一方、dodisk スクリプトは、acctdisk および acctdusg コマンドを起動して、ログインによるディスク使用量を収集させます。


注意 – 注意 –

dodisk スクリプトを実行して収集された情報は、/var/adm/acct/nite/disktacct ファイルに格納されます。これらの情報は、次に dodisk スクリプトを実行したときに上書きされます。したがって、dodisk スクリプトは同じ日に 2 回以上実行しないでください。


acctdusg コマンドは、ランダムに書き込まれたため穴があいたファイルに対して過剰に課金します。このような問題が起こるのは、acctdusg コマンドが、ファイルサイズを決めるときに、ファイルの間接ブロックを読み取らないからです。acctdusg コマンドは、i ノードの di_size の値をチェックして、ファイルのサイズを決めます。

ユーザー料金の計算

chargefee ユーティリティは、ユーザーに提供した特別なサービス (ファイルの復元など) に対する課金を、/var/adm/fee ファイルに格納します。このファイルの各エントリは、ユーザーのログイン名、ユーザー ID、および料金から構成されています。このファイルは、runacct スクリプトによって毎日チェックされて、新しいエントリが全体のアカウンティングレコードにマージされます。chargefee スクリプトを実行してユーザーに課金する命令については、ユーザーに課金する方法を参照してください。

日次アカウンティング機能の動作

次に、SunOS の日次アカウンティング機能がどのように動作するかを要約して示します。

  1. システムをマルチユーザーモードに切り替えると、/usr/lib/acct/startup プログラムが実行されます。この startup プログラムは、それぞれ日次アカウンティング機能を呼び出す他のプログラムを実行します。

  2. acctwtmp プログラムは /var/adm/wtmpx ファイルに「ブート」レコードを追加します。このレコードには、システム名が wtmpx レコード内のユーザー名として示されます。次の表に、raw アカウンティングデータがどのように収集され、どこに格納されるかをまとめて示します。

    表 19–1 raw アカウンティングデータ

    /var/adm 内のファイル

    格納される情報 

    データを書き込むプログラム 

    表記形式 

    wtmpx

    接続セッション数  

    login, init

    バイナリ 

     

    日付変更

    date

     

     

    リブート

    acctwtmp

     

     

    シャットダウン

    shutacct

     

    pacctn

    プロセス 

    カーネル (プロセス終了時) 

    バイナリ 

     

     

    turnacct switch (古いファイルの内容が 500 ブロックに達すると、新しいファイルが作成される)

     

    fee

    特別料金 

    chargefee

    ASCII 

    acct/nite/disktacct

    使用ディスク領域 

    dodisk

    バイナリ 

  3. turnacct スクリプトが -on オプションで起動されて、プロセスアカウンティングを開始します。turnacct スクリプトは、特に /var/adm/pacct 引数を使用して accton プログラムを実行します。

  4. remove シェルスクリプトが、runacct によって sum ディレクトリに保存されている pacct および wtmpx ファイルを「整理」します。

  5. login および init プログラムが、/var/adm/wtmpx ファイルにレコードを書き込み、接続セッションを記録します。すべての日付変更 (引数を指定して date を使用) も /var/adm/wtmpx ファイルに書き込まれます。リブート回数とシャットダウン回数も、acctwtmp コマンドを使用して、 /var/adm/wtmpx ファイルに記録されます。

  6. プロセスが終了すると、カーネルが /var/adm/pacct ファイルにプロセスごとに 1 レコードを acct.h 形式で書き込みます。

    cron コマンドは、1 時間ごとに ckpacct スクリプトを実行して、/var/adm/pacct ファイルのサイズをチェックします。このファイルが 500 ブロック (デフォルト) よりも大きくなった場合は、turnacct switch コマンドが実行されます。(このプログラムは pacct ファイルを pacctn ファイルに移動して、新しいファイルを作成します。) pacct ファイルを小さく分けることの利点は、それらのレコードを処理するときに障害が発生して、 runacct スクリプトを再起動しようとしたときに明らかになります。

  7. runacct スクリプトは、 cron コマンドによって毎晩実行されます。 runacct スクリプトは、/var/adm/pacctn/var/adm/wtmpx/var/adm/fee および /var/adm/acct/nite/disktacct のアカウンティングファイルを処理し、ユーザー別のコマンド要約と利用状況要約を生成します。

  8. /usr/lib/acct/prdaily スクリプトは、runacct スクリプトによって 1 日 1 回実行され、/var/adm/acct/sum/rprt MMDD ファイルに日次アカウンティング情報を書き込みます。

  9. monacct スクリプトが月に 1 回 (または毎会計期の終わりなど、ユーザーが決めた周期で) 実行されます。monacct スクリプトは、sum ディレクトリに格納されているデータに基づいてレポートを作成します。これらのデータは runacct スクリプトによって毎日更新されています。このレポートを作成後、monacct スクリプトは sum ディレクトリを「整理」して、新しい runacct データを格納するためのファイルを準備します。

システムがシャットダウンしたときの動作

shutdown コマンドを使用してシステムをシャットダウンした場合は、shutacct スクリプトが自動的に実行されます。shutacct スクリプトは /var/adm/wtmpx ファイルに理由レコードを書き、アカウンティングプロセスを無効に設定します。

システムアカウンティングの設定

システムアカウンティングは、システムがマルチユーザーモード (システム状態 2) のときに実行されるように設定できます。システムアカウンティングには、次の内容が含まれます。

  1. /etc/rc0.d/K22acct および /etc/rc2.d/S22acct 起動スクリプトの作成

  2. crontab ファイル /var/spool/cron/crontabs/adm および /var/spool/cron/crontabs/root の変更

表 19–2 に、デフォルトのアカウンティング管理スクリプトを説明します。

表 19–2 デフォルトのアカウンティング管理スクリプト

アカウンティングスクリプト 

マニュアルページ 

種類 

実行頻度 

ckpacct

ckpacct(1M)

/usr/adm/pacct ログファイルのサイズをチェックし、ファイルが大きくなりすぎていないことを確認する

定期的 

runacct

runacct(1M)

接続、ディスク、および料金のアカウンティング情報を処理する。 このスクリプトから、処理したくないアカウンティング機能のコマンドを削除できる 

日次 

monacct

monacct(1M)

会計アカウンティング要約レポートを月に 1 回のベースで生成する。このスクリプトの実行頻度を決めることができる。このスクリプトから、生成したくないアカウンティング機能のコマンドを削除できる 

会計期間に基づく 

デフォルトでどのアカウンティングスクリプトを実行するのかを選択できます。これらのエントリを crontab ファイルに追加すると、アカウンティングは自動的に実行されるようになります。

システムアカウンティングを設定する方法

  1. スーパーユーザーになります。

  2. 必要な場合は、pkgadd コマンドを使用して、システムに SUNWaccrSUNWaccu パッケージをインストールします。

  3. 次のように入力して、/etc/init.d/acct を実行レベル 2 の起動スクリプトとしてインストールします。


    # ln /etc/init.d/acct /etc/rc2.d/S22acct
    
  4. /etc/init.d/acct を実行レベル 0 の停止スクリプトとしてインストールします。


    # ln /etc/init.d/acct /etc/rc2.d/S22acct
    
  5. ckpacctrunacct、および monacct スクリプトが自動的に起動するように、adm ユーザーの crontab ファイルに次の行を追加します。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    0 * * * * /usr/lib/acct/ckpacct
    30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
    30 7 1 * * /usr/lib/acct/monacct
  6. dodisk スクリプトが自動的に起動するように、rootcrontab ファイルに次の行を追加します。


    # crontab -e
    30 22 * * 4 /usr/lib/acct/dodisk
  7. /etc/acct/holidays を編集して祭日と休日を含めます。

    詳細は、holidays(4) のマニュアルページおよび次の例を参照してください。

  8. システムをリブートするか、手入力でアカウンティングを起動します。


    # /etc/init.d/acct start
    

例 — アカウンティングを設定する

この編集された admcrontab には、 ckpacctrunacct および monacct スクリプトが含まれています。


#ident  "@(#)adm        1.5     92/07/14 SMI"    /* SVr4.0 1.2   */
#
# The adm crontab file should contain startup of performance 
# collection if the profiling and performance feature has been 
# installed.
0 * * * * /usr/lib/acct/ckpacct
30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
30 7 1 * * /usr/lib/acct/monacct

この編集された rootcrontab には、 dodisk プログラムのエントリが含まれています。


#ident  "@(#)root       1.19    98/07/06 SMI"   /* SVr4.0 1.1.3.1       */
#
# The root crontab should be used to perform accounting data collection.
#
# The rtc command is run to adjust the real time clock if and when
# daylight savings time changes.
#
10 3 * * * /usr/sbin/logadm
15 3 * * 0 /usr/lib/fs/nfs/nfsfind
1 2 * * * [ -x /usr/sbin/rtc ] && /usr/sbin/rtc -c> /dev/null 2>&1
30 3 * * * [ -x /usr/lib/gss/gsscred_clean ] && /usr/lib/gss/gsscred_clean
30 22 * * 4 /usr/lib/acct/dodisk

次に /etc/acct/holidays ファイルの例を示します。


* @(#)holidays	January 1, 2001
*
* Prime/Nonprime Table for UNIX Accounting System
*
* Curr	Prime	Non-Prime
* Year	Start	Start
*
  1999	0800	1800
*
* only the first column (month/day) is significant.
*
* month/day	Company
* 		Holiday
*
1/1		New Years Day
7/4		Indep. Day
12/25		Christmas

ユーザーへの課金

ファイルの復元やリモート印刷など、ユーザーに特別なサービスを提供する場合は、 chargefee ユーティリティを実行して、ユーザーに課金したいこともあります。chargefee ユーティリティは、 /var/adm/fee ファイルに料金を記録します。次に、runacct ユーティリティが実行されるたびに、新しいエントリが拾い出されて、全体のアカウンティングレコードにマージされます。

詳細は、acctsh(1M) のマニュアルページを参照してください。

ユーザーに課金する方法

  1. スーパーユーザーになります。

  2. ユーザーに提供されたサービスに対して課金します。


    # /usr/lib/acct/chargefee username amount
    

    username

    課金したいユーザーアカウント 

    amount

    ユーザーに対する課金の単位数。これは、ファイルの印刷や復元のような作業に基づいて、ユーザーに課金するために設定する任意の単位。 chargefee を実行し、特定の作業に対してユーザーに課金するスクリプトを書く必要があるでしょう。

例 — ユーザーに課金する

次の例は、ユーザーがアカウント print_customer にログインするたびに 10 単位を課金します。


# /usr/lib/acct/chargefee print_customer 10

アカウンティング情報の管理

この節では、壊れたアカウンティングファイルを修復し、runacct スクリプトを再起動する方法を説明します。

壊れたファイルと wtmpx エラーを修復する

アカウンティングシステムは絶対に障害を発生しないというものではありません。ファイルが壊れたり、失われることがあります。ファイルによっては、単に無視してよいものや、バックアップから復元できるものがあります。ただし、特定のファイルは、アカウンティングシステムの完全性を維持するために修復しなければなりません。

wtmpx ファイルは、アカウンティングシステムを日常的に運用する上で発生する問題の大部分の原因になっています。日付を手動で変更した時に、システムがマルチユーザーモードの場合は、日付変更レコードが/var/adm/wtmpx ファイルに書き込まれます。wtmpfix ユーティリティは、日付変更が行われたときに、wtmp レコードのタイムスタンプを調整するように設計されています。ただし、日付変更とリブートの組み合わせによっては、wtmpfix の処理から漏れて、acctcon プログラムの処理が失敗することがあります。

壊れた wtmpx ファイルの修復方法

  1. スーパーユーザーになります。

  2. /var/adm ディレクトリに移動します。

  3. wtmpx ファイルの形式をバイナリから ASCII に変換します。


    # /usr/lib/acct/fwtmp < wtmpx > wtmpx.ascii 
    
  4. wtmpx.ascii を編集して、壊れたレコードを削除します。

  5. wtmpx.ascii ファイルを再びバイナリファイルに変換します。


    # /usr/lib/acct/fwtmp -ic < wtmpx.ascii> wtmpx
    

    詳細は、fwtmp(1M) のマニュアルページを参照してください。

tacct エラーを修復する

/var/adm/acct/sum/tacct ファイルの完全性は、システム資源に対してユーザーに課金している場合は重要です。不正な tacct レコードが、負の数値、重複ユーザー ID、65535 のユーザー ID で表示されることがあります。このような場合はまず、prtacct スクリプトを使用して/var/adm/acct/sum/tacctprev ファイルを印刷してチェックします。内容が正しい場合は、最新の /var/adm/acct/sum/tacctMMDD ファイルを使用して、/var/adm/acct/sum/tacct ファイルを作成し直してください。次の手順は、簡単な修復手順の概要を説明しています。

tacct エラーを修復する方法

  1. スーパーユーザーになります。

  2. ディレクトリ /var/adm/acct/sum に移動します。

  3. tacctMMDD ファイルの形式をバイナリから ASCII に変換します。


    # /usr/lib/acct/acctmerg -v < tacctMMDD > xtacct
    

    MMDD は、月と日をあらわす 2 桁の数値を組み合わせたものです。

  4. xtacct ファイルを編集して、壊れたレコードを削除し、重複レコードを別のファイルに書き込みます。

  5. xtacct ファイルを ASCII 形式からバイナリに変換します。


    # /usr/lib/acct/acctmerg -i < xtacct > tacctMMDD
    

    MMDD は、月と日をあらわす 2 桁の数値を組み合わせたものです。

  6. ファイル tacctprevtacctMMDD をマージしてファイル tacct を生成します。


    # /usr/lib/acct/acctmerg < tacctprev tacctMMDD > tacct
    

runacct スクリプトを再起動する

runacct スクリプトは、さまざまな理由で失敗することがあります。最も一般的な理由には、システムクラッシュ、/var ディレクトリの容量不足での実行、wtmpx ファイルが壊れたなどがあります。activeMMDD ファイルが存在する場合は、まずエラーメッセージをチェックします。active ファイルおよび lock ファイルが存在する場合は、異常なメッセージがないかどうか fd2log ファイルを調べます。

runacct スクリプトは、引数を指定しないで実行すると、その実行がその日の最初の実行であるとみなします。runacct スクリプトを再起動し、runacct スクリプトがアカウントを返す月と日を指定する場合は、引数 MMDD が必要になります。処理のエントリポイントは statefile ファイルの内容に基づきます。statefile ファイルを無効にするには、処理を開始したい状態をコマンド行に指定します。利用可能な状態の説明については、runacct(1M) のマニュアルページを参照してください。


注意 – 注意 –

runacct プログラムを手動で実行するときは、ユーザー adm として実行していることを確認してください。


runacct スクリプトを再起動する方法

  1. lastdate ファイルと lock* ファイル (もしあれば) を削除します。


    $ cd /var/adm/acct/nite
    $ rm lastdate lock*
    

    lastdate ファイルには、 runacct プログラムが最後に実行された日付が含まれています。次の手順で runacct を再起動することによって、このファイルが再び作成されます。

  2. runacct スクリプトを再起動します。


    $ /usr/lib/acct/runacct MMDD [state] 2> /var/adm/acct/nite/fd2log &
    

    MMDD

    月日を 2 桁の数値で指定する 

    state

    runacct 処理を開始させたい状態または開始点を指定する。

システムアカウンティングの停止と無効

システムアカウンティングは、一時的に停止することも、永続的に無効にすることもできます。

一時的にシステムアカウンティングを停止する方法

  1. スーパーユーザーになります。

  2. 適切な行をコメントアウトすることによって、プログラム ckpacctrunacct、および monacct の実行が停止するように、ユーザー admcrontab ファイルを編集します。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    #0 * * * * /usr/lib/acct/ckpacct
    #30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
    #30 7 1 * * /usr/lib/acct/monacct
  3. 適切な行をコメントアウトすることによって、プログラム dodisk の実行が停止するように、ユーザー rootcrontab ファイルを編集します。


    # crontab -e 
    #30 22 * * 4 /usr/lib/acct/dodisk
  4. 次のように入力して、アカウンティングプログラムを停止します。


    # /etc/init.d/acct stop
    
  5. (省略可能)新規に追加したコメント記号を crontab ファイルから削除し、アカウンティングプログラムを再起動して、システムアカウンティングを再び利用できるようにします。


    # /etc/init.d/acct start
    

システムアカウンティングを永続的に無効にする方法

  1. スーパーユーザーになります。

  2. ユーザー admcrontab ファイルを編集して、プログラム ckpacctrunacct、および monacct 用のエントリを削除します。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    
  3. ユーザー rootcrontab ファイルを編集して、プログラム dodisk 用のエントリを削除します。


    # crontab -e
    
  4. 実行レベル 2 用の起動スクリプトのリンクを取り外します。


    # unlink /etc/rc2.d/S22acct
    
  5. 実行レベル 0 用の停止スクリプトのリンクを取り外します。


    # unlink /etc/rc0.d/K22acct
    
  6. 次のように入力して、アカウンティングプログラムを停止します。


    # /etc/init.d/acct stop