【実践シェルスクリプト講座 第3回】「えっ、手動で50人分登録するの!?」面倒なユーザー作成を全自動化しよう
こんにちは!「リナックス先生」です。
前回は、サーバーを守るための「バックアップ」と「通知」の仕組みを構築しました。
これで守りは完璧…と言いたいところですが、コウ君、なんだかお疲れ気味じゃない?
先生…実は、来週から新しいプロジェクトが始まるらしくて、開発メンバー20人分のユーザーアカウントを作成することになったんです。
しかも、「セキュリティのため全員SSH鍵認証にして、秘密鍵を個別に配布してくれ」って言われて…。
ユーザー作って、パスワード設定して、鍵を作って、権限変えて…これを20回繰り返すなんて、指が取れちゃいますよ!(泣)
それは大変ね。でも、エンジニアにとって「単純な繰り返し作業」は最大の敵であり、同時に自動化のチャンスでもあるの。
エクセル(CSV)で作った名簿さえあれば、その作業、スクリプト一つで1秒で終わらせられるわよ。
今回は、シェルスクリプトの真骨頂である「ループ処理」と「テキスト読み込み」をマスターしましょう!
「実践シェルスクリプト講座」第3回のテーマは、インフラエンジニアの業務効率を劇的に改善する「ユーザー管理の自動化」です。while ループを使ってCSVファイルを一行ずつ読み込み、ユーザー作成からSSH鍵の生成・配置までを一気に処理するプロ仕様のスクリプトを作成します。
本講座のカリキュラム(全4回)
本シリーズでは、現場で即使えるレベルの実践的なスクリプトを作成します。
- サーバーの異変を未然に防ぐ!「ディスク容量監視」と「ログローテーション」【完了】
- データ消失の悲劇を防ぐ!「自動バックアップ」と「エラー通知」【完了】
- 【今回】ユーザー管理の効率化:CSVファイルから大量のユーザーとSSH鍵を一括生成する
- セキュリティ監視:不正アクセス(SSH総当たり攻撃)を検知してIPを自動ブロックする
1. 手作業の恐怖と自動化の設計図
まず、コウ君がやろうとしている手作業の手順を書き出してみましょう。
ユーザー1人あたり、これだけのコマンドが必要です。
# 1. ユーザー作成 useradd -m -s /bin/bash tanaka # 2. パスワード設定(対話式で入力が必要) passwd tanaka # 3. .sshディレクトリ作成 mkdir /home/tanaka/.ssh chmod 700 /home/tanaka/.ssh # 4. SSH鍵ペアの生成 ssh-keygen -t rsa -f /home/tanaka/.ssh/id_rsa -N "" # 5. 公開鍵をauthorized_keysに登録 cat /home/tanaka/.ssh/id_rsa.pub > /home/tanaka/.ssh/authorized_keys chmod 600 /home/tanaka/.ssh/authorized_keys # 6. 所有者の変更 chown -R tanaka:tanaka /home/tanaka/.ssh
これを20人分、一度もタイプミスせずに打つ自信はありますか?
途中で誰かの権限設定を間違えてログインできなくなったり、SSH鍵を他人のものと取り違えたりするリスクが非常に高いです。
今回は、「ユーザー名と初期パスワードを書いたCSVファイル」を用意し、それをスクリプトに読み込ませることで、これら全てを自動実行させます。
2. ループ処理の主役「while read」構文
シェルスクリプトでファイルを一行ずつ読み込むには、while read という構文を使います。
これはLinuxの定型文として覚えてしまいましょう。
基本構文
while IFS=, read -r 変数1 変数2 ...; do
# ここに処理を書く
echo "読み込んだ値: $変数1, $変数2"
done < 読み込むファイル名
💡 呪文の解説
IFS=,(Internal Field Separator):
「区切り文字はカンマ(,)ですよ」という宣言です。CSVを読む時は必須です。read -r:
ファイルから一行読み込みます。-rはバックスラッシュを文字として扱うオプションで、安全のために付けます。< ファイル名:
ループの最後に書くことで、指定したファイルの中身をループに流し込みます。
3. 準備:CSVファイルの作成
まずは、ユーザーリストとなる user_list.csv を作成します。
フォーマットは「ユーザー名,初期パスワード」としましょう。
[root@localhost ~]# vi user_list.csv
user_list.csv の中身
tanaka,Pass1234 suzuki,P@ssword5678 sato,Linux2024!
※実務では、パスワードを平文(そのままの文字)でファイルに保存するのはリスクがあります。
作業が終わったらこのCSVファイルは即座に削除するか、後述するパスワード自動生成テクニックを使うのが一般的ですが、今回はわかりやすく「指定したパスワードを設定する」方式で進めます。
4. 実装:一括ユーザー作成スクリプト
それでは、スクリプト create_users.sh を作成していきましょう。
段階を追って機能を積み上げていきます。
Step 1: CSVを読んで表示するだけ(テスト)
まずは正しく読み込めるか確認します。
#!/bin/bash
CSV_FILE="user_list.csv"
# ファイルの存在確認
if [ ! -f "$CSV_FILE" ]; then
echo "エラー: $CSV_FILE が見つかりません。"
exit 1
fi
echo "--- 読み込み開始 ---"
# ループ処理
while IFS=, read -r USERNAME PASSWORD; do
# 空行や、#で始まるコメント行はスキップする
[[ -z "$USERNAME" || "$USERNAME" =~ ^# ]] && continue
echo "ユーザー: $USERNAME / パス: $PASSWORD を処理予定"
done < "$CSV_FILE"
echo "--- 読み込み終了 ---"
実行して、CSVの中身が表示されればOKです。
Step 2: ユーザー作成とパスワード設定の実装
実際に useradd コマンドを組み込みます。
パスワード設定には、対話入力が不要な chpasswd コマンドを使います。
💡 chpasswdコマンドとは?
通常 passwd ユーザー名 だと人間が手入力する必要がありますが、echo "ユーザー名:パスワード" | chpasswd
とすることで、スクリプトから一発でパスワードを設定できます。大量登録の必須コマンドです。
# (ループの中身に追加)
# ユーザーが既に存在しないかチェック
if id "$USERNAME" &>/dev/null; then
echo "[SKIP] $USERNAME は既に存在します。"
else
# ユーザー作成 (-m:ホームディレクトリ作成, -s:シェル指定)
useradd -m -s /bin/bash "$USERNAME"
# パスワード設定
echo "${USERNAME}:${PASSWORD}" | chpasswd
if [ $? -eq 0 ]; then
echo "[OK] $USERNAME を作成しました。"
else
echo "[ERROR] $USERNAME の作成に失敗しました!"
fi
fi
Step 3: SSH鍵の生成と配置(プロ級テクニック)
ここが今回のハイライトです。
ユーザーを作成した直後に、そのユーザー専用のSSH鍵ペア(秘密鍵と公開鍵)をサーバー上で生成し、ログインできるように設定してあげます。
完成したスクリプト create_users_full.sh は以下のようになります。
#!/bin/bash
# ==========================================
# 設定エリア
# ==========================================
CSV_FILE="user_list.csv"
KEY_DIR="generated_keys" # 生成した秘密鍵を集める場所
# root権限チェック
if [[ $EUID -ne 0 ]]; then
echo "エラー: このスクリプトはrootユーザーで実行してください。"
exit 1
fi
# ==========================================
# メイン処理
# ==========================================
# 配布用鍵ディレクトリの作成
mkdir -p "$KEY_DIR"
chmod 700 "$KEY_DIR"
echo "=== ユーザー一括作成処理を開始します ==="
while IFS=, read -r USERNAME PASSWORD; do
# 1. データチェック(空行・コメント行スキップ)
[[ -z "$USERNAME" || "$USERNAME" =~ ^# ]] && continue
# 2. ユーザー存在チェック
if id "$USERNAME" &>/dev/null; then
echo "[SKIP] ユーザー $USERNAME は既に存在します。"
continue
fi
# 3. ユーザー作成
useradd -m -s /bin/bash "$USERNAME"
if [ $? -ne 0 ]; then
echo "[ERROR] $USERNAME の作成に失敗しました。"
continue
fi
# 4. パスワード設定
echo "${USERNAME}:${PASSWORD}" | chpasswd
# 5. SSHディレクトリの準備
USER_HOME="/home/$USERNAME"
SSH_DIR="$USER_HOME/.ssh"
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
# 6. SSH鍵ペアの生成
# -t rsa: 暗号化方式
# -b 2048: 鍵の長さ
# -N "": パスフレーズなし(自動化のため)
# -f: 出力先ファイル名
# -C: コメント(誰の鍵かわかるように)
ssh-keygen -t rsa -b 2048 -N "" -f "$SSH_DIR/id_rsa" -C "Key for $USERNAME" > /dev/null 2>&1
# 7. 公開鍵をauthorized_keysに登録
cat "$SSH_DIR/id_rsa.pub" >> "$SSH_DIR/authorized_keys"
chmod 600 "$SSH_DIR/authorized_keys"
# 8. 権限修正(重要!)
# rootで作ってしまったファイルを、ユーザーの所有に変更する
chown -R "$USERNAME:$USERNAME" "$SSH_DIR"
# 9. 秘密鍵を管理者が回収(配布用)
# ユーザー本人に渡すために、手元のディレクトリにコピーしておく
cp "$SSH_DIR/id_rsa" "$KEY_DIR/${USERNAME}_id_rsa"
echo "[OK] $USERNAME を作成し、SSH鍵(${USERNAME}_id_rsa)を生成しました。"
done < "$CSV_FILE"
echo "=== 全処理完了 ==="
echo "生成された秘密鍵は $KEY_DIR に保存されています。"
echo "各ユーザーに安全な方法で配布してください。"
おおお!
実行したら一瞬で画面が流れて、generated_keys フォルダの中に全員分の秘密鍵ができあがってます!
これなら、あとはこの鍵ファイルを本人にメールかチャットで送るだけで済みますね!
その通り!
ただし、秘密鍵は「家の鍵」と同じくらい重要なものだから、メールで送るときはZipでパスワードをかけたり、社内の安全なファイルサーバー経由で渡したりと、取り扱いには十分注意してね。
そして、使い終わったこのスクリプトとCSVファイルは、必ず削除しておくこと。パスワードが残ったまま放置するのは厳禁よ。
5. パーミッション(権限)の落とし穴
このスクリプトで一番ハマりやすいポイントは、ステップ8の chown(所有者の変更) です。
これを忘れるとどうなると思いますか?
スクリプトは root 権限で実行しているため、作られた .ssh ディレクトリや authorized_keys ファイルの所有者は、デフォルトで root になってしまいます。
すると、ユーザー(例:tanakaさん)がログインしようとした時、「自分の家(ホームディレクトリ)にある鍵ファイルなのに、root様の持ち物だから読み取れない!」という状態になり、SSHログインが拒否されてしまうのです。
SSHのトラブル原因のNo.1は、この「パーミッションと所有権の間違い」です。
自動化スクリプトを書くときは、「誰の権限でファイルが作られるか」を常に意識しましょう。
6. 応用:パスワードを自動生成する場合
「初期パスワードを考えるのも面倒くさい」という場合は、openssl コマンドを使ってランダムな文字列を生成することができます。
CSVファイルのパスワード欄を空にして、スクリプト側で以下のように生成すれば、さらに自動化が進みます。
# ランダムな12文字のパスワードを生成 PASSWORD=$(openssl rand -base64 12) echo "ユーザー: $USERNAME / 自動生成パスワード: $PASSWORD" # 生成したパスワードを別途ファイルに保存して、後で管理者が確認できるようにする echo "$USERNAME,$PASSWORD" >> created_passwords.csv
まとめ:ループ処理を制する者はサーバーを制す
今回は、シェルスクリプトによる「繰り返し処理(ループ)」の実践編として、ユーザー一括作成ツールを作りました。
| 技術要素 | 解説 |
|---|---|
while read |
ファイルを行単位で読み込む基本構文 |
IFS=, |
CSV(カンマ区切り)を正しく分割するための設定 |
chpasswd |
スクリプトから非対話でパスワードを設定するコマンド |
ssh-keygen -N "" |
パスフレーズなしのSSH鍵を自動生成するオプション |
20人のユーザー作成も、1000人のユーザー作成も、このスクリプトがあれば労力は変わりません。
これが「自動化(Automation)」の威力です。
コウ君、これで浮いた時間を使って、もっとクリエイティブな仕事(あるいは休憩)ができそうね!
次回予告:見えない攻撃者との戦い
さて、ユーザーを作成してSSHを開放したということは、外部からのアクセスの入り口が増えたことも意味します。
あなたのサーバーは今この瞬間も、世界中から「総当たり攻撃(ブルートフォースアタック)」を受けているかもしれません。
次回は最終回。
ログをリアルタイムで監視し、何度もログインに失敗してくる怪しいIPアドレスを自動的に検知して、ファイアウォールでブロックする「自動防衛システム」を作成します。
まさに「サーバーの守護神」となるスクリプトを作りましょう!
今回のスクリプト、試すときは間違って自分(今ログインしているユーザー)を上書きしたりしないように、テスト環境で慎重にやってね。
VPSなら、OS再インストール機能を使って、まっさらな状態から試すのが一番の練習になるわよ!
▼スクリプトの実験場に最適!推奨VPS



コメント