一言で言うと
chmodは、誰がファイルを読み込み、書き込み、実行できるかを定義するUnixコマンドで、世界のほとんどのサーバーや開発者マシンの基本的なアクセス制御システムとして機能しています。
こいつが解決すること
コンピューティングの黎明期を想像してみてください。一人の人間が、一台のマシンで、一度に一つのタスクをこなす。そんなシステムでは、ファイルパーミッションなんてのは問題を探している解決策にすぎません。コンピュータを使うのが自分だけなら、誰からファイルを保護するっていうんです?自分自身から?
そこに1960年代後半、ベル研究所でUnixが登場しました。その革命的なアイデアは、最初からマルチユーザー、マルチタスクのオペレーティングシステムであることでした。突如として、複数のプログラマーが別々のターミナルから同じメインフレームコンピュータにログインし、全員が同時に作業するようになったのです。これにより、新しく、そして緊急の問題が生まれました。どうやってデニスがケン作の新しいCコンパイラを誤って(あるいは「誤って」)削除するのを防ぐか?プロジェクトのパートナーにコードを読ませつつ、変更はさせないようにするにはどうすればいいか?へっぽこインターンからコアなOSファイルをどうやって守るか?
その解決策は、ファイルシステム自体に組み込まれた、美しくシンプルで堅牢な所有権とパーミッションのシステムでした。すべてのファイルとディレクトリには所有者がいて、グループに属し、そして3つのユーザー分類(所有者、グループのメンバー、その他全員)に対して特定のパーミッションセットを持つことになったのです。
ファイルの「モードを変更する」、つまりこれらのパーミッションを修正するためのコマンドは、chmodと名付けられました。これは、システム管理者やユーザーが「このファイルは私のもので、これとやり取りするためのルールはこれだ」と宣言するための普遍的なツールとなりました。このマルチユーザーによるカオスの問題を非常に効果的に解決したため、今日でも事実上すべてのLinuxサーバー、macOSマシン、Androidフォン、そしてIoTデバイスで、同じコアモデルが使われています。
内部の仕組み
chmodシステムの核心は、3x3のルールグリッドに、ちょっとした味付けのための特殊フラグがいくつか加わったものです。これを理解するには、3種類のパーミッションと、それらが適用される3つのユーザー分類を把握する必要があります。
3つのパーミッション:Read, Write, Execute
すべては、ファイルやディレクトリに対して実行できる3つの基本的なアクションを中心に展開します。これらはr、w、xの文字で表されます。
- Read (
r): ファイルの内容を開いて閲覧する能力。 - Write (
w): ファイルの内容を修正、変更、または削除する能力。 - Execute (
x): ファイルをプログラムやスクリプトとして実行する能力。
しかし、ここに最初の「ハマりポイント」があります。これらのパーミッションは、ディレクトリに対しては少し意味が違うのです。これは非常によくある混乱の元です。
| パーミッション | ファイルに対して | ディレクトリに対して |
|---|---|---|
Read (r) |
ファイルの内容を見ることができる | ディレクトリ内のファイル名を一覧表示できる (ls) |
Write (w) |
ファイルの内容を変更できる | ディレクトリ内でファイルを作成、名前変更、削除できる |
Execute (x) |
ファイルを実行できる | ディレクトリに入り (cd)、その中のファイルにアクセスできる |
最後のやつを考えてみてください。もしディレクトリにあなたに対する実行権限がなければ、たとえ中身が見えてもcdでそのディレクトリに入ることはできません!ディレクトリの「ドア」を通り抜けるにはxが必要なのです。
3つのユーザークラス:Owner, Group, Others
Unixのパーミッションは普遍的なものではなく、特定のユーザーカテゴリに割り当てられます。
- Owner (
u): ファイルを所有する一人のユーザー。通常は、ファイルを作成した人です。所有者が最も多くの制御権を持ちます。 - Group (
g): すべてのファイルはグループに属します。これにより、所有者は特定のチームメンバーとアクセスを共有できます。例えば、「アポロ計画」の全ファイルはapollo-devsグループに属することができます。 - Others (
o): 文字通り、その他全員。システム上のユーザーで、所有者でもなく、ファイルのグループにも属していない人たちです。
rwxr-xr--のようなパーミッション文字列を見たとき、それは実際にはOwner、Group、Othersの順で3セットのrwxパーミッションがくっついたものです。
rwx: Ownerは読み込み、書き込み、実行ができます。r-x: Groupは読み込みと実行はできますが、書き込みはできません。r--: Othersは読み込みしかできません。
2つの記法:シンボル記法 vs. オクタル記法
chmodに何をしたいか伝えるには2つの方法があり、開発者は永遠にこの2つの間で翻訳作業をしています。
1. シンボル記法(「フレンドリーな」方法)
シンボル記法は、すでに学んだ文字(r, w, xとu, g, o, a。aは「all」の意味)を使います。+でパーミッションを追加し、-で削除し、=で正確に設定します。
# 所有者に実行権限を与える
$ chmod u+x my_script.sh
# グループとその他のユーザーから書き込み権限を削除する
$ chmod go-w sensitive_data.txt
# パーミッションを正確に設定:所有者は読み書き、グループは読み取り、その他はアクセス不可
$ chmod u=rw,g=r,o= config.yml
これは、小さく的を絞った変更を行うのに最適です。
2. オクタル記法(「ギークな」方法)
オクタル記法はより速く、スクリプトでより一般的に使われ、2進数に基づいています。各パーミッション(r, w, x)は3ビットの数値の中の1ビットです。
r(read) は最初のビットで、値は 4 です。w(write) は2番目のビットで、値は 2 です。x(execute) は3番目のビットで、値は 1 です。
欲しいパーミッションに対応する数値を足し合わせます。
| 数字 | 2進数 (rwx) |
許可されるパーミッション |
|---|---|---|
| 0 | 000 (---) |
なし |
| 1 | 001 (--x) |
実行 |
| 2 | 010 (-w-) |
書き込み |
| 3 | 011 (-wx) |
書き込みと実行 |
| 4 | 100 (r--) |
読み取り |
| 5 | 101 (r-x) |
読み取りと実行 |
| 6 | 110 (rw-) |
読み取りと書き込み |
| 7 | 111 (rwx) |
読み取り、書き込み、実行 |
755のような3桁のオクタルコードは、Owner、Group、Othersのパーミッションを表します。
chmod 755 my_script.sh は以下の意味です:
- Owner:
7(rwx) - 読み取り、書き込み、実行。 - Group:
5(r-x) - 読み取りと実行。 - Others:
5(r-x) - 読み取りと実行。
これは、他のユーザーが実行しても安全な実行可能スクリプトにとって、非常に一般的なパーミッションです。ファイルに一般的なパーミッションは644(所有者は読み書き可能、その他全員は読み取りのみ可能)です。
特別ゲスト:SUID, SGID, そしてスティッキービット
基本的なrwxの他に、3つの特別なモードがあり、先頭に4桁目のオクタル数字で表されます(例:chmod 4755)。
- SUID (Set User ID) - オクタル
4: このビットが設定された実行可能ファイルが実行されると、それを実行したユーザーではなく、ファイルの所有者の権限で実行されます。古典的な例はpasswdコマンドで、これは保護された/etc/shadowファイルを変更する必要があります。passwd実行可能ファイルはrootによって所有され、SUIDビットが設定されているため、一般ユーザーが実行すると、その操作のためだけに一時的にroot権限を得ます。強力ですが危険です。 - SGID (Set Group ID) - オクタル
2: SUIDに似ていますが、実行可能ファイルはファイルのグループIDで実行されます。より便利な使い方として、ディレクトリに設定すると、その中に作成された新しいファイルやディレクトリは、作成したユーザーのプライマリグループではなく、親ディレクトリのグループを自動的に継承します。これは共有プロジェクトフォルダーには不可欠です。 - スティッキービット - オクタル
1: これには奇妙な歴史がありますが、今日ではほぼディレクトリにのみ使用されます。ディレクトリにスティッキービットが設定されている場合(システムの/tmpフォルダーなど)、すべてのユーザーがそこにファイルを作成できますが、ユーザーは自分が所有するファイルしか削除または名前変更できません。これにより、共有スペースで他人のファイルをいじるのを防ぎます。
実録・世界の現場から
実行できないスクリプト事件
ジュニア開発者のアレックスは、サーバーのデプロイを自動化する素晴らしいシェルスクリプトを書きました。彼はdeploy.shをGitにコミットします。本番サーバーで、リポジトリをクローンし、./deploy.shとタイプしてエンターキーを押しました。返ってきたのは bash: ./deploy.sh: Permission denied。パニック。サーバーを壊してしまったのか?先輩開発者が冷静にls -l deploy.shとタイプし、彼に出力を見せました:-rw-r--r--。ファイルには読み取りと書き込みのパーミッションはありましたが、実行(x)がありませんでした。Gitはデフォルトでは実行権限を保持しません。すばやくchmod +x deploy.shを実行すると、スクリプトは完璧に動作しました。
教訓: ファイル、特にGitやzipアーカイブのようなソースからのファイルは、デフォルトでは実行可能ではありません。実行するには明示的に許可を与える必要があります。
共有プロジェクトフォルダーの悪夢
デザインチームと開発チームが、Linuxサーバー上の/data/project-xというフォルダーでアセットを共有する必要がありました。システム管理者は全員をproject-x-teamグループに入れ、そのグループにフォルダーへの書き込みアクセス権を与えました。しかし、カオスが始まりました。デザイナーがファイルをアップロードすると、それはdesigner:designersの所有となり、開発者はそれを修正できませんでした。開発者がサブフォルダーを作成すると、それはdev:developersの所有となり、デザイナーはそこにファイルを追加できませんでした。誰もが常にシステム管理者にパーミッションの修正を依頼していました。解決策は?管理者がchmod g+s /data/project-xを実行しました。これにより、ディレクトリにSGIDビットが設定されました。それ以降、/data/project-x内に作成されたすべての新しいファイルとフォルダーは、自動的にproject-x-teamグループを継承するようになりました。調和が取り戻されたのです。
教訓: ディレクトリのSGIDは、共有グループフォルダーを管理するための正しく、ハックではない方法です。
公開ウェブサイトのセキュリティホール
フリーランスのウェブ開発者が、クライアントのためにシンプルなPHPサイトを立ち上げました。便宜上、彼はデータベース設定ファイルconfig.inc.phpをホームページと同じディレクトリに残しました。このファイルには、データベースのユーザー名とパスワードが平文で含まれていました。そのパーミッションはデフォルトの644(-rw-r--r--)で、ウェブサーバーのユーザーがそれを読めることを意味していましたが(それは良い)、URLを推測した地球上の誰でも読めることも意味していました。セキュリティスキャナーがそのファイルを見つけ、攻撃者はデータベースの認証情報をダウンロードしました。修正はchmod 600 config.inc.phpであるべきでした。これにより、所有者(ウェブサーバープロセス)のみが読み取り可能になります。
教訓: デフォルトのパーミッションが安全だと思い込んではいけません。設定ファイルや秘密鍵のような機密ファイルは、可能な限り厳格にロックダウンする必要があります。
よくある間違いと落とし穴
- 思考停止の
chmod 777。 イライラすると、多くの人がディレクトリに対してchmod -R 777 .を実行したくなります。これは再帰的にすべての人にすべての読み取り、書き込み、実行権限を与えます。これは壊滅的なセキュリティ脆弱性であり、家のドアを取り払い、芝生に「ご自由にどうぞ」という看板を立てるのと同じデジタル版です。絶対にやらないでください。 - ディレクトリの
xパーミッションを忘れる。 ファイルに対するrパーミッションを持っていても、そのパスの親ディレクトリの1つにxパーミッションがないためにアクセスできないことがあります。通過したいすべてのディレクトリに対して実行権限が必要です。 umaskの謎。 新しく作成したファイルがなぜ777ではなく644になるのか不思議に思ったことはありませんか?それはあなたのumaskの仕業です。umaskはシェルが適用する「マスク」で、ファイルやディレクトリが作成される際にパーミッションを取り除きます。一般的なumaskの022は、GroupとOthersの「書き込み」パーミッションを削除し、デフォルトの666を644に変えます。chmod +xがchmod 755と同じだと思い込む。 違います。chmod 755 my_fileはパーミッションを絶対的に設定します。chmod +x my_fileは、すでに読み取りビットを持っているユーザークラス(owner, group, other)に対して実行ビットを追加するだけで、他のビットは変更しません。シンボルモードは相対的、オクタルモードは絶対的です。
なぜ知っておくべきか
Windows以外のコマンドラインに触れるなら、chmodを理解する必要があります。これはオプションではありません。この知識は次のような場合に極めて重要です:
- Linuxサーバーにアプリケーションをデプロイするとき。
- 実行する必要があるスクリプト(Shell、Python、Node.js)を書くとき。
- ファイルパーミッションについて独自の考えを持つGitを扱うとき。
- ファイル共有や共同作業環境を設定するとき。
- 機密ファイルへのアクセスを制限してサーバーのセキュリティを強化するとき。
- コンテナ内のファイルパーミッションが最重要となるDockerを使用するとき。
chmodは、カジュアルなユーザーと、真のシステムオペレーターや開発者を分ける、最初にして最も基本的なコマンドの1つです。それを理解することは、マシンをただ使うだけでなく、制御するための通過儀礼なのです。
さらに深く
- Wikipedia: chmod - コマンド、その歴史、さまざまな記法についての優れた高レベルの概要。
- Wikipedia: File-system permissions - DAC、ACL、およびシステム間のシンボル/オクタル記法の概念に関するより広範な見解。
- The Linux man-pages project: chmod(1) - Linux上の
chmodコマンドに関する、正統で技術的なリファレンス。内容は濃いが権威がある。 - The Open Group Base Specifications (POSIX): chmod - (macOSやLinuxのような)POSIX準拠システムで
chmodがどのように動作しなければならないかを定義する実際の標準。 - ArchWiki: File permissions and attributes - Arch Linuxコミュニティによる非常に実践的でよくメンテナンスされているガイド。
chmod、chown、および特別な属性をカバーしています。