セキュリティ管理業務とは

Linuxサーバーの運用では、「誰が」「いつ」「どの権限で」システムを操作したかを把握し、必要な操作以外はできないように制限しておくことが基本的なセキュリティ対策になります。LPIC-1・LinuCレベル1の「セキュリティ管理業務」という主題は、この考え方を次の4つの観点に整理したものです。

  • 権限昇格の管理:一般ユーザーが管理者権限(root権限)で操作する必要がある場面で、どのように安全に権限を昇格させるか(su、sudo、/etc/sudoers)。
  • ログイン状況の把握:誰が現在ログインしているか、過去に誰がいつログインしたかを確認する方法(who、w、last)。
  • リソース制限:1ユーザーが利用できるプロセス数やメモリ量などに上限を設け、意図しない・悪意のあるリソース枯渇を防ぐ方法(ulimit)。
  • 自動ログアウト:ログインしたまま離席した端末が放置されるリスクを減らすための、一定時間操作が無い場合の自動ログアウト設定(TMOUT)。

これらはいずれも、ユーザーの権限・ログイン状態・利用可能な資源をどのように管理・監視するかという共通のテーマでつながっています。

権限昇格の管理:suとsudo

画像

su:別のユーザーとしてログインし直す

su(substitute user、switch userの略とされることもあります)は、現在ログイン中のシェルから、別のユーザーとしてログインし直すコマンドです。

  • su ユーザー名:指定したユーザーに切り替えます。ユーザー名を省略するとrootへの切り替えとみなされます。
  • su - ユーザー名(またはsu -l ユーザー名):ユーザーを切り替えるだけでなく、切り替え先ユーザーのログインシェルとして環境を初期化します。環境変数(PATHなど)やカレントディレクトリ(ホームディレクトリに移動)が、そのユーザーが直接ログインした場合と同じ状態になります。ハイフン無しのsu ユーザー名では、切り替え元のシェルの環境変数の多くがそのまま引き継がれるため、想定と異なるPATHが残ってしまうなどの問題が起こり得ます。
  • su -c 'コマンド' ユーザー名:シェルに入らず、指定したコマンドだけを切り替え先ユーザーの権限で1回実行します。

suで重要な特徴は、認証に使うパスワードが「切り替え先ユーザーのパスワード」であるという点です。一般ユーザーがsuでrootに切り替えるには、rootのパスワードを知っている必要があります。これは、後述するsudoとの最も大きな違いです。

多くのディストリビューションでは、PAM(pam_wheelモジュールなど)を使って「wheelグループに所属するユーザーだけがsuでrootになれる」ように制限する設定が可能ですこの制限は多くのディストリビューションで標準的に用意されている設定例ですが、既定で有効になっているとは限らず、ディストリビューションや設定次第です。「wheelグループのメンバーでなければsuが一切使えない」と断定せず、あくまで「そのように制限する設定が一般的に用意されている」と理解してください。[1]。

sudo:許可されたコマンドを指定された権限で実行する

sudo(superuser do)は、一般ユーザーが自分自身のアカウントとして認可・認証を受け、/etc/sudoersで許可された特定のコマンドを一時的に管理者権限(または指定した別ユーザーの権限)で実行するためのコマンドです。

sudoで重要な特徴は、通常、認証に使うパスワードが「実行者自身のパスワード」であるという点です。rootのパスワードを一切知らないユーザーでも、/etc/sudoersで許可されていればsudo経由で管理者権限の操作ができます。これにより、「rootパスワードを複数人で共有する」必要がなくなり、誰がいつどのコマンドを実行したかを個人単位でログに残せる(多くの環境で/var/log/auth.logや/var/log/secureなどに記録されます)という利点があります。sudoersのrootpw、runaspw、targetpwなどの設定により、認証に求めるパスワードを変更することもできます。[2]

コマンド・オプション説明
sudo指定したコマンドを管理者権限で実行
sudo -u ユーザー名 コマンドroot以外の、指定した別ユーザーの権限でコマンドを実行
sudo -l現在のユーザーがsudoで実行を許可されているコマンドの一覧を確認
sudo -irootのログインシェルとして対話的なシェルを開始(su -に近い動作)

sudoは、一度パスワード認証に成功すると、標準的な既定値では15分間、再認証を求めずにsudoコマンドを実行できる仕組み(タイムスタンプによるキャッシュ)を持っていますこの既定の時間はディストリビューションやバージョン、/etc/sudoers側のtimestamp_timeout設定によって変わり得るため、「常に15分」と断定はできません。[3]。

/etc/sudoers:sudoの許可設定ファイル

/etc/sudoersは、「どのユーザー(またはグループ)が」「どのホスト上で」「誰の権限として」「どのコマンドを」実行してよいかを定義する設定ファイルです。基本的な書式は次のとおりです。

ユーザー ホスト = (実行対象ユーザー) コマンド

例えば次の行は、ユーザーaliceがどのホスト(ALL)上でも、root権限で/usr/bin/systemctl restart nginxだけを実行できることを表します。

alice ALL=(root) /usr/bin/systemctl restart nginx
  • グループ指定:ユーザー名の代わりに、先頭に%を付けてグループ名を指定できます(例:%wheel ALL=(ALL) ALLは、wheelグループの全メンバーに、あらゆるホスト上であらゆるユーザー権限としてあらゆるコマンドの実行を許可します)。
  • NOPASSWDタグ:コマンドの前にNOPASSWD:を付けると、そのコマンドに限りパスワード再入力を求めずに実行できます(例:alice ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx)。認証を省略する設定であるため、対象コマンドは慎重に絞り込む必要があります。
  • エイリアス機能:User_Alias(ユーザーのグループ化)、Host_Alias(ホストのグループ化)、Cmnd_Alias(コマンドのグループ化)、Runas_Alias(実行対象ユーザーのグループ化)を使うと、複数のユーザー・コマンドをまとめて管理できます。
  User_Alias ADMINS = alice, bob
  Cmnd_Alias SERVICE_CMDS = /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php-fpm
  ADMINS ALL=(root) SERVICE_CMDS
  
  • @includedir:@includedir /etc/sudoers.dという行により、/etc/sudoers.dディレクトリ内の各設定ファイルを読み込めます。ユーザーやアプリケーションごとに設定を分割して管理したい場合に使われます。

/etc/sudoersはvisudoコマンドで編集することが推奨されます。 viやnanoなどのエディタで直接編集することもファイル権限上は可能ですが、visudoには次のような役割があります。

  • 編集中、他のプロセスが同時に/etc/sudoersを変更しないようロックを掛けます。
  • 保存時に文法チェックを行い、文法エラーがある場合は再編集するか、保存せずに終了するかなどを選択できます。

/etc/sudoersの設定ミスにより必要な許可設定が利用できなくなると、sudo経由での復旧もできなくなる可能性があります。visudoによる事前の文法チェックは、こうした事態を防ぐための重要な仕組みです。

ユーザーのログイン状況・履歴の把握

画像

who:現在ログインしているユーザーの一覧

whoは、現在システムにログインしているユーザーの一覧を表示するコマンドです。ユーザー名、使用している端末(tty)、ログイン日時などが表示されます。who am i(またはwho -m)とすると、実行者自身のログイン情報だけに絞り込めます。

w:現在ログインしているユーザーとその作業内容

wは、whoと同様に現在ログインしているユーザーの一覧を表示しますが、加えて各ユーザーの端末に関連付けられた現在のプロセス(WHAT欄)、システム全体の負荷(ロードアベレージ)、各ユーザーの無操作時間(idle time)なども表示します。「whoをより詳しくしたコマンド」と捉えると理解しやすいですが、whoの単純な上位互換ではなく、表示項目の目的(誰がログインしているかの一覧か、何をしているかも含めた稼働状況の把握か)が異なる別のコマンドです。

last:過去のログイン履歴

lastは、過去のログイン・ログアウトの履歴を新しい順に表示するコマンドです。who・wが「現在」の状態を示すのに対し、lastは「過去」の記録を確認するためのコマンドという違いがあります。last ユーザー名のようにユーザー名を指定すると、そのユーザーに絞り込んで表示できます。

これらのコマンドが参照するファイル

who・wは、現在ログイン中のセッション情報が記録された/var/run/utmp(ディストリビューションによっては/var/run/utmpではなく/run/utmpへの配置になっている場合もあります)を参照します。一方、lastは、ログイン・ログアウトの履歴が蓄積される/var/log/wtmpを参照します/var/log/wtmpはバイナリ形式のログファイルであるため、catなどのテキスト表示コマンドでそのまま閲覧することはできません。lastコマンド経由で参照します。[4]。

関連コマンドとして、ログイン失敗の履歴を表示するlastb(/var/log/btmpを参照)、各ユーザーの最終ログイン日時を表示するlastlog(/var/log/lastlogを参照)があります。「ログインの成功・失敗のどちらを記録したファイルか」「現在の状態か、過去の履歴(ログ)か」という2つの軸で整理しておくと、who/w/last/lastb/lastlogの役割を混同しにくくなります。

リソース制限:ulimit

画像

ulimitは、現在のシェル(およびそこから起動される子プロセス)が使用できるリソースの上限を確認・設定するシェルの組み込みコマンドです。オープンできるファイル数、生成できるプロセス数、使用できるメモリ量など、さまざまなリソースに上限を設けることで、1ユーザー・1プロセスの暴走がシステム全体に影響を及ぼすことを防ぎます。

  • ulimit -a:現在設定されている全リソースの上限を一覧表示します。
  • ulimit -n:オープンできるファイルディスクリプタ数の上限を確認・設定します。
  • ulimit -u:1ユーザーが生成できるプロセス数の上限を確認・設定します。
  • ulimit -f:作成できるファイルサイズの上限を確認・設定します。

ソフトリミットとハードリミット

リソースの上限には、ソフトリミットとハードリミットの2種類があります。

  • ソフトリミット(ulimit -S):実際に適用されている上限です。一般ユーザーは、ハードリミットの範囲内であれば、自分でソフトリミットを引き上げることができます。
  • ハードリミット(ulimit -H):ソフトリミットが超えられない上限です。一般ユーザーはハードリミットを引き上げることはできず、引き下げることしかできません。ハードリミットを引き上げられるのは管理者(root)権限を持つ場合のみです。

オプションを付けずにulimitだけを実行した場合は、ファイルサイズ(-f)のソフトリミットが対象になります。bashでは、特定の項目を単独で確認する場合もソフトリミットが表示されます。設定時に-Hと-Sのいずれも指定しない場合は、ソフトリミットとハードリミットの両方が設定対象になります。

永続化にはlimits.confが必要

ulimitコマンドで設定した値は、そのシェル(セッション)が終了すると失われます。ログアウトしても設定を維持したい場合は、/etc/security/limits.conf(または/etc/security/limits.d/以下の設定ファイル)に永続的な設定を記述します。

ユーザー名または@グループ名 soft/hard/- 項目 値

例えば次の行は、appuserが生成できるプロセス数のソフトリミットを4096に設定します。

appuser soft nproc 4096

このlimits.confの設定は、PAM(Pluggable Authentication Modules)のpam_limits.soモジュールが設定されているログインサービスで、ログインセッションの開始時に読み込んで適用する仕組みになっています。「ulimitコマンドを実行すれば恒久的に設定が反映される」わけではなく、「ulimitはその場限りの確認・調整用のコマンドであり、恒久的な設定はlimits.conf側で行う」という役割分担を押さえておくことが重要です。

自動ログアウトの設定:TMOUT

TMOUTは、bashなどのシェルが持つ特殊なシェル変数で、対話型シェルにおいて、一定時間(秒単位)入力が無かった場合に自動的にシェルを終了(ログアウト)させるための仕組みです。

export TMOUT=600

上記の設定は、600秒(10分)操作が無いとシェルが自動的に終了することを意味します。

  • 単位は秒です。
  • TMOUTによる自動ログアウトは対話型シェルに適用されます。非対話シェル自体を自動ログアウトさせるものではありませんが、bashでは非対話シェルのread組み込みコマンドの既定タイムアウト値として影響する場合があります。
  • 現在のシェルだけでなく、これから起動する子プロセスのシェルにも設定を反映させたい場合は、exportを付けて環境変数としてエクスポートする必要があります。
  • ログインシェルに適用したい場合は、/etc/profileや/etc/profile.d/以下のスクリプトにTMOUTの設定を記述します(ログインシェル起動時に読み込まれるため)。

システム管理者が設定した自動ログアウトを、一般ユーザーが自分のシェル内でTMOUT=0やunset TMOUTによって無効化できてしまうと、セキュリティ対策として機能しません。これを防ぐため、その設定を読み込んだシェル内での変更・解除を防止する目的で、readonly TMOUTとして読み取り専用に設定する運用が広く紹介されていますreadonlyにすることはTMOUTという仕組み自体が要求する必須の設定ではなく、あくまで「一般ユーザーに変更・解除させないための追加の運用上の工夫」です。「TMOUTは必ずreadonlyにしなければならない」という意味ではない点に注意してください。読み取り専用属性は子シェルへそのまま継承されないため、これだけで全てのシェルでの無効化を完全に防げるわけではありません。[5]。


補足

  1. この制限は多くのディストリビューションで標準的に用意されている設定例ですが、既定で有効になっているとは限らず、ディストリビューションや設定次第です。「wheelグループのメンバーでなければsuが一切使えない」と断定せず、あくまで「そのように制限する設定が一般的に用意されている」と理解してください。 ↩
  2. sudoersのrootpw、runaspw、targetpwなどの設定により、認証に求めるパスワードを変更することもできます。 ↩
  3. この既定の時間はディストリビューションやバージョン、/etc/sudoers側のtimestamp_timeout設定によって変わり得るため、「常に15分」と断定はできません。 ↩
  4. /var/log/wtmpはバイナリ形式のログファイルであるため、catなどのテキスト表示コマンドでそのまま閲覧することはできません。lastコマンド経由で参照します。 ↩
  5. readonlyにすることはTMOUTという仕組み自体が要求する必須の設定ではなく、あくまで「一般ユーザーに変更・解除させないための追加の運用上の工夫」です。「TMOUTは必ずreadonlyにしなければならない」という意味ではない点に注意してください。読み取り専用属性は子シェルへそのまま継承されないため、これだけで全てのシェルでの無効化を完全に防げるわけではありません。 ↩