【実践シェルスクリプト講座 番外編】プロはここを見る!スクリプトの安全性向上とトラブルシューティング

【実践シェルスクリプト講座 番外編】動かない時はここを見ろ!安全性向上と「ハマりポイント」総まとめ

こんにちは!「リナックス先生」です。
全4回の「実践シェルスクリプト講座」、お疲れ様でした!
コウ君、その後スクリプトを運用していて、何か困ったことは起きてない?

コウ君

先生!実は…手動で動かすと完璧なのに、Cronに登録したら動かなかったり、別のLinuxに入れたら変なエラーが出たりするんです。
あと、第3回で作ったSSH鍵で、なぜかログインできないユーザーがいて…。
僕の書き方が悪いんでしょうか?

リナックス先生

それはスクリプトあるあるね!
プログラミングの世界では「環境の差異」「見落としがちな設定」が原因で動かないことがよくあるの。
今回は番外編として、全4回の記事に対する「補足」と、より安全に運用するための「プロの修正テクニック」を解説するわよ!

本記事は、これまでの講座(全4回)で作成したスクリプトを、より安全に、より確実に動作させるための補足・修正記事です。
特に「SELinux」や「Cronのパス問題」など、現場で必ず直面する壁の乗り越え方を学びましょう。

講座アーカイブ

各回の記事はこちらから確認できます。

  1. 第1回:ディスク容量監視とログローテーション
  2. 第2回:自動バックアップと通知システム
  3. 第3回:ユーザー一括作成とSSH鍵配布
  4. 第4回:SSH総当たり攻撃の自動ブロック

共通の落とし穴:Cronで動かない時の「パス問題」

現象:
手動で ./script.sh と叩くと動くのに、Cronに登録すると動かない、または一部のコマンドだけ失敗する。

原因:
Cronが実行される時は、環境変数 $PATH が最小限しか設定されていません。
そのため、普段使えているコマンド(例えば rsyncfirewall-cmd)が見つからないことがあります。

【対策】絶対パスで書くか、PATHを定義する

スクリプトの冒頭で、環境変数を明示的に読み込ませるのが一番確実です。

#!/bin/bash

# 方法1: PATHを通す(推奨)
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

# 方法2: コマンドを全て絶対パスで書く(面倒だが確実)
# rsync -> /usr/bin/rsync
# firewall-cmd -> /usr/bin/firewall-cmd

コマンドの場所がわからないときは、which コマンド名(例:which rsync)で調べることができます。


第1回(ログローテーション)の補足・修正

修正:空変数の恐怖と「set -u」

第1回のログローテーションスクリプトで、find コマンドを使って古いログを削除しました。
もし、設定ミスで LOG_DIR 変数が空っぽだったらどうなるでしょうか?

LOG_DIR=""
cd "$LOG_DIR"  # 空なので移動せず、カレントディレクトリに留まる
find . -name "*.gz" -delete # カレントディレクトリ(例えば /root)のファイルを消し始める!

これは大惨事を招きます。
これを防ぐために、スクリプトの冒頭に set -u を入れる習慣をつけましょう。

#!/bin/bash
set -e # エラーで停止
set -u # 未定義の変数を使おうとしたらエラーで停止

LOG_DIR="/var/log/myapp"
# ...以下略

set -u があれば、万が一変数が空だった場合に「unbound variable」というエラーが出て、削除コマンドが実行される前に止まってくれます。


第2回(バックアップ)の補足・修正

補足:tarの「-P」オプションの危険性

記事中で、バックアップ時に「絶対パスを保持する -P オプション」を使用しました。
これは便利な反面、リストア(解凍)時に注意が必要です。

# -P つきで圧縮されたファイルを、ルートディレクトリ(/)で解凍すると...
cd /
tar -xzvf backup.tar.gz
# いきなり本番環境のファイル (/var/www/html/...) が上書きされてしまう!

安全なリストア方法:
不安な場合は、特定のディレクトリに展開するように -C オプションを指定しましょう。

mkdir /tmp/restore_work
tar -xzvf backup.tar.gz -C /tmp/restore_work

第3回(ユーザー作成)の補足・修正

重要:RHEL/CentOS/AlmaLinuxでの「SELinux」の罠

第3回のスクリプトで、.ssh ディレクトリや authorized_keys を作成し、権限(chmod/chown)も完璧に設定したのに、「なぜかSSHログインできない」という現象が起きることがあります。

その犯人は、RHEL系OSの強力なセキュリティ機能 SELinux である可能性が高いです。
手動で作成したファイルには、SELinuxの正しい「コンテキスト(ラベル)」が付与されていないため、SSHデーモンが読み込みを拒否するのです。

【対策】restorecon コマンドの追加

スクリプトの最後(chownの後あたり)に、以下のコマンドを追加してください。

    # 8. 権限修正
    chown -R "$USERNAME:$USERNAME" "$SSH_DIR"

    # 【追加】SELinuxのコンテキストを修復する
    if command -v restorecon &> /dev/null; then
        restorecon -R -v "$SSH_DIR"
        echo "[SELinux] $SSH_DIR のコンテキストを修正しました。"
    fi

restorecon コマンドは、ファイルのある場所(パス)に応じて、本来あるべき正しいSELinuxラベルを貼り直してくれます。
これを知っているかどうかで、トラブルシューティングにかかる時間が数時間変わります!


第4回(SSH攻撃ブロック)の補足・修正

修正:ログフォーマットのOS差分

第4回では、awk '{print $(NF-3)}' を使ってIPアドレスを抜き出しました。
しかし、OSの設定やバージョンによって、ログの形式は微妙に異なります。

パターンA (IPのみ): from 192.168.1.1 port...
パターンB (ホスト名あり): from bad-host.com [192.168.1.1] port...

パターンBの場合、$(NF-3) ではIPではなくホスト名が取れてしまったり、ずれたりする可能性があります。
より確実に行うには、「正規表現でIPアドレスを抜き出す」方法が安全です。

【改善版】IP抽出コマンド

grep -oE (Extended Regexでマッチした部分だけ出力) を使います。

# 修正前
... | awk '{print $(NF-3)}' | ...

# 修正後:行の中からIPアドレスっぽい文字列(数字.数字.数字.数字)だけを無理やり引っこ抜く
... | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" | ...

これなら、ログの文言が多少変わっても、確実にIPアドレスだけを集計できます。

補足:firewalldの「即時反映」と「永続化」

記事中のコードで、同じコマンドを2回打っている箇所がありました。

firewall-cmd --zone=drop --add-source="$IP"             # (1) 今すぐ有効にする
firewall-cmd --permanent --zone=drop --add-source="$IP" # (2) 再起動後も有効にする

これにはちゃんとした理由があります。
--permanent だけを打って firewall-cmd --reload すると、一瞬ファイアウォールが再読み込みされ、通信が途切れるリスクがあります。
攻撃をブロックするたびにリロードするのは負荷が高いため、「メモリ上(即時)に追加」「設定ファイル(永続)に追加」を別々に行うのが、無停止運用の鉄則なのです。


まとめ:失敗こそが一番の教科書

今回の番外編では、スクリプトをより実践的にするための「泥臭い」知識を紹介しました。

対象 ポイント プロの処方箋
全体 Cronで動かない export PATH=... を書く
全体 変数が空で事故る set -u を冒頭に書く
ユーザー作成 SSHログインできない restorecon でSELinuxを修正
セキュリティ IP抽出がずれる grep -oE でIPパターン抽出
コウ君

なるほど…!特にSELinuxの話は目からウロコでした。
「権限は合ってるのになぜ?」って3時間くらい悩んだ経験があります…。
スクリプトって、書いて終わりじゃなくて、育てていくものなんですね!

リナックス先生

その通り!
エラーが出たらラッキーだと思いなさい。それはシステムが「ここがおかしいよ」と教えてくれているメッセージなんだから。
今回学んだテクニックを、第1回〜第4回のスクリプトに組み込んで、自分だけの「最強ツール」を作り上げてみてね!

これで本当に「実践シェルスクリプト講座」は完結です。
あなたのサーバーエンジニアとしての旅が、トラブル少なく、楽しいものになることを祈っています!

▼安全に実験するなら、壊してもすぐ直せるVPSで!

【2026年最新】Linuxサーバー構築におすすめのVPS比較3選!現役エンジニアが速度とコスパで厳選
Linuxの勉強、まだ「自分のPC」でやって消耗していませんか?「Linuxを覚えたいけど、環境構築でエラーが出て先に進めない…」「VirtualBoxを入れたらパソコンが重くなった…」これは、Linux学習を始める9割の人がぶつかる壁です...

コメント