drwxr-xr-xの意味と755をわかりやすく解説
Linuxのdrwxr-xr-xを1文字ずつ読み解き、8進数755への変換を説明します。ディレクトリのxが通過を意味する理由と、chmod 777が適切な解決策でない理由もわかります。
drwxr-xr-x の意味
drwxr-xr-x は、所有者が変更でき、その他のユーザーは変更せずに読み取りと通過ができるディレクトリを表します。このモードは 8 進数では 755 です。Linux は ls -l の出力の各行の先頭に、この 10 文字を表示します。文字は常に同じ順序で同じ意味を持つため、1 つ覚えればすべて理解できます。
まず、他のルールより先に確認すべき点があります。自分で行うテスト結果に意味があるかどうかを左右するためです。root ユーザーは権限ビットを無視します。カーネルは root に CAP_DAC_OVERRIDE capability(任意アクセス制御の上書き)を付与するため、モードで禁止されているファイルも root は開けます。このページの例は、ビットの設定にかかわらず root ではすべて成功します。ルールがどのように適用されるかを確認するときは、通常のユーザーでログインしてください。
10 文字を 1 文字ずつ確認する
確認用のディレクトリとファイルを作成します。ここで行う操作が新しいディレクトリの外部に影響することはありません。
mkdir -p ~/permdemo/inner
printf 'hello\n' > ~/permdemo/inner/notes.txt
ls -ld ~/permdemo ~/permdemo/inner ~/permdemo/inner/notes.txt一般的なデフォルトの umask 022 では、2 つのディレクトリの行は drwxr-xr-x で始まり、ファイルの行は -rw-r--r-- で始まります。
1 文字目は権限ではなく、ファイル種別です。d はディレクトリです。- は通常のファイルです。l はシンボリックリンクです。c と b はキャラクタデバイスとブロックデバイスのノードです。s はソケット、p は名前付きパイプです。この文字は 8 進数の値には含まれません。そのため、drwxr-xr-x は d で始まる値ではなく、755 になります。
その後ろの 9 文字は 3 文字ずつの 3 グループに分かれており、順序は変わりません。
- 2 文字目から 4 文字目までは 所有者 の 3 文字です。ファイルを所有するユーザーに適用されるビットを示します。
- 5 文字目から 7 文字目までは グループ の 3 文字です。ファイルのグループに適用されるビットを示します。
- 8 文字目から 10 文字目までは その他 の 3 文字です。それ以外のすべてのユーザーに適用されるビットを示します。
各 3 文字の位置は常に r、w、x の順です。ハイフンはそのビットが無効であることを示します。各文字の位置が入れ替わることはありません。r-x は読み取りのみを示します。-w- は読み取りなしの書き込みを示します。この設定は可能ですが、一般的ではありません。
したがって、drwxr-xr-x は次のように分解できます。d がディレクトリ、rwx が所有者、r-x がグループ、r-x がその他を示します。
システムによっては 11 文字目が表示されます。末尾のドットである drwxr-xr-x. は、そのファイルに SELinux(security enhanced Linux)のコンテキストが付いていることを示します。Fedora や Rocky などの SELinux ディストリビューションでは、デフォルトで表示されます。末尾のプラス記号である drwxr-xr-x+ は、そのファイルに POSIX ACL(access control list)が付いていることを示します。これは、9 個のビットに加えて適用される追加のルールです。getfacl <path> で追加のルールを確認できます。
ディレクトリでは r、w、x が異なる役割を持ちます
これは、初心者が最初に間違えやすいルールです。ファイルとディレクトリでは同じ文字を使いますが、付与される権限は異なります。
- ファイルの
rは内容を読み取ります。ディレクトリのrは内部の名前を一覧表示します。通常のlsに必要なのはこの権限です。 - ファイルの
wは内容を変更します。ディレクトリのwは、その中のエントリを追加・削除します。ファイルの削除はディレクトリへの変更なので、決め手になるのはディレクトリの write 権限です。ファイル自体のモードは関係ありません。 - ファイルの
xは、ファイルをプログラムとして実行します。ディレクトリのxは、ディレクトリを通過します。つまり、パス検索中にカーネルが内部の名前を解決できるようにします。
通過の仕組みは、分かりにくい部分です。ディレクトリの x は何も実行しません。/srv/site/index.html を開くには、まず x が / に必要です。次に x が /srv に必要で、続いて x が /srv/site に必要です。最後に、ファイルに r が必要です。その経路上のいずれかのディレクトリで、ユーザーに対する x が不足していると、そこで検索が停止します。この場合、末尾のファイルが誰でも読み取れる状態でも、呼び出し元にはパス全体について Permission denied が返されます。namei -l /srv/site/index.html は経路上の各段階を、モードと所有者とともに表示します。どの箇所で停止しているかを確認できます。
r があり、x がないディレクトリは、認識しておくべき特殊な中間状態です。通常のユーザーは名前を一覧表示できます。これは r が付与する権限です。ただし、各エントリの stat 情報は取得できません。そのため ls -l はサイズ列とモード列を疑問符で埋め、各エントリについて ls: cannot access ...: Permission denied を表示します。
文字を 755 に変換する
各 3 文字の組は、3 ビットの数値です。r は 4、w は 2、x は 1 を表します。オンになっているビットを合計します。
rwxは 4 + 2 + 1 = 7 ですrw-は 4 + 2 = 6 ですr-xは 4 + 1 = 5 ですr--は 4 です---は 0 です
したがって、drwxr-xr-x は所有者が 7、グループが 5、その他が 5 で、755 になります。-rw-r--r-- は 6、4、4 で、644 です。drwxrwxr-x は 7、7、5 で、グループに書き込み権限を追加した 755 に相当する 775 です。stat は両方の形式を同時に表示するため、文字を手作業で数える必要はありません。
stat -c '%A %a %U %G %n' ~/permdemo ~/permdemo/inner/notes.txt%A は文字形式、%a は 8 進数形式、%U と %G は所有ユーザーと所有グループを示します。
実際のサーバーでよく使うパーミッション文字列
実際のサーバーで使用するモードを、8 進数の値と用途とともに示します。
-rw-r--r--は 644 です。サービスが読み取るだけの通常ファイルで、設定ファイルや HTML ページなどが該当します。-rw-------は 600 です。SSH 秘密鍵や、アプリケーションの.envファイルなどの Secret に使用します。-rw-rw-r--は 664 です。グループで共有するディレクトリ内のファイルで、チームメンバーによる書き込みが必要な場合に使用します。-rwxr-xr-xは 755 です。/usr/local/bin/backup.shや、ほとんどの/usr/binなどのスクリプトやバイナリに使用します。-rwx------は 700 です。所有者だけが実行できる非公開スクリプトに使用します。drwxr-xr-xは 755 です。ほぼすべてのシステムディレクトリや、Web サイトのドキュメントルートに使用します。drwx------は 700 です。~/.sshや、アクセスを厳しく制限した環境のホームディレクトリに使用します。drwxrwxr-xは 775 です。所有者のグループが書き込めるディレクトリに使用します。drwxrwsr-xは 2775 です。drwxrwxr-xと同じですが、setgid ビットも設定されるため、内部に新しく作成したファイルはディレクトリのグループを継承します。drwxrwxrwtは 1777 です。/tmp。末尾のtは sticky bit であり、ユーザーは自分のファイルだけを削除できます。-rwsr-xr-xは 4755 です。所有者の権限で実行される setuid バイナリに使用し、/usr/bin/passwdや/usr/bin/sudoなどが該当します。-rw-rw-rw-は 666、drwxrwxrwxは 777 です。全ユーザーが書き込める状態であり、サーバーではほぼ常に設定ミスです。lrwxrwxrwxは、すべてのシンボリックリンクに表示される値です。Linux はリンクのモードビットを無視し、リンク先を確認するため、この文字列自体にはまったく意味がありません。
自分に適用される3つ組
初心者が間違えやすい2つ目のルールです。kernel は3つ組を必ず1つだけ選び、そこで判定を終了します。
ユーザー ID がファイルの所有者と一致する場合は、所有者の3つ組が適用されます。group と other のビットは確認されません。それ以外で、ファイルの group が自分の所属する group の1つである場合は、group の3つ組が適用されます。それ以外の場合は、other の3つ組が適用されます。
ここから2つの点が分かります。所有者の3つ組は、それが最も制限の厳しい設定でも適用されます。モードが 0466 のファイルは -r--rw-rw- と表示されます。この場合、所有者には読み取りだけが許可され、他の全員には書き込みが許可されます。最初に所有者であることが一致し、その後のビットは確認されないためです。これは正しい動作ですが、初めて見ると混乱しやすい点です。
group の3つ組を選ぶ基準は、所属する group の一覧ではなく、ファイルの group です。ls -l は各行に2つの名前を表示します。最初が所有者、2つ目が group です。そのファイルに対して有効なのは、2つ目の group だけです。20個の group に所属していても、ファイルの group がそのいずれかである場合にだけ意味があります。
id
stat -c '%U %G %A %n' ~/permdemo/inner/notes.txtid は、自分のユーザーと所属するすべての group を表示します。stat は、ファイルの所有者と group を表示します。両者を比較すれば、kernel が自分に適用する3つ組が分かります。
このため、共有ディレクトリには通常、group と setgid ビットを設定します。sudo chmod 2775 /srv/shared は drwxrwsr-x と表示されます。このディレクトリ内で作成したファイルは、作成者個人の group ではなく、ディレクトリの group を継承します。新しいサブディレクトリも setgid ビットを継承します。setgid が設定するのは group であり、モードではありません。デフォルトの umask が 022 の場合、新しいファイルのモードは 644 になるため、チームメンバーは読み取れますが、書き込めません。group の書き込みを許可するには、そこで作業する全員の umask を 002 にするか、ディレクトリに default ACL を設定します。default ACL は、その中で作成されるファイルに対して umask の代わりに適用されます。各サービスに専用のアカウントを割り当てることも、この問題の重要な対策です。詳しくは VPS 上でサービスごとに Linux ユーザーを1つ割り当てる で説明します。
umask は新しい各ファイルのモードを決める
新しいファイルのモードは、ユーザーが直接決めるものではありません。作成したプログラムが要求したモードから、umask がクリアするビットを除いたものになります。umask は削除するビットのマスクです。そのため、umask の値が大きいほど、より限定されたファイルが作成されます。
多くのディストリビューションでは 022 が設定されています。通常のファイルを作成するプログラムは、通常 0666 を要求します。ディレクトリを作成するプログラムは、通常 0777 を要求します。umask はどちらの要求からも 022 をクリアするため、ファイルは 644、ディレクトリは 755 になります。これは、新しい VPS で広く見られる組み合わせです。
umask
umask -S
touch ~/permdemo/new.txt && mkdir -p ~/permdemo/newdir
ls -ld ~/permdemo/new.txt ~/permdemo/newdirumask -S は同じ値を文字で表示するため、0022 より読みやすくなります。より厳しいデフォルトにするには、~/.profile で umask 027 を設定します。ファイルは 640、ディレクトリは 750 になります。これにより、グループは作業内容を読み取れますが、それ以外のユーザーはアクセスできません。これらの結果は、通常の 0666 と 0777 の要求を前提としています。
重要な制限が 2 つあります。umask でできるのはビットをクリアすることだけで、追加することはできません。touch が要求する 0666 のファイルは、どのような値を設定しても実行可能にはなりません。また、所有者だけのアクセスを要求するプログラムは、その設定を維持します。mktemp は、umask が 022 でも 027 でも、ファイルを 600、ディレクトリを 700 で作成します。さらに、systemd サービスはシェルのプロファイルを読み込まないため、値は unit ファイルで設定してください。
[Service]
UMask=0027umask を完全に無視するケースが 1 つあります。親ディレクトリに default ACL がある場合、umask は無視され、新しいファイルの権限ビットは継承された ACL から決まります。
Web ファイルが 644 で、Web ディレクトリが 755 である理由
Web サーバーは専用のアカウントで実行されます。Debian と Ubuntu では www-data、Rocky と Alma では nginx です。このプロセスには、配信するファイルへの読み取り権限と、その上位にあるディレクトリを通過する権限が必要です。書き込み権限は必要ありません。静的サイトでは、Web サーバーに書き込みを許可してはなりません。
ファイルを 644 にすると、所有者には書き込み権限を与え、全員に読み取り権限を与えます。そのため、deploy user は公開でき、web user は配信できます。ディレクトリを 755 にすると、所有者には書き込み権限を与え、全員に通過権限を与えます。そのため、web user はパスをたどれますが、ファイルやディレクトリを追加・削除することはできません。アプリケーションのバグが、配信中のページを書き換えることもありません。
通過権限の規則が問題になるのは、まさにこの部分です。サイトが /home/deploy/site にあり、/home/deploy が 750 で、web user がそのディレクトリのグループに所属していない場合、web user は home directory に入れません。その結果、リクエストは HTTP 403 で終了し、/var/log/nginx/error.log には次のような行が記録されます。
open() "/home/deploy/site/index.html" failed (13: Permission denied), client: 203.0.113.5この 13 は EACCES、つまり kernel が権限を拒否したことを示します。ネットワークに問題があるわけではありません。ポートは listening 状態で、リクエストも到着しています。Linux で listening ポートがどのように動作するかを学んでいる途中では、この点が分かりにくくなります。namei -l /home/deploy/site/index.html を実行し、チェーンを下へたどって、x が other に設定されていない最初のディレクトリを確認します。
upload path など、アプリケーションが書き込むディレクトリは例外です。モードを広げるのではなく、所有権で書き込みを許可します。sudo chown -R www-data:www-data /srv/site/uploads を設定し、モードは 755 のままにします。書き込み権限は、必要な 1 つのディレクトリだけに限定してください。
chmod でディレクトリツリー全体の権限を一律に変更しない
chmod には 2 つの形式があります。8 進数形式では 9 つのビットを一度に設定します: chmod 644 notes.txt。シンボリック形式では指定した部分だけを変更し、それ以外はそのままにします: chmod u+x deploy.sh は所有者に実行権限を追加し、chmod go-w notes.txt は group と other から書き込み権限を削除します。
再帰処理では、ディレクトリツリーを壊さないように注意が必要です。chmod -R 755 . を使うと、すべての画像ファイルと設定ファイルに実行権限が設定されます。chmod にはスクリプトと JPEG を区別できないためです。代わりに大文字の X を使用してください。
chmod -R u=rwX,go=rX ~/permdemo
stat -c '%a %n' ~/permdemo ~/permdemo/inner/notes.txt大文字の X は、ディレクトリと、どこかのクラスに実行ビットがすでに設定されているファイルに実行権限を適用します。ディレクトリは 755、通常のファイルは 644 になり、すでに実行可能だったスクリプトはその状態を維持します。信頼できるモードのファイルが 1 つある場合は、chmod --reference=good.sh other.sh でそのモードを他のファイルにコピーできます。
ビットに問題がある場合に表示されるメッセージ
bash: ./deploy.sh: Permission deniedは、スクリプトに、対象となる三つ組の x ビットがないことを示します。または、パス上のディレクトリに x がありません。最初のケースは chmod u+x deploy.sh で修正できます。
bash: ./deploy.sh: cannot execute: required file not foundは、分かりにくい名前が付いた別のエラーです。x ビットは正しく設定されていますが、1 行目で指定されたインタープリターが見つかりません。通常の原因は Windows の改行コードです。そのため、kernel は /bin/bash\r という名前のインタープリターを探します。sed -i 's/\r$//' deploy.sh で修正します。
Permissions 0644 for '/home/deploy/.ssh/id_ed25519' are too open.は SSH クライアントから出力されます。他のアカウントから読み取れる private key の使用を拒否するためです。key の権限は 600、~/.ssh の権限は 700 にします。key の取り扱い全般については、SSH key とファイル権限の管理で説明しています。
Authentication refused: bad ownership or modes for directory /home/deploy/.sshは、home directory またはその .ssh が group に対して書き込み可能な場合に、server の journal に表示されます。sshd の StrictModes 設定が key を拒否するためです。client 側では、説明のない予期しない password プロンプトとして現れます。
sudo: /etc/sudoers is world writableに続いて sudo: no valid sudoers sources found, quittingが表示される場合、sudo が自身の設定ファイルの mode を確認し、実行を拒否しています。このファイルは 0440 に設定し、world writable にしてはいけません。これは、広範囲に対して再帰的に chmod を実行した典型的な結果です。上記の sshd メッセージと同時に発生することもあり、その場合は provider の console だけが復旧手段になります。
777 では、マシン上のすべてのアカウントと、それらのアカウントで実行されるすべてのプロセスに書き込み権限を与えます。サーバーではサービスを専用ユーザーで実行するため、VPS における「全員」の範囲はノート PC よりはるかに広くなります。侵害されたサービスは、777 で許可される場所ならどこにでも書き込めます。
Web ルートでは被害が直接発生します。サーバーが配信するディレクトリが全ユーザー書き込み可能だと、ファイルアップロードの脆弱性を悪用してスクリプトを設置し、そのスクリプトをリクエストできるようになります。
777 は、所有者に関する問題への解決策としてほぼ常に不適切です。症状は「アプリケーションがこのディレクトリに書き込めない」です。原因は、ディレクトリの所有者が誤っていることです。sudo chown -R appuser:appuser /srv/app/storage をモード 755 で設定すれば解決します。アプリケーションはそこに書き込めますが、他のアカウントはディレクトリの一覧表示と移動はできても、そこへ書き込むことはできません。何かをデプロイする前にこれらのアカウントを作成する手順については、新しい VPS で最初の 10 分に行う作業を参照してください。
全ユーザーによる書き込みが正当なのは、よく知られた 1 か所である /tmp です。その表記は drwxrwxrwt です。末尾の t は sticky bit です。ディレクトリは全員が書き込めますが、ユーザーが削除できるのは自分が所有するファイルだけです。このビットがないと、どのアカウントでも別のアカウントの一時ファイルを削除できてしまいます。
変更する前にモードを確認する
これらのコマンドは状態を読み取るだけなので、どこでも安全に実行できます。
id
umask
stat -c '%A %a %U %G %n' ~/permdemo ~/permdemo/inner/notes.txt
namei -l ~/permdemo/inner/notes.txt
find ~/permdemo -perm -0002find <path> -perm -0002は、world write ビットが設定されたパス配下のすべてを一覧表示します。chmod 777で誰かが修復作業を行った後に、システムを監査する最も迅速な方法です。
特定のサービスアカウントがディレクトリに入れるか確認するには、そのアカウントとして確認します。sudo -u www-data test -x /srv/site && echo yes || echo noは、そのユーザーにディレクトリの traverse 権限がある場合は yes、ない場合は noを出力します。root として確認しても意味はありません。root はこのチェックを回避するため、結果は常に yesになります。
FAQ
Linux で drwxr-xr-x は何を意味しますか?
先頭の d で示されるディレクトリで、モードは 755 です。所有者の 3 ビットは rwx なので、所有者はすべての権限を持ちます。グループの 3 ビットは r-x、その他の 3 ビットは r-x です。そのため、所有者以外は内部の名前を一覧表示してディレクトリを通過できますが、追加や削除は誰もできません。stat -c '%A %a %U %G %n' <path> で任意のパスを確認すると、記号形式と 8 進形式が横並びで表示されます。
Web ファイルが 644、Web ディレクトリが 755 なのはなぜですか?
Web サーバーは別のアカウントで実行されます。Ubuntu では www-data です。提供するファイルには読み取り権限が必要で、そこへ至るすべての親ディレクトリには通過権限が必要です。一方、どちらにも書き込み権限は必要ありません。644 では所有者が書き込みでき、その他のユーザーは読み取りできます。755 では所有者が書き込みでき、その他のユーザーは通過できます。アプリケーションが実際に書き込む必要のあるディレクトリは、全員に対してモードを広げるのではなく、chown でそのアプリケーションのユーザーに移管します。
x ビットはディレクトリを実行できることを意味しますか?
いいえ。ディレクトリでは x は通過を意味します。これは、カーネルがパスをたどる際に、内部の名前を 1 つ解決する権限です。cd にも必要であり、その下にあるファイルを開く場合にも必要です。パス上の各ディレクトリには x が必要です。そのため、上位ディレクトリにあなたが利用できる x がなければ、モード 644 のファイルにも到達できません。namei -l /path/to/file を実行すると、連続するすべてのディレクトリのモードが表示され、どこで検索が停止したかを確認できます。
chmod 777 が正しい解決策になることはありますか?
サーバーでは、ほとんどありません。マシン上のすべてのアカウントに書き込み権限を与えるため、サービスの実行アカウントも含めてファイルを書き換えられます。サービスが侵害されると、そのサービスによってファイルを書き換えられる可能性があります。アプリケーションがディレクトリに書き込めない場合、実際の問題は通常、所有者です。sudo chown -R appuser:appuser /srv/app/storage にしてモードを 755 にすれば、アプリケーションは書き込みでき、他のアカウントはディレクトリを読み取れても書き込めません。よく知られた例外は、1777 の /tmp です。これは sticky bit によってユーザー同士が互いのファイルを削除できないために機能します。
ls が権限の後ろにドットやプラスを表示するのはなぜですか?
その 11 番目の文字は、9 個の権限ビット以外のルールを示します。drwxr-xr-x. のようなドットは、SELinux のセキュリティコンテキストが付いていることを意味します。Fedora や Rocky では通常の状態です。drwxr-xr-x+ のようなプラスは、POSIX ACL(アクセス制御リスト)が設定されていることを意味します。そのため、3 組の権限ビットには表示されない権限を、特定のユーザーまたはグループが持っています。getfacl <path> を実行すると、追加のエントリを一覧表示できます。