
ファイルパーミッションの見直し|777を安全に直す順番と勘所
「管理画面から画像をアップロードすると、エラーになる」 「キャッシュのフォルダに書き込めなくて、真っ白な画面が出る」 「深夜のリリースで、バッチがログを吐けずに止まった」
——そういう夜に、chmod 777 で通したこと、ありませんか。
あるなら、それはたぶん正しい判断でした。障害を止めるのが最優先で、原因を突き止める時間はなくて、ひとまず動かすことが仕事だった。あの夜の777は、システムを止めなかった手当てです。そこは責める話ではありません。
ただ、応急処置は自分から元に戻ってはくれません。数か月後に一覧を眺めると、あのときの777が、まだそのまま残っている。ここでは、その777を安全に直す順番を一緒に見ていきます。難しい話にはしません。数字の読み方さえ分かれば、あとは順番の問題です。
結論:直す順番はこうです。①いまの権限を一覧で「見るだけ」→ ②誰(どのユーザー)で動いているかを確かめる → ③「書き込みが要るか」だけで数字を決める → ④所有者を先に合わせ、それから数字を戻す → ⑤また777が要らないように、1か所だけ手を入れる。いちばんの勘所は、数字を先に決めないこと。「そのファイルを、どのユーザーが読んで、どのユーザーが書くのか」が決まれば、数字は自動的に決まります。順番が逆だと、直したそばからまた777に戻ります。
なお、実行ユーザーの名前も、必要な権限も、環境(自社サーバー・レンタルサーバー・クラウド・コンテナ・保守委託の範囲)でかなり変わります。本文は一般的な進め方の一例です。コマンドは本番で実行する前に、検証環境と公式ドキュメントで挙動を確認してください。共用のレンタルサーバーなど裁量が限られる場合は、契約先の窓口に相談しながら進めるのが安全です。
何が起きているか:777は「知識不足」ではなく「情報不足」の結果
まず、777がなぜ生まれるのかを整理しておきます。ここを飛ばすと、直しても同じことが起きます。
Linuxのパーミッション(権限)は、「誰が」×「何をできるか」の掛け算でできています。「誰が」は3つの立場に分かれます。ファイルの所有者、そのファイルのグループに属する人、そしてその他の全員です。「何をできるか」も3つで、読む・書く・実行する。この3×3を数字で書いたものが 755 や 644 です。
つまり777は、「3つの立場すべてに、3つの権限すべてを与えた状態」です。
では、なぜ777にしてしまうのか。多くの場合、Webサーバーやバッチが「どのユーザーで動いているか」が分からなかったからです。
www-data なのか apache なのか nginx なのか。PHPは Apache と同じユーザーで動いているのか、php-fpm の別ユーザーなのか。cronは誰で回っているのか。——障害の最中に、それを調べる余裕はありません。だから「全員に許可」で通す。知識が足りなかったのではなく、その瞬間に手元に情報がなかった、というだけの話です。
そして777のまま残ると、少し困ることが起きます。
- そのサーバーで動いているすべてのプロセスが、そのファイルを書き換えられます。同居している別のサイトや、脆弱性を突かれた別のプログラムも含みます
- ディレクトリが777だと、中のファイルを自分が作っていなくても消せます。あとで「ファイルが消えた、誰も触っていないのに」となる原因のひとつです
- レンタルサーバーによっては、777のファイルやディレクトリをサーバー側が拒否する設定になっていて、そもそも動きません
これは「777にしたのが間違い」という話ではありません。応急処置のまま平常運転に入ってしまった、という、どの現場でも起きることです。
数字の読み方:覚えるのは3つだけ

3桁の数字は、左から所有者・グループ・その他の順です。それぞれの桁が、その立場に与える権限を表します。
| 数字 | 意味 |
|---|---|
| 4 | 読む(r) |
| 2 | 書く(w) |
| 1 | 実行する(x) |
足し算するだけです。4+2=6 なら「読み書きできる」、4+1=5 なら「読めるし実行できるが、書けない」、7 は全部。
よく出てくる組み合わせを並べると、こうなります。
644(rw-r--r--)… 所有者だけが書ける。他は読むだけ。普通のファイルの基本形755(rwxr-xr-x)… 所有者だけが書ける。他は読めて、入れる/実行できる。ディレクトリとスクリプトの基本形600(rw-------)… 所有者以外は読むことすらできない。鍵や認証情報を置くファイル777(rwxrwxrwx)… 全員が何でもできる
ここでひとつ、勘所があります。
ディレクトリの「x」は、プログラムを実行するという意味ではありません。「その中に入る」という意味です。 ディレクトリから x を外すと、中のファイルがどんな権限でも開けなくなります。「644にしておけば安全だろう」とディレクトリまで644にしてしまうと、サイトが動かなくなります。ディレクトリは755、ファイルは644。ここを分けて考えるだけで、事故がかなり減ります。
見直しの手順(消さない・止めない・戻せる)
① いまの権限を一覧で「見るだけ」
最初の日は、何も変えません。眺めるだけです。
# 対象は自分の環境に置き換える
DOCROOT=/var/www/html
# 誰でも書ける状態のもの(777 や 666 など)を洗い出す
find "$DOCROOT" -maxdepth 4 -perm -o+w -printf '%m %u:%g %p\n' | sort
# ディレクトリとファイルを分けて、権限の分布を見る
find "$DOCROOT" -maxdepth 4 -type d -printf '%m\n' | sort | uniq -c | sort -rn
find "$DOCROOT" -maxdepth 4 -type f -printf '%m\n' | sort | uniq -c | sort -rn
-perm -o+w は「その他の人が書ける」ものだけを拾う書き方です。-printf が使えない環境(BSD系の find など)では、末尾を -ls に置き換えれば同じような情報が出ます。1ファイルだけ見たいときは stat -c '%a %U:%G %n' ファイル名 が手軽です。
分布を見ると、たいてい傾向が見えます。「アップロード用のディレクトリだけ777」なら話は早い。「全部まとめて777」なら、過去に一括で当てた形跡です。どちらでも大丈夫です。今日は数を把握するだけで十分です。
② 誰で動いているかを確かめる
ここが本命です。数字より先に、ユーザーを確定させます。
# Webサーバー・PHPがどのユーザーで動いているか
ps -eo user,comm | grep -E 'httpd|apache2|nginx|php-fpm' | sort -u
# cronの実行ユーザー(root配下と、ユーザー個別の両方)
sudo crontab -l
crontab -l
ps の結果には root の行も混ざりますが、これは待ち受け役の親プロセスです。実際にファイルを読み書きするのは、その下にいる子プロセスのユーザー(www-data apache nginx など)だと思ってください。php-fpm を使っている場合は、プール設定ファイルの user / group が実際の書き手です。
分かったら、その場でメモに残します。 運用ドキュメントに次の3行を書くだけで、次に同じ夜が来たとき、777に頼らずに済みます。
- Webサーバーの実行ユーザー:(例)www-data
- PHPの実行ユーザー:(例)www-data
- バッチの実行ユーザー:(例)deploy
③ 「書き込みが要るか」だけで数字を決める
ユーザーが分かれば、判断はとても単純になります。そのファイルに、Webサーバーが書く必要があるか。それだけです。
| 対象 | 書き込み | 目安 |
|---|---|---|
プログラム本体(.php .html .css など) | 不要 | ファイル 644 / ディレクトリ 755 |
| アップロード先・キャッシュ・ログの置き場 | 必要 | 所有者かグループをWebサーバー側に合わせたうえで 755(または 775) |
| シェルスクリプト・実行するファイル | 不要 | 755 |
| 設定ファイル・鍵・認証情報 | 不要 | 600(または 640) |
大事なのは、書き込みが必要な場所で数字を上げるのではなく、所有者を合わせるという発想です。所有者がWebサーバーのユーザーになっていれば、755 のままでも書けます。777が要る場面は、思っているより多くありません。
もうひとつ、アップロード先については覚えておくと安心な点があります。アップロードされたファイルが、プログラムとして実行されない場所に置くという考え方です。公開ディレクトリの外に置く、あるいはサーバー設定でその配下の実行を止める。書き込み権限そのものより、こちらのほうが効いてきます(設定の書き方は環境ごとに異なるので、公式ドキュメントを確認してから本番へ)。
④ 所有者を先に合わせ、それから数字を戻す
いよいよ直しますが、順番があります。先に数字を下げると、その瞬間に書けなくなって障害になります。 所有者を合わせるのが先です。
そして、始める前に戻せる状態を作っておきます。
# 1) 現状を控える(これが戻し方の元になる)
find /var/www/html -printf '%m %u:%g %p\n' > ~/perm-backup-2026-08-21.txt
# 2) 所有者・グループを合わせる(対象ディレクトリを1つずつ)
sudo chown -R www-data:www-data /var/www/html/uploads
# 3) それから数字を戻す(ディレクトリとファイルを分けて当てる)
sudo find /var/www/html/uploads -type d -exec chmod 755 {} +
sudo find /var/www/html/uploads -type f -exec chmod 644 {} +
3つ目の書き方がポイントです。chmod -R 755 を丸ごと当てると、ファイルにまで実行権が付きます。ディレクトリは755、ファイルは644。find で -type を分けて当てれば、この取り違えは起きません。
作業の進め方としては、
- 1回に1ディレクトリだけ。全体に一括で当てない
- 当てたら、その機能を実際に触って確認する(アップロードしてみる、画面を開いてみる)
- アクセスの少ない時間帯に、戻せる手が空いている状態でやる
- 何を・いつ・どこに当てたかを、変更管理の記録に1行残す
もし直したあとに書き込みエラーが出たら、控えた一覧を見て元の値に戻せば済みます。全体を一気にやらないのは、この「戻す」を現実的なサイズに保つためです。
なお、RHEL系(Rocky Linux・AlmaLinux・RHELなど)でSELinuxが有効な環境では、パーミッションを正しくしても書き込めないことがあります。権限とは別に「ラベル(コンテキスト)」という仕組みが働いているためです。ls -Z でラベルを確認し、必要なら restorecon で復元します。心当たりがあるときは、権限だけを疑って深追いしないほうが早く済みます。
⑤ また777が要らないように、1か所だけ手を入れる
直しても、次のリリースでまた777が生えてくることがあります。生えてくる元をひとつだけ塞ぎましょう。全部やらなくて大丈夫です。
- 手順書に1行足す:リリース手順書の最後に「権限を変更したなら、変更管理に記録したか」を追加する
- umaskを確認する:新しく作られるファイルの既定の権限を決めている値です。
umaskと打つと出ます。022なら新規ファイルは644・ディレクトリは755になります。ここが緩いと、作るそばから緩い権限が増えます - デプロイ側で決めてしまう:デプロイのスクリプトやツールに、所有者と権限を明示的に指定する行を1つ入れておく
- アップロード先を1か所にまとめる:書き込みが必要な場所が散らばっているほど、777の誘惑が増えます
ひとつ目の「手順書に1行」だけでも、来年の自分は助かります。
おまけ:一度だけ見ておきたい2つ
頻繁にやることではありませんが、一度見ておくと安心なものが2つあります。
# 所有者の権限で実行される設定(setuid/setgid)が付いたファイル
sudo find /usr /opt /home /var/www -xdev -perm /6000 -type f -ls 2>/dev/null
# 全員が書けるディレクトリのうち、sticky bit が付いていないもの
sudo find /var/www -xdev -type d -perm -0002 ! -perm -1000 -ls 2>/dev/null
前者は、OSの標準コマンド(sudo や passwd など)にも正しく付いているものなので、出てきたからといって消さないでください。見るのは「身に覚えのない場所に付いていないか」だけです。後者の sticky bit は、/tmp のように全員が書ける場所で「他人のファイルは消せない」ようにする仕組みです。共有の作業ディレクトリを自分で作ったときは、付けておくと安心です。
どちらも今日でなくて構いません。余裕のある日に、眺めるだけで十分です。
明日やること
明日30分だけ取れそうなら、この4つでちょうど収まります。
find ... -perm -o+wを1本流して、誰でも書ける場所の数を数える(この日は変えない)ps -eo user,comm | grepで、Webサーバーとバッチの実行ユーザーを確かめる- その3つのユーザー名を、運用ドキュメントに3行書く(次の夜、777に頼らずに済みます)
find ... -printf '%m %u:%g %p\n'で現状の一覧をファイルに控える(直す日の保険になります)
数が多くても、落ち込まなくて大丈夫です。長く動いているシステムほど、応急処置の跡は積み重なります。それは、そのたびに誰かが止めずに乗り切ってきたということです。
今日のチェックリスト
- 3桁の数字が「所有者・グループ・その他」の順であることを説明できる
- ディレクトリの
xが「中に入る」の意味だと分かっている - 誰でも書ける状態(
-perm -o+w)のファイル・ディレクトリを一覧で確認した - Webサーバー/PHPの実行ユーザーを確かめて、運用ドキュメントに書いた
- バッチ(cron)の実行ユーザーを確かめた
- 書き込みが必要な場所を洗い出し、「所有者を合わせる」で足りるか検討した
- 直す前に、現状の権限一覧をファイルに控えた
-
chmod -Rを一括で当てず、ディレクトリ755/ファイル644を分けて当てた - 1ディレクトリ直すごとに、その機能を実際に触って確認した
- 設定ファイルや鍵が
600相当になっているか確認した - 変更した内容を、変更管理の記録に1行残した
-
umaskの値を確認し、必要なら手順書に1行足した

777は、手抜きの印ではありません。動かないシステムを、その夜のうちに動かした跡です。あの手当てがなければ、朝の業務は止まっていました。今日その1か所を、所有者を合わせて数字を戻せたなら、それは過去の自分の仕事を、ちゃんと引き継いだということです。全部をきれいにしなくて大丈夫。次に「書き込めない」に出会ったとき、chmod 777 の前に ps を一度打てる自分になっていれば、この見直しはもう成功しています。
よければ、こちらも
- 公開ディレクトリの置きっぱなしファイル棚卸し|外から見えていないか
- パスワードとAPIキーの平文放置をなくす|一人運用の保管手順
- SSHを安全にする基本|鍵認証とrootログイン禁止の始め方
- 変更管理台帳の付け方|いつ・誰が・何を変えたか残す
保守運用の実務ヒントを、メールでお届けしています。よかったら受け取ってください。