Linuxエンジニア養成講座 第10回|全36回・フェーズ2「Linux基礎」の7回目です。
前回までに学んだこと: viエディタの基本操作、モードの概念、vi -R によるリードオンリー表示(第9回)。
今回学ぶこと: ユーザーとグループの仕組み、/etc/passwd と /etc/shadow の読み方、ユーザーの作成・変更・削除、sudo の仕組み。
この記事を読み終えると、以下のことができるようになります。
- /etc/passwd の各フィールドの意味を読み取れる
- useradd でユーザーを新規作成し、passwd でパスワードを設定できる
- usermod でユーザーの属性(所属グループ等)を変更できる
- userdel でユーザーを削除できる
- sudo の仕組み(wheel グループ、/etc/sudoers)を理解し、なぜ root で直接作業しないのかを説明できる
- id / groups コマンドでユーザーの所属情報を確認できる
alma-mainにSSH接続した状態で進めます。以降のコマンドはすべてalma-main上で実行します。
なぜユーザー管理を学ぶのか
業務用のLinuxサーバーには、複数のエンジニアがSSHでログインして作業します。障害が発生したとき「誰がいつ何をしたか」を追跡できなければ、原因究明は困難です。そのため、サーバーには利用者ごとに個別のアカウントを作成し、「全員が同じアカウントを共有する」運用は禁止するのが原則です。これは監査の観点からも求められます。第3回「セキュリティ意識の基本」で学んだ最小権限の原則を、今回はLinuxのアカウント管理として具体的に体験します。
第8回で cat /etc/passwd | cut -d: -f1 を実行してユーザー名の一覧を取り出しました。あのコマンドで抜き出していたのは、/etc/passwd というファイルの1番目のフィールドです。今回はそのファイルの全フィールドを読み解き、ユーザーの作成から削除までを一通り行います。
また、第7回から sudo dnf install ... のように使ってきた sudo は、これまで「おまじない」のように扱ってきました。今回はその正体を明かします。
Linuxにおけるユーザーの仕組み
root と一般ユーザー
Linuxには大きく分けて2種類のユーザーがいます。
root(ルート)は、システム上のあらゆる操作が可能なスーパーユーザーです。ファイルの削除も、サービスの停止も、OS自体の設定変更も制限なく実行できます。裏を返せば、rm -rf / のような破壊的なコマンドも止められません。
一般ユーザーは、制限された権限で操作を行います。自分のホームディレクトリ内では自由にファイルを作成・編集できますが、システム全体に影響する操作(パッケージのインストール、サービスの起動など)にはroot権限が必要です。
現場では「rootで直接ログインして作業する」ことは避けます。理由はミスの影響範囲が無制限になるからです。一般ユーザーでログインし、必要なときだけ sudo で権限を昇格する運用が標準です。
UID と GID
Linuxはユーザーを「名前」ではなく「番号」で管理しています。この番号を UID(User ID)と呼びます。同様にグループも GID(Group ID)という番号で識別されます。
人間が「developer」と呼ぶユーザーを、Linuxは内部的に「1000」という数字で管理しています。id コマンドで確認してみます。
実行コマンド:
$ id developer
実行結果:
uid=1000(developer) gid=1000(developer) groups=1000(developer),10(wheel)
uid=1000 がこのユーザーの UID、gid=1000 がプライマリグループの GID です。groups の部分には所属する全グループが表示されています。
UIDには範囲があり、/etc/login.defs というファイルで定義されています。
| UID の範囲 | 用途 |
|---|---|
| 0 | root(スーパーユーザー) |
| 1〜999 | システムユーザー(サービス実行用) |
| 1000〜60000 | 一般ユーザー |
この範囲は /etc/login.defs の UID_MIN(1000)と UID_MAX(60000)で定義されています。useradd で一般ユーザーを作成すると、1000番以降の空き番号が自動的に割り当てられます。
グループの仕組み
グループとは、複数のユーザーをまとめて同じ権限を付与する仕組みです。ユーザーには2種類のグループ所属があります。
プライマリグループ(主グループ): ユーザー作成時に1つ割り当てられるグループです。ファイルを作成すると、このグループが所有グループになります(詳細は第11回「パーミッションと所有権」で学びます)。
サプリメンタリグループ(補助グループ): 追加で所属できるグループです。1人のユーザーが複数の補助グループに所属できます。先ほどの id developer の出力で、developer は自身のプライマリグループ(developer, GID=1000)に加えて、補助グループとして wheel(GID=10)にも所属していました。
groups コマンドでも所属グループを確認できます。
実行コマンド:
$ groups developer
実行結果:
developer : developer wheel
wheel グループとは何か、なぜ developer がそこに所属しているのかは、後ほど「sudoの仕組み」で解説します。
/etc/passwd を読み解く
前回学んだ vi -R(リードオンリーモード)で /etc/passwd を開いてみます。
実行コマンド:
$ vi -R /etc/passwd
内容を確認したら :q で閉じてください。cat コマンドでも同じ内容を表示できます。
実行コマンド:
$ cat /etc/passwd
実行結果:
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/:/usr/sbin/nologin
sssd:x:998:998:User for sssd:/:/sbin/nologin
polkitd:x:997:997:User for polkitd:/:/sbin/nologin
chrony:x:996:996:chrony system user:/var/lib/chrony:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin
developer:x:1000:1000:developer:/home/developer:/bin/bash
全21行あります。一般ユーザーは最後の developer(UID=1000)だけで、残りはすべてシステムユーザーです。
各行は :(コロン)で7つのフィールドに区切られています。第8回の cut -d: -f1 で抜き出していたのは、この1番目のフィールド(ユーザー名)でした。developer の行を例にフィールドを分解してみます。
developer : x : 1000 : 1000 : developer : /home/developer : /bin/bash
| | | | | | |
1 2 3 4 5 6 7
1. ユーザー名 : developer
2. パスワード欄 : x(実際のパスワードは /etc/shadow に格納)
3. UID : 1000
4. GID : 1000(プライマリグループのGID)
5. コメント(GECOS): developer(フルネームや説明を入れる欄)
6. ホームディレクトリ: /home/developer
7. ログインシェル : /bin/bash
2番目のフィールドの「x」は、パスワードが /etc/shadow という別ファイルに格納されていることを意味します。昔はこの欄にパスワードのハッシュ値が直接書かれていましたが、セキュリティ上の理由から分離されました(次のセクションで解説します)。
システムユーザーの行も見てみます。sshd の行に注目してください。
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin
7番目のフィールドが /usr/sbin/nologin になっています。これは「このユーザーではログインできない」ことを意味します。sshd はSSHサービスを動かすためだけに存在するユーザーであり、人間がこのアカウントでログインすることは想定されていません。サービスごとに専用のユーザーを割り当てるのは、最小権限の原則の体現です。万が一そのサービスに脆弱性があっても、被害がそのユーザーの権限範囲内に限定されます。
/etc/shadow — パスワードの管理
/etc/passwd は全ユーザーが読めるファイルです(パーミッション 644)。もしここにパスワードのハッシュ値が書かれていたら、どのユーザーでもハッシュを取得して解析を試みることができてしまいます。そこで、パスワード情報は /etc/shadow という別ファイルに分離されています。/etc/shadow は root しか読めません。
実行コマンド:
$ sudo cat /etc/shadow | grep developer
実行結果:
developer:$6$edCdSYECF2n2dE7e$k3mQF0GrSiOPHuc.i4HwI22q4KK29UUBklcQYgtn2ff7i7O3sYSn7p9QpnvjqN3aFP5T6wZHLSzk9sBW1Ca6o.::0:99999:7:::
先頭の $6$ は、パスワードのハッシュ方式が SHA-512 であることを示しています。この方式は /etc/login.defs の ENCRYPT_METHOD で定義されています。ハッシュ値そのものの詳細には立ち入りませんが、「元のパスワードから一方向に変換された文字列」とだけ理解しておいてください。
: で区切られたハッシュ値の後ろには、パスワードの有効期限に関する情報が続きます。::0:99999:7::: の部分は、最小変更間隔0日、最大有効日数99999日(実質無期限)、期限切れ7日前に警告、という意味です。
システムユーザーの shadow エントリも確認してみます。
実行コマンド:
$ sudo cat /etc/shadow | grep sshd
実行結果:
sshd:!!:20536::::::
パスワード欄が !! になっています。これはパスワードが設定されていない(ロックされている)ことを意味します。* もログイン不可を示す記号です。システムユーザーはログインを想定していないため、パスワードが設定されることはありません。
ユーザーの作成・変更・削除
ここからは useradd、passwd、usermod、userdel の4つのコマンドを使って、ユーザーの一連のライフサイクルを体験します。
useradd — ユーザーを作成する
新しいユーザー trainee01 を作成します。
実行コマンド:
$ sudo useradd trainee01
エラーが出なければ成功です。作成されたユーザーの情報を確認します。
実行コマンド:
$ id trainee01
実行結果:
uid=1001(trainee01) gid=1001(trainee01) groups=1001(trainee01)
UID=1001 が自動的に割り当てられました(developer が 1000 を使っているため、次の番号です)。プライマリグループとして trainee01(GID=1001)も自動作成されています。
/etc/passwd にエントリが追加されたことも確認します。
実行コマンド:
$ getent passwd trainee01
実行結果:
trainee01:x:1001:1001::/home/trainee01:/bin/bash
useradd はデフォルトで以下の処理を行います。
- /etc/passwd にエントリを追加
- /etc/shadow にエントリを追加
- 同名のプライマリグループを作成(/etc/group に追加)
- ホームディレクトリ /home/trainee01 を作成
- /etc/skel 配下のファイル(.bashrc、.bash_profile、.bash_logout)をホームディレクトリにコピー
デフォルト設定は useradd -D で確認できます。useradd にどんなオプションがあるか知りたいときは man useradd を参照してください。
passwd — パスワードを設定する
useradd でユーザーを作成しただけでは、パスワードが設定されていません。この状態ではログインできません。パスワードを設定します。
実行コマンド:
$ sudo passwd trainee01
実行結果:
ユーザー trainee01 のパスワードを変更。
新しい パスワード:
正しくない パスワード: このパスワードは辞書チェックに失敗しました - 類似した文字の繰り返しが多すぎます
新しい パスワード:
よくない パスワード: このパスワードは8文字未満です。
新しい パスワード:
新しい パスワード を再入力してください:
passwd: すべての認証トークンが正しく更新できました。
パスワード入力時は画面に文字が表示されません。これは仕様です。また、短すぎるパスワードや単純なパスワードを入力すると警告が表示されます。検証環境なので適当なパスワードでも設定できますが、本番環境では十分な強度のパスワードを使用してください。
usermod — ユーザー情報を変更する
作成済みのユーザーの属性を変更するには usermod を使います。よく使う操作は、ユーザーを補助グループに追加することです。
trainee01 を wheel グループに追加してみます。
実行コマンド:
$ sudo usermod -aG wheel trainee01
-aG は2つのオプションの組み合わせです。-a(append: 追加)と -G(supplementary groups: 補助グループ)を意味します。このオプションの組み合わせは、既存の補助グループを維持したまま新しいグループを追加します。
追加されたことを確認します。
実行コマンド:
$ id trainee01
実行結果:
uid=1001(trainee01) gid=1001(trainee01) groups=1001(trainee01),10(wheel)
groups に wheel(GID=10)が追加されています。usermod には他にも -c(コメント変更)や -s(ログインシェル変更)といったオプションがあります。詳細は man usermod で確認できます。
userdel — ユーザーを削除する
不要になったユーザーを削除するには userdel を使います。2つの使い方があります。
ユーザーのみ削除(ホームディレクトリは残る):
$ sudo userdel trainee01
ホームディレクトリごと削除:
$ sudo userdel -r trainee01
現場では、退職者のアカウントをすぐに削除するのではなく、まず usermod -L(Lock: アカウントロック)でログインを無効化し、一定期間経過後に削除するのが一般的です。退職直後にアカウントを削除すると、そのユーザーが作成したファイルの所有者が UID の数字だけになり、「誰のファイルだったか」がわからなくなるためです。
ここでは後ほど「やってみよう」セクションで改めて作成するため、一旦削除しておきます。
実行コマンド:
$ sudo userdel -r trainee01
sudo の仕組み
第7回で sudo dnf install vim-enhanced tree man-pages bash-completion を実行したとき、sudo は「root権限でコマンドを実行するためのおまじない」として使いました。ここでは、その仕組みを理解します。
sudo と su の違い
sudo は、コマンド単位で一時的にroot権限を借りて実行する仕組みです。sudo dnf install ... のように、1つのコマンドだけがroot権限で実行され、終わったら元の一般ユーザーに戻ります。
su は、ユーザーそのものを切り替えるコマンドです。su - root を実行するとrootに切り替わり、exit で戻るまでrootのままです。
sudo が推奨される理由は、「誰が」「いつ」「何のコマンドを」実行したかがログ(/var/log/secure)に記録されることです。su でrootに切り替えてしまうと、以降の操作は「rootが実行した」としか記録されず、実際の操作者が特定できなくなります。
wheel グループと /etc/sudoers
sudo が使えるかどうかは /etc/sudoers ファイルで制御されています。AlmaLinux のデフォルト設定を確認してみます。
実行コマンド:
$ sudo cat /etc/sudoers | grep wheel
実行結果:
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
# %wheel ALL=(ALL) NOPASSWD: ALL
コメント行(# で始まる行)を含む3行が表示されます。有効な設定行 %wheel ALL=(ALL) ALL の意味は次のとおりです。
%wheel— wheel グループに所属するユーザー全員が対象(% はグループを意味する)ALL=— どのホストからでも(ALL)— どのユーザーとしてでもALL— どのコマンドでも実行できる
つまり、wheel グループに所属していれば sudo が使えるということです。developer ユーザーは wheel グループに所属しているため、第7回から sudo を使えていたのです。先ほど trainee01 を wheel グループに追加したのも、sudo を使えるようにするためでした。
検証環境の developer には、さらに特別な設定があります。
実行コマンド:
$ sudo cat /etc/sudoers.d/developer
実行結果:
developer ALL=(ALL) NOPASSWD: ALL
NOPASSWD の設定により、developer は sudo 実行時にパスワードを求められません。これは検証環境で作業効率を上げるための設定です。本番環境では通常、sudo 実行時にパスワード入力が求められます。パスワード入力は「本当にroot権限が必要な操作を実行しようとしているか」を確認する安全装置の役割を果たしています。
visudo — sudoers を安全に編集する
/etc/sudoers を編集する必要がある場合は、visudo コマンドを使います。vi /etc/sudoers で直接編集してはいけません。
visudo は内部的に vi を起動してファイルを編集させますが、保存時に構文チェックを行います。/etc/sudoers に構文エラーがあると sudo 自体が使えなくなり、復旧が困難になります。visudo はその事故を防ぐためのコマンドです。前回学んだ vi の操作がここでも活きてきます。
今回は visudo の実行は行いませんが、存在を知っておくことが重要です。今後サーバーの sudo 設定を変更する場面では、必ず visudo を使ってください。
やってみよう — ユーザーを作成して sudo 権限を付与する
ここまで学んだコマンドを組み合わせて、ユーザーの作成から削除までの一連の流れを実践します。
ステップ1: ユーザーを作成する
実行コマンド:
$ sudo useradd trainee01
ステップ2: ユーザー情報を確認する
実行コマンド:
$ id trainee01
実行結果:
uid=1001(trainee01) gid=1001(trainee01) groups=1001(trainee01)
ステップ3: /etc/passwd のエントリを確認する
実行コマンド:
$ getent passwd trainee01
実行結果:
trainee01:x:1001:1001::/home/trainee01:/bin/bash
ステップ4: パスワードを設定する
実行コマンド:
$ sudo passwd trainee01
任意のパスワードを入力してください。検証環境のため、短いパスワードでも警告を無視して設定できます。
ステップ5: wheel グループに追加する
実行コマンド:
$ sudo usermod -aG wheel trainee01
ステップ6: グループ追加を確認する
実行コマンド:
$ id trainee01
実行結果:
uid=1001(trainee01) gid=1001(trainee01) groups=1001(trainee01),10(wheel)
wheel グループが追加されていることを確認できます。
ステップ7: trainee01 に切り替えて sudo を試す
実行コマンド:
$ su - trainee01
trainee01 のパスワードを求められるので、ステップ4で設定したパスワードを入力します。切り替わったら sudo が使えるか確認します。
実行コマンド:
$ sudo whoami
trainee01 のパスワードを求められるので入力してください(developer と違い NOPASSWD 設定がないためです)。
実行結果:
root
root と表示されれば、sudo が正常に動作しています。trainee01 が wheel グループに所属しているため、sudo が使えます。
ステップ8: developer に戻る
実行コマンド:
$ exit
developer ユーザーに戻ります。プロンプトの表示が developer に戻っていることを確認してください。
クリーンアップ: ユーザーを削除する
実行コマンド:
$ sudo userdel -r trainee01
削除されたことを確認します。
実行コマンド:
$ id trainee01
実行結果:
id: `trainee01': no such user
ユーザーが存在しないことを確認できました。これでクリーンアップ完了です。
現場のヒヤリハット — usermod -G で既存グループが消えた
ある新人エンジニアが、ユーザーを新しいグループに追加しようとして次のコマンドを実行しました。
$ sudo usermod -G newgroup someuser
-a オプションを付け忘れています。-G だけを指定すると、既存の補助グループがすべて上書きされ、newgroup だけになります。その結果、someuser は wheel グループから外れてしまい、sudo が使えなくなりました。本人はパニック状態になりましたが、幸い別の管理者が root でログインして wheel グループに再追加し、復旧できました。
教訓: usermod -G は必ず -aG(追加)で使う。不安なときは実行前に man usermod でオプションの意味を確認する習慣を持ちましょう。
理解度チェック
以下の文が正しければ○、間違っていれば×と答えてください。
- /etc/passwd の2番目のフィールド「x」は、パスワードそのものが格納されている
- UID 0 のユーザーは root である
- useradd でユーザーを作成しただけで、すぐにパスワード認証でログインできる
- usermod -G group user を実行すると、そのユーザーの既存の補助グループは維持される
- sudo は実行ログが /var/log/secure に記録される
- /etc/shadow は一般ユーザーでも読める
- wheel グループに所属しているユーザーは sudo が使える(AlmaLinux のデフォルト設定)
- visudo ではなく vi /etc/sudoers で直接編集するべきである
解答
- × ―― 「x」はパスワードが /etc/shadow に格納されていることを示す記号。パスワードそのものではない
- ○ ―― UID 0 は root に予約されている
- × ―― useradd だけではパスワードが未設定。passwd コマンドでパスワードを設定する必要がある
- × ――
-Gだけでは既存の補助グループが上書きされる。既存グループを維持するには-aGを使う - ○ ―― sudo の実行ログは /var/log/secure に記録される。「誰が何を実行したか」の追跡に使われる
- × ―― /etc/shadow は root しか読めない。パスワードハッシュを保護するためにアクセスが制限されている
- ○ ―― AlmaLinux では /etc/sudoers に
%wheel ALL=(ALL) ALLが設定されている - × ―― /etc/sudoers は必ず visudo で編集する。構文エラーがあると sudo 自体が使えなくなるため、visudo の構文チェック機能が必要
まとめ
今回はLinuxのユーザーとグループの仕組みを学びました。
- Linuxはユーザーを UID(番号)で管理する。0 = root、1〜999 = システムユーザー、1000以降 = 一般ユーザー
- /etc/passwd にはユーザー名・UID・GID・ホームディレクトリ・ログインシェルなど7つのフィールドがある
- /etc/shadow にはパスワードハッシュが格納されており、root しか読めない
- useradd でユーザー作成、passwd でパスワード設定、usermod で属性変更、userdel で削除
- usermod -G は必ず
-aGで使う(-a を忘れると既存グループが消える) - sudo はコマンド単位でroot権限を借りる仕組み。wheel グループへの所属が条件
- /etc/sudoers の編集は必ず visudo を使う
- 共有アカウントは禁止。個人アカウントで作業し、必要なときだけ sudo を使うのが原則
今回ユーザーとグループを学びました。次回の第11回「パーミッションと所有権」では、ファイルの「誰が読めるか・書けるか・実行できるか」を制御するパーミッションを学びます。ユーザーとグループはパーミッションの土台です。今回の知識なしには次回の内容は理解できません。trainee01 が developer のファイルにアクセスできないのはなぜか、その答えは次回わかります。
シリーズ一覧
フェーズ1: エンジニアのいろは(第1回〜第3回)
フェーズ2: Linux基礎(第4回〜第15回)
- 第4回 Linuxとは何か+環境確認
- 第5回 SSH接続とターミナル操作
- 第6回 ファイルシステムとディレクトリ構造
- 第7回 基本コマンド(ファイル操作)
- 第8回 基本コマンド(テキスト処理・パイプとリダイレクト)
- 第9回 viエディタ
- 第10回 ユーザーとグループ管理(この記事)
- 第11回 パーミッションと所有権
- 第12回 プロセス管理
- 第13回 systemd
- 第14回 シェルスクリプト入門
- 第15回 フェーズ2まとめ演習
フェーズ3: ネットワークとインフラ基盤(第16回〜第27回)
- 第16回 ネットワーク基礎
- 第17回 ネットワーク設定と疎通確認
- 第18回 企業ネットワークの仕組み
- 第19回 パッケージ管理
- 第20回 ファイアウォール(firewalld)
- 第21回 ボンディング/チーミング
- 第22回 VLAN
- 第23回 ログ管理
- 第24回 cron / systemd timer
- 第25回 ストレージ管理(LVM)
- 第26回 シェルスクリプト実践
- 第27回 SSH応用
フェーズ4: サーバー構築と運用(第28回〜第36回)
