はじめに
Linux はマルチユーザーオペレーティングシステムです。すべてのプロセスとファイルはユーザーに属し、すべてのユーザーにはプライマリグループと、任意の補助グループがあります。ユーザーの識別情報、所有権、権限ビットによって、リソースの読み取り、変更、実行、またはディレクトリへの移動を許可されるユーザーが決まります。
この実験では、専用の練習用アカウントを使って小規模なチーム環境を構築します。ユーザーの作成、グループメンバーシップの管理、ファイルの保護、アカウントロックの確認、umask によるデフォルト権限の制御、sticky bit と setgid ディレクトリの設定を行います。すべての操作は実験環境内で完結し、デフォルトの labex ログインパスは変更されません。
識別情報を確認して練習用ユーザーを作成する
このステップでは、現在のユーザー情報を確認し、権限演習用の別アカウントを作成します。Linux では、ユーザーをユーザー名と数値のユーザー ID(UID)で表します。また、プライマリグループ ID(GID)と補助グループも記録されます。
まず、現在の shell のユーザー情報を確認します。
whoami
出力は labex になるはずです。次に、このアカウントに関連付けられた UID、プライマリグループ、補助グループを表示します。
id
数値 ID は環境によって異なる場合がありますが、出力には uid、gid、groups というラベルが表示されます。
アカウントの作成はシステムファイルを変更するため、管理者権限が必要です。sudo は「superuser do」を意味し、現在のアカウントに実行が許可されているかを確認したうえで、続くコマンドを高い権限で実行します。管理者権限が必要なコマンドにだけ使用し、Enter キーを押す前にコマンド全体を確認してください。
次の useradd コマンドでは、3 つのオプションを使用します。
-mはホームディレクトリを作成します。-Uはユーザー名と同じ名前のプライマリグループを作成します。-s /bin/bashはアカウントのログイン shell として Bash を指定します。
jack という練習用ユーザーを作成します。
sudo useradd -m -U -s /bin/bash jack
新しいアカウントとホームディレクトリを確認します。
id jack
ls -ld /home/jack
id の出力では、jack がユーザーとプライマリグループの両方として表示されるはずです。ディレクトリ一覧には、/home/jack が存在し、jack:jack に属していることが表示されます。
補助グループを管理する
このステップでは、チーム用グループを作成し、ユーザーを補助グループに追加します。通常、ユーザーのプライマリグループは、新しく作成するファイルのグループ所有者になります。補助グループを使うと、追加の共有リソースへのアクセス権を付与できます。
developers という名前のグループを作成します。
sudo groupadd developers
usermod -aG オプションは、「補助グループに追加する」ことを意味します。-a は重要です。-a を付けずに -G を使用すると、既存の補助グループメンバーシップが置き換えられる場合があります。jack を developers と sudo の両方に追加します。
sudo usermod -aG developers,sudo jack
さらに、labex を developers のメンバーとして登録します。現在の shell に新しいグループ情報はすぐには反映されないため、最後のステップで安全に更新します。
sudo usermod -aG developers labex
両方のアカウントを確認します。
groups jack
groups labex
最初の出力には jack、developers、sudo が含まれるはずです。2 つ目の出力には developers が含まれるはずです。sudo のメンバーシップがあると、認証済みのアカウントは高い権限を要求できます。この権限は、信頼できる管理者にだけ付与してください。
ファイルの所有権と権限を制御する
このステップでは、特定の所有者、グループ、権限モードを持つチームレポートを保護します。長形式の一覧表示では、最初にファイル種別が表示され、その後に所有者、グループ、その他のユーザー向けの 3 つの権限セットが続きます。
プロジェクトディレクトリに空のレポートファイルを作成します。
touch /home/labex/project/secure-report.txt
user:group 形式の chown を使って、ユーザーとグループの所有者を変更します。
sudo chown jack:developers /home/labex/project/secure-report.txt
モードを 640 に設定します。
sudo chmod 640 /home/labex/project/secure-report.txt
数値表記では、読み取り権限は 4、書き込み権限は 2、実行権限は 1 です。したがって、次の意味になります。
- 所有者の
6は読み取りと書き込み(4 + 2)を意味します。 - グループの
4は読み取り専用を意味します。 - その他のユーザーの
0はアクセス権がないことを意味します。
結果を確認します。
ls -l /home/labex/project/secure-report.txt
stat -c 'owner=%U group=%G mode=%a' /home/labex/project/secure-report.txt
stat の安定した項目には、owner=jack group=developers mode=640 と表示されるはずです。
アカウントロックを確認して変更する
このステップでは、専用アカウントを一時的にロックおよびロック解除する練習を行います。Linux は、パスワードハッシュとアカウント状態を /etc/shadow に保存します。パスワードフィールドの先頭に ! がある場合、そのアカウントのパスワード認証はロックされています。
セットアップでは、contractor という練習用アカウントを作成済みです。ハッシュそのものが表示されないように、パスワードフィールドの先頭文字だけを表示します。パイプラインは左から右に読みます。getent shadow contractor がアカウントの shadow レコードを取得し、最初の cut が : を区切り文字としてフィールド 2 を選択し、2 つ目の cut がそのフィールドの 1 文字目だけを残します。
sudo getent shadow contractor | cut -d: -f2 | cut -c1
最初の文字は通常、最新のパスワードハッシュ形式の先頭を示す $ になります。usermod -L でアカウントをロックします。
sudo usermod -L contractor
もう一度、先頭文字を確認します。
sudo getent shadow contractor | cut -d: -f2 | cut -c1
今度は ! になるはずです。usermod -U でアカウントをロック解除し、! が消えたことを確認します。
sudo usermod -U contractor
sudo getent shadow contractor | cut -d: -f2 | cut -c1
このシナリオでは、contractor はチームを離れました。ファイルを保持したまま、最後にもう一度アカウントをロックします。
sudo usermod -L contractor
パスワード認証をロックしても、アカウントの削除やホームディレクトリの削除が行われるわけではなく、既存のセッションが必ず終了するわけでもありません。これはユーザーを削除する操作とは異なり、レビューのためにファイルを保持する必要がある場合に役立ちます。
Umask でデフォルト権限を制御する
このステップでは、shell が新しいファイルやディレクトリを作成するときに取り除く権限ビットを、umask で制御します。通常、プログラムは通常ファイルに対して最大モード 666、ディレクトリに対して 777 で開始します。マスク 027 は、グループから書き込み権限を、その他のユーザーからすべての権限を取り除きます。
実験用のワークスペースを作成します。
mkdir -p /home/labex/project/umask-demo
後で元に戻せるように、現在のマスクを保存します。$(command) は コマンド置換 と呼ばれます。shell は括弧内のコマンドを実行し、その出力で式全体を置き換えます。この代入では、その結果を original_umask に保存します。他の shell 変数の代入と同様に、= の前後にスペースは入れません。
original_umask=$(umask)
マスク 027 を適用してから、ファイルとディレクトリを作成します。
umask 027
touch /home/labex/project/umask-demo/private-note.txt
mkdir /home/labex/project/umask-demo/private-dir
作成されたモードを数値で確認します。
stat -c '%a %n' /home/labex/project/umask-demo/private-note.txt /home/labex/project/umask-demo/private-dir
ファイルのモードは 640、ディレクトリのモードは 750 になるはずです。ファイルには、実行権限が自動的に付与されません。shell の元のマスクを復元します。
umask "$original_umask"
umask の変更は、それ以降に作成するオブジェクトに影響します。既存のオブジェクトの権限を書き換えることはありません。
Sticky bit で共有ディレクトリを保護する
このステップでは、すべてのユーザーがファイルを作成できる一方で、他のユーザーが所有するファイルを削除できない共有ドロップボックスを設定します。通常のモード 777 は、すべてのユーザーにディレクトリへの完全なアクセス権を付与します。sticky bit を追加すると、そのディレクトリ内での削除ルールが変わります。
共有ディレクトリを作成し、モードを 1777 に設定します。先頭の 1 が sticky bit を有効にします。
mkdir /tmp/shared-dropbox
chmod 1777 /tmp/shared-dropbox
sudo -u を使い、それぞれの練習用アカウントとして 1 つずつファイルを作成します。
sudo -u jack touch /tmp/shared-dropbox/jack-note.txt
sudo -u contractor touch /tmp/shared-dropbox/contractor-note.txt
次に、jack として contractor のファイルを削除してみます。
sudo -u jack rm /tmp/shared-dropbox/contractor-note.txt
この失敗は意図した結果です。Operation not permitted と表示され、contractor のファイルが残っているはずです。ディレクトリを確認します。
ls -ld /tmp/shared-dropbox
権限の末尾は、drwxrwxrwt のように小文字の t になるはずです。小文字の t は、sticky bit とその他のユーザーに対する実行権限の両方が設定されていることを示します。大文字の T は、sticky bit は設定されているものの、対応する実行権限がないことを示します。
Setgid チームディレクトリを設定する
このステップでは、非公開の共同作業用ディレクトリを準備します。ディレクトリに setgid を設定すると、新しく作成された子要素は、作成者のプライマリグループではなく、そのディレクトリのグループを継承します。これにより、チームのファイルを 1 つの共有グループに関連付けたままにできます。
ディレクトリを作成します。
mkdir /home/labex/project/team-share
jack をユーザー所有者に、developers をグループ所有者に設定します。
sudo chown jack:developers /home/labex/project/team-share
モードを 2770 に設定します。先頭の 2 が setgid を有効にします。770 は所有者とグループに完全なアクセス権を付与し、その他のユーザーのアクセスを拒否します。
sudo chmod 2770 /home/labex/project/team-share
結果を確認します。
ls -ld /home/labex/project/team-share
stat -c 'owner=%U group=%G mode=%a' /home/labex/project/team-share
長形式の一覧には、グループの実行権限の位置に、drwxrws--- のような s が表示されるはずです。小文字の s は、setgid とグループの実行権限の両方が有効であることを示します。大文字の S は、setgid は設定されているものの、グループの実行権限がないことを示します。
所有者の実行権限の位置に s で表示される setuid も、慎重に管理されたシステム実行ファイルでよく使われる特殊ビットです。権限を読むときに setuid を認識できるようにしてください。ただし、任意のプログラムに追加してはいけません。
グループメンバーシップを更新して継承を確認する
このステップでは、子 shell で developers のメンバーシップを有効にし、setgid によって新しいファイルのグループが決まることを確認します。ユーザーを /etc/group に追加しても、すでに実行中の shell の補助グループ情報は書き換えられません。
developers をアクティブグループとして子 shell を起動します。
newgrp developers
プロンプトが更新される場合があります。ユーザーは引き続き labex ですが、子 shell では developers が有効なグループになります。両方の識別情報を確認します。
id
setgid ディレクトリにファイルを作成します。
touch /home/labex/project/team-share/labex-note.txt
新しいファイルを確認します。
stat -c 'owner=%U group=%G mode=%a' /home/labex/project/team-share/labex-note.txt
所有者は labex、グループは developers になるはずです。setgid はグループ所有者を継承させますが、ファイルの読み取りと書き込みの権限は、作成プロセスとその umask によって決まります。
子 shell を終了し、元のターミナルセッションに戻ります。
exit
子 shell を閉じた後も、ファイルはそのまま残ります。
まとめ
Linux システムで使われる基本的な識別情報とアクセスモデルを練習しました。ユーザーとチームグループを作成し、補助グループのメンバーシップを管理し、所有権を割り当て、数値の権限モードを実際のアクセスルールに対応付けました。また、パスワードハッシュを公開せずにアカウントロックを確認しました。
続いて、通常の権限以外の仕組みも扱いました。umask でデフォルト権限を制御し、sticky bit で公開ディレクトリ内のファイルを保護し、setgid で非公開の共同作業用ディレクトリにおけるチームグループの所有権を維持しました。最後に、newgrp でグループメンバーシップを更新し、実際のファイルで継承されたグループを確認しました。



