chmod -R 777 . や chown -R を誤ったパスに対して実行してしまった、あるいはスクリプトのバグで権限が一括上書きされてしまった——そのような事態での復旧手順を、状況別に解説します。「権限をどう変えるか」ではなく、「壊れた権限をどう元に戻すか」に絞っています。
まず被害の範囲を把握する
復旧作業に入る前に、影響を受けたファイルがどの範囲かを確認します。再設定の方針が決まりやすくなるためです。
現在の権限と所有者の一覧を取得するには次のコマンドで確認できます。
find /対象ディレクトリ -printf "%M %u %g %p\n"
%M は権限を drwxr-xr-x 形式で、%u はユーザー名、%g はグループ名、%p はパスで出力します。ファイル数が多い場合はリダイレクトしてファイルに保存しておくと、後で差分を比較しやすくなります。
find /対象ディレクトリ -printf "%M %u %g %p\n" > /tmp/current_perms.txt
対象がシステムファイルか、Web アプリなどの独自ファイルかによって、この後の復旧方針が異なります。システムファイルはパッケージ管理ツールが正解の情報を持っているため、それを活用するのが最短ルートです。
パッケージ管理ツールでシステムファイルを復旧する
RPM や dpkg でインストールされたシステムファイルの場合、パッケージ管理ツール自体が「正しい権限・所有者」の情報を保持しています。これを使うのが最も確実な復旧方法です。
RPM 系(RHEL・CentOS・AlmaLinux など)
rpm --verify で、パッケージ定義から変更されたファイルを検出できます。
# インストール済み全パッケージを検証し、権限・所有者の差異があるファイルを探す
rpm -Va | grep -E "^.M|^.U|^.G"
出力の先頭文字列のうち M は権限(Mode)の不一致、U はユーザー、G はグループの不一致を示します。
対象パッケージが特定できたら、権限と所有者をパッケージ定義どおりに戻せます。
# 権限(パーミッション)をパッケージ定義に戻す
rpm --setperms パッケージ名
# 所有者・グループをパッケージ定義に戻す
rpm --setugids パッケージ名
ファイルパスからパッケージ名を調べるには次のコマンドが使えます。
rpm -qf /usr/bin/対象ファイル
差異が検出されたすべてのファイルを一括復旧したい場合は、次のようにパッケージ名を列挙して渡す方法があります。実行前に影響範囲を必ず確認してください。
rpm -Va | grep -E "^.M|^.U|^.G" | awk '{print $NF}' \
| xargs -I{} rpm -qf {} 2>/dev/null | sort -u \
| xargs rpm --setperms
rpm -Va | grep -E "^.M|^.U|^.G" | awk '{print $NF}' \
| xargs -I{} rpm -qf {} 2>/dev/null | sort -u \
| xargs rpm --setugids
DEB 系(Debian・Ubuntu など)
dpkg --verify で変更を検出できます。
dpkg --verify | grep -E "^.M|^.U|^.G"
DEB 系には RPM の --setperms に相当するコマンドがないため、パッケージを再インストールすることで正しい権限に戻します。
sudo apt-get install --reinstall パッケージ名
ファイルが所属するパッケージ名は次のコマンドで調べられます。
dpkg -S /usr/bin/対象ファイル
getfacl のバックアップから復旧する
事前に getfacl でバックアップを取っていた場合は、setfacl --restore で権限と所有者をまとめて復元できます。バックアップがあれば最もシンプルな復旧方法です。
バックアップの取り方(次回の事故に備えて):
getfacl -R /対象ディレクトリ > /backup/perms_backup.acl
バックアップからの復元:
setfacl --restore=/backup/perms_backup.acl
setfacl --restore は ACL だけでなく、通常の権限(rwx)と所有者情報も含めて復元します。バックアップファイルの中身はテキスト形式なので、cat で内容を確認してから実行するとより安全です。
バックアップが存在しない場合は、次のセクションで紹介する find コマンドを使った手動復旧に切り替えます。
find コマンドで手動復旧する
バックアップがなく、パッケージ管理でもカバーできない独自ファイル(Web アプリのドキュメントルート、自社スクリプト群など)については、find コマンドでディレクトリと通常ファイルを分けて設定し直します。
想定例として、一般的な Web コンテンツでは「ディレクトリは 755、通常ファイルは 644」が標準的な構成です。
# ディレクトリに 755 を設定
find /var/www/html -type d -exec chmod 755 {} \;
# 通常ファイルに 644 を設定
find /var/www/html -type f -exec chmod 644 {} \;
実行可能スクリプトが混在している場合は、拡張子で絞って個別に権限を付与します。
find /var/www/html -type f -name "*.sh" -exec chmod 755 {} \;
所有者の復旧は chown -R を使います。適用前に対象パスを慎重に確認してください。
chown -R www-data:www-data /var/www/html
ファイル数が多い場合は -exec の代わりに -print0 | xargs -0 を使うと処理が速くなります。
find /var/www/html -type f -print0 | xargs -0 chmod 644
find /var/www/html -type d -print0 | xargs -0 chmod 755
よくあるつまずきと対処
setuid・setgid ビットが消えてしまった
chmod -R は setuid(4000)・setgid(2000)ビットも上書きします。/usr/bin/passwd など setuid が必要なコマンドが正しく動かなくなることがあります。RPM 系は rpm --setperms でまとめて戻せます。DEB 系はパッケージの再インストールが確実です。個別に対処する場合は chmod u+s または chmod g+s で付与できます。
root 以外では chown が実行できない
chown で所有者を変更するには root 権限が必要です。一般ユーザーで実行した場合は「Operation not permitted」エラーになります。sudo を付けて実行してください。
find の対象パスを起点から広げすぎた
find / -exec chmod ... のようにルートから実行すると、想定外のシステムファイルまで変更されます。パスを必ず絞ってから実行し、不安な場合は -exec の前に -print を追加してファイル一覧を確認してから本番実行に切り替えると安全です。
ACL が残っていてアクセス制御が変わらない
chmod で権限を戻しても ACL(アクセス制御リスト)が残っていると、ACL 側のルールが優先されてアクセス制御が変わらない場合があります。getfacl /対象パス で ACL の有無を確認できます。不要なエントリは setfacl -b /対象パス で削除できます。
シンボリックリンク先が想定外に変更される
chmod や chown は、デフォルトではシンボリックリンク先の実体に対して動作します。リンク自体の所有者を変更したい場合は chown -h を使います。find に -L を付けるとリンク先をたどるため、意図せず対象が広がることがあります。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
