Linuxサーバーに、退職者のアカウントが残ったままになっていませんか?
「本番サーバーに誰も使っていないアカウントがある」「サービスアカウントにログインシェルが設定されたまま」「パスワードに有効期限が設定されていない」——こうした状態は、攻撃者に無防備な裏口を提供しているようなものです。
堅牢なファイアウォールを築いていても、有効な認証情報が1つあれば攻撃者はシステムに「正規ユーザー」として侵入できます。不正アクセスの多くは、こうした管理されていないアカウントを突き口として始まります。
この記事では、Linuxのユーザーアカウント管理を見直すための実践的な手順を解説します。アカウントの棚卸し方法から、不要アカウントの削除・ロック、ログインシェルの制限、chageコマンドを使ったパスワード期限設定まで、情シス1人でもすぐ実行できる内容です。
なぜユーザーアカウント管理がセキュリティの要なのか
Linuxのユーザー情報は、主に2つのファイルで管理されています。
・/etc/passwd: ユーザー名・UID(ユーザーID)・GID(グループID)・ホームディレクトリ・ログインシェルが記録されています。すべてのユーザーが読み取り可能なファイルです
・/etc/shadow: ハッシュ化されたパスワードとパスワードの期限情報が記録されています。rootのみが読み取り可能です
「ユーザーアカウントが有効である」ということは、そのアカウントに対応したパスワードや秘密鍵を持つ者がシステムにログインできることを意味します。アカウントの数だけ、攻撃者の侵入口が存在するのです。
適切にアカウントを管理することで、攻撃面(アタックサーフェス)を最小化できます。これは、ファイアウォールの設定やパスワードポリシーと並ぶ、Linuxセキュリティの基本中の基本です。
攻撃者が狙う「放置されたアカウント」の実態
1. 退職者・異動者のアカウントが残存している
人事異動や退職が発生したとき、Linuxサーバーのアカウントが削除されないことは非常によくあります。アカウントが生きていれば、元社員が設定したパスワードでログインできてしまいます。そのパスワードが過去のデータ侵害で流出している場合、まったくの第三者でも利用可能です。
2. UID 0(root権限)が意図せず複数存在する
Linuxでは、UID(ユーザーID)が0のアカウントがroot権限を持ちます。通常はrootアカウントのみですが、システム移行時の手動操作や設定ミスで、UID 0のアカウントが複数存在することがあります。この状態に気づかずにいると、攻撃者に完全な管理者権限を与えてしまいます。
3. サービスアカウントにログインシェルが設定されている
apacheやnginx、mysqlといったサービス実行用のアカウントは、本来ログイン目的ではありません。しかし設定を誤ると、これらのアカウントに/bin/bashなどの対話型シェルが設定されたままになり、パスワードや鍵を入手した攻撃者がSSHでログインできる状態になります。
4. パスワード未設定・有効期限なしのアカウント
パスワードフィールドが空のアカウントや、有効期限が設定されていないアカウントは、長期間にわたって攻撃者に悪用されるリスクがあります。一度設定したパスワードが何年も変更されないと、データ侵害で流出した際の被害が長引きます。
具体的な防御手順
1. アカウントの棚卸し:まず現状を把握する
最初に「どんなアカウントが存在するか」を把握します。以下のコマンドで全体像を確認しましょう。
# ユーザーアカウントの一覧(ユーザー名・UID・ホームディレクトリ・シェル) awk -F: '{print $1, $3, $6, $7}' /etc/passwd # 対話型シェルを持つアカウント(nologin・false以外のシェルを持つユーザー) awk -F: '$7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 != "" {print $1, $3, $7}' /etc/passwd
次に、UID 0を持つアカウント(root権限アカウント)を確認します。rootアカウント以外にUID 0が存在する場合は、意図したものか即時確認が必要です。
# UID 0を持つアカウントを一覧表示 awk -F: '$3==0 {print $1}' /etc/passwd # 正常な結果: rootのみが表示されるはずです # root以外が表示された場合は即時調査が必要です
最後に、最終ログイン日時を確認します。長期間ログインがないアカウントは、不要になっている可能性があります。
# 全ユーザーの最終ログイン日時を確認 lastlog # 一度もログインしていないアカウントを除いて表示 lastlog | grep -v "Never logged in"
2. 不要アカウントのロックと削除
不要なアカウントは、いきなり削除するよりも「まずロック → 業務影響がないことを確認 → 削除」の順で進めるのが安全です。
# アカウントをロックする(パスワードフィールドの先頭に ! を付ける) sudo usermod -L username # ロック状態を確認(L と表示されればロック済み) sudo passwd -S username # ロック解除が必要になった場合 sudo usermod -U username
業務上の影響がないことを確認した後、ホームディレクトリをバックアップしてから削除します。
# ホームディレクトリをアーカイブしてからアカウントを削除 sudo tar czf /backup/home_username_$(date +%Y%m%d).tar.gz /home/username # アカウントとホームディレクトリを削除 sudo userdel -r username # 削除後、そのユーザーIDが所有するファイルが残っていないか確認 sudo find / -nouser 2>/dev/null
3. サービスアカウントのログインシェルを制限する
サービス実行用アカウント(apache、nginx、mysql、nobodyなど)には、/usr/sbin/nologin か /bin/false を設定してSSH経由のログインを禁止します。
# サービスアカウントのログインシェルをnologinに変更 sudo usermod -s /usr/sbin/nologin apache sudo usermod -s /usr/sbin/nologin nginx sudo usermod -s /usr/sbin/nologin mysql # 変更後の確認(シェル欄が/usr/sbin/nologinになっていればOK) grep -E "^(apache|nginx|mysql):" /etc/passwd
/usr/sbin/nologin は「このアカウントは現在使用できません」というメッセージを表示してログインを拒否します。/bin/false は何も表示せずに終了します。サービスアカウントにはどちらでも構いません。
4. chageコマンドでパスワード有効期限を設定する
chage(change age)コマンドを使うと、パスワードの有効期限や警告日数をアカウントごとに設定できます。
# パスワード有効期限を90日・警告を7日前・最短変更間隔を1日に設定 sudo chage -M 90 -W 7 -m 1 username # オプションの意味: # -M 90: パスワードの最大有効日数を90日に設定 # -W 7 : 期限切れの7日前から警告を表示 # -m 1 : パスワード変更後1日は再変更できないように設定(即時切り戻し防止) # 設定内容を確認 sudo chage -l username
次回ログイン時にパスワード変更を強制させたい場合は次のコマンドを使います。
# 最終パスワード変更日を1970年1月1日に設定し、次回ログイン時に変更を強制 sudo chage -d 0 username # パスワードが事実上無期限になっているアカウントを一覧で確認 for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do expires=$(sudo chage -l "$user" | grep "Password expires" | awk -F: '{print $2}') echo "$user: $expires" done
5. /etc/login.defsでデフォルトポリシーを設定する
個別アカウントへの設定に加えて、新規作成されるアカウントへのデフォルトポリシーを/etc/login.defsで定義しておきましょう。
# /etc/login.defs の該当行を修正(デフォルト値からの変更点) # パスワードの最大有効日数(デフォルト: 99999 = 事実上無期限) PASS_MAX_DAYS 90 # パスワード変更後、次に変更できるまでの最短日数(デフォルト: 0) PASS_MIN_DAYS 1 # パスワード期限前の警告日数(デフォルト: 7) PASS_WARN_AGE 7
この設定は既存アカウントには適用されません。新規作成されるアカウントにのみ有効です。既存アカウントへの適用はchageコマンドを個別に実行してください。
| 設定項目 | 推奨値 | 意味 |
|---|---|---|
| PASS_MAX_DAYS | 90 | パスワードの最大有効日数(90日後に変更を強制) |
| PASS_MIN_DAYS | 1 | パスワード変更後1日は再変更できないように設定 |
| PASS_WARN_AGE | 7 | 期限切れ7日前から警告メッセージを表示 |
中小企業でも今日からできること
ユーザーアカウントのセキュリティ強化は、特別なツールを導入しなくても、Linuxの標準コマンドだけで実現できます。以下の3つを最優先で実施しましょう。
・優先度1 — UID 0アカウントの棚卸し: awk -F: '$3==0 {print $1}' /etc/passwd を実行し、root以外にUID 0が存在しないか確認します。もし存在すれば、意図的に作成されたものか即座に調査が必要です
・優先度2 — 90日以上ログインのないアカウントをロック: lastlog コマンドで最終ログイン日を確認し、90日以上ログインがないアカウントは担当者に確認の上でロックします。これだけで休眠アカウントを悪用した侵入リスクが大幅に下がります
・優先度3 — サービスアカウントのシェルをnologinに変更: apache・nginx・mysql等のサービスアカウントに対話型シェルが設定されていた場合、usermod -s /usr/sbin/nologin アカウント名 で修正します
この3ステップは合計30分程度で完了します。四半期に一度の定期棚卸しとして定着させることが理想的です。
よくある誤解と注意点
【誤解】「削除が怖いからロックだけしておけばいい」
ロックは一時的な措置として有効ですが、長期間ロック状態のまま放置するのも問題です。ホームディレクトリや設定ファイルが残ったままになり、ディスクを消費し続けます。また、将来的に誰かが誤ってロックを解除してしまうリスクもあります。ロックから半年以上経過した不要アカウントは、バックアップの上で削除することを推奨します。
【誤解】「サービスアカウントのシェルを変えると動かなくなる」
/usr/sbin/nologinに変更しても、サービスの動作には影響しません。SSH経由の対話型ログインが禁止されるだけで、httpd・mysqldのようなサービスプロセスは通常通り起動します。ただし、そのアカウントを使ってシェルスクリプトがsuで切り替えている場合は影響があります。変更前に grep -rn "su.*アカウント名" /etc/cron* /etc/init.d/ /etc/systemd/ などで確認しましょう。
【注意】変更作業は必ず別のSSHセッションを開いたまま行う
アカウントの設定変更や削除は、自分自身がログインできなくなるリスクを伴います。作業中は必ず別のSSHセッションを接続したまま作業し、変更後に新しいセッションでログインできることを確認してから既存のセッションを閉じてください。
Linuxのsudo設定やファイル権限管理については、姉妹サイトLinuxMaster.JPで詳しく解説しています。
本記事のまとめ
Linuxのユーザーアカウント管理は、複雑なセキュリティツールを導入しなくても、標準コマンドだけで大幅にセキュリティを向上させられる分野です。まず現状を把握し、不要なアカウントを削除・ロックすることから始めましょう。
| 対策 | コマンド/設定ファイル | 難易度 |
|---|---|---|
| アカウント棚卸し・UID 0確認 | awk、lastlog、passwd -S | 低(コマンド実行のみ) |
| 不要アカウントのロック | usermod -L / passwd -l | 低(コマンド実行のみ) |
| 不要アカウントの削除 | userdel -r | 低(削除前バックアップが必要) |
| サービスアカウントのシェル制限 | usermod -s /usr/sbin/nologin | 低(コマンド実行のみ) |
| パスワード有効期限の設定 | chage -M 90 -W 7 -m 1 | 低(コマンド実行のみ) |
| 新規アカウントのデフォルトポリシー | /etc/login.defs | 低(設定ファイル編集のみ) |
あなたのサーバーに「忘れられたアカウント」はありませんか?
今日紹介したコマンドを実行するだけで、見えていなかった侵入口を閉じられます。まず awk -F: '$3==0' /etc/passwd と lastlog を実行してみてください。
正しいセキュリティ知識を体系的に身につけたい方へ、メルマガで実践的なセキュリティ対策ノウハウをお届けしています。
