ACLでファイルにアクセス権限を付与する

ACLを使ってsudoせずにファイルを読み取る。

更新履歴

  • 2022/11: 結論部分を整理。

状況

ファイル・ディレクトリに対してアクセス権限(r: 読み取り)を持ってないユーザーで、特定のディレクトリの中にあるファイルを読み取れるようにしたいケースがありました。

chmodを使う手もありますが、こちらでは、特定ユーザー・グループ以外でもアクセス可能になるのでこれはどうなんだろうと思いました。

sudoを使えばアクセスできるのですが、パスワードの要不要の切り替えやsudoresへのこのためだけの設定が面倒です。

最終的にはこれだけで:

cat /need/permission/dir/afile.txt

特定のユーザーもしくはグループが、特定のディレクトリの中の任意のファイルを見れるようにしたいのです。

この状況に適しているのが、ACLの設定です。

ACL

ACL(アクセスコントロールリスト)は、文字通りアクセスを制御するために使われるリストです。ここでは、ファイル・ディレクトリのアクセスの制御のためのリストを意味します。ネットワークなどでも使われますが、目的としては同じです。

全てのファイル・ディレクトリはデフォルトで基本ACLを持っています。ls -lしたときにも表示される「所有者・グループ・その他」のことです。それ以外のACLは拡張ACLと呼ばれるようです。今回はこの拡張ACLを設定します。

ファイル・ディレクトリのACLを変更するときは、setfaclコマンドとgetfaclコマンドを使用します。

getfaclで確認

現在の設定の確認は、getfacl <path>で行えます:

$ getfacl /aaa/
getfacl: Removing leading '/' from absolute path names
# file: aaa/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

これは初期状態のACLです。

また、拡張ACLが設定されていると、ls -lしたときに+表示が付きます:

$ ls -l /aaa/bbb/
total 16
drwx------  2 root root 4096 Sep 20 01:56 a1
drwx------  2 root root 4096 Sep 20 01:56 a2
-rwxr-----+ 1 root root   22 Sep 20 02:16 bb2.txt
-rwx------  1 root root    9 Sep 20 01:59 bbbfile.txt

この例では拡張ACLで特定ユーザーにbb2.txtへの読み取り権限を付与しています。 付与後のgetfaclはつぎのようになります:

$ cd /aaa
$ getfacl bbb/bb2.txt
# file: bbb/bb2.txt
# owner: root
# group: root
user::rwx
user:<username>:r--
group::r--
mask::r--
other::---

maskは与えられる権限の最大範囲を表しています。上の状態だと、読み書き(rw)と実行(x)をsetfaclで与えても実際には、r--となります。実際の権限を実効権といい、maskACLマスクといいます。ACLマスクを超えた権限の場合、getfaclでは、行末でのコメントアウトのように#effective:r--などが表示されます。

後述するデフォルト設定もgetfaclで確認できます。

setfaclで設定

setfaclでACLの変更・追加・削除などが行えます。基本的には-mオプションで対象ユーザーまたはグループと権限を指定して使います。 基本的には、そのディレクトリ・ファイルの権限を持つユーザーか、rootユーザーなどで行うべきだと思います。

ただの単一ユーザーの単一ファイルへの権限追加であれば、これだけでできます:

$ setfacl -m user:<username>:r-- /aaa/bbb/bb2.txt

権限の指定方法は、rwxの文字列で行います。無効にしたいものは、-で置き換えます。

もし、先の述べたACLマスクにより実効権で制限される場合は、ACLマスクを変更します:

$ setfacl -m mask::r-- /aaa/bbb/

ディレクトリに対しても設定できます。対象のディレクトリに対する実行権限xがないと、その中にあるファイルへのアクセスはできないのでディレクトリの権限も注意しましょう。

-Rオプションでサブディレクトリとファイルに対して再帰的に適用することもできます。

--testオプションを使うと、ACLは適用せずに実行結果だけ出力できます。結構便利です。使い終わってから気がつきました…

-bオプションで既存の拡張ACL設定を破棄できます。-Rとも組み合わせられます。

setfaclのデフォルト

ディレクトリに対してsetfaclするときに、-dオプションを使うと、内部のファイルの作成時に、そのファイルに対して指定したACLが適用されるようになります。既存のファイルには適用されないようです。

再帰指定オプション-Rと組み合わせた時は、ファイルは無視されてディレクトリに対してのみ、ACLが設定されるようです。

その他

ACLの設定は、--testで結果を十分検討した上で行った方がいいでしょう。複雑なのを検証したいときは、dockerを使うといいです:

$ docker run --rm -it centos:7 bash

でお手軽に実験できます。ディレクトリ構造を適当に作って実験できます。--testもこれ上で行いました。

結論

結論としては、最初に述べた状況のようなケース(特定ユーザーがファイルの読み取り可能)に対応するには、次のコマンドを使います:

2022/11更新: 既存ファイルにも対応。xargsも使うようにした。

# デフォルトfacl設定
setfacl -R -d -m u:<user>:r-- /aaa/bbb
# 既存ファイルのfacl設定
find /aaa/bbb/ -name "pattern" -print0 | xargs -0 setfacl -m u:<user>:r--
# 既存フォルダのfacl設定
find /aaa/bbb/ -type d -print0 | xargs -0 setfacl -m u:<user>:r-x
# ok

これで、ディレクトリbbbにあるpatternに一致する全てのファイルに対して、ユーザー<user>はディレクトリに到達でき、ファイルへの読み取り権限を持つことができます。--testを付与して確認したから行いましょう。ユーザーでなくグループでも同様にできると思います。

ファイルは適度なタイミングで作成される一方で、ディレクトリは手動で作成しない限り作成されないため、このような方法をとることにしました。

もっといい方法があるような気がします。

おわり

わかってない部分もありますが、とりあえず目的は達成できました。また使うこともあると思うので、ここにまとめておいて参考も載せておきます。

日本語資料も多いですが、結構動かして見ないと分からないかもしれないです。短縮表記の*,*もよくわかってないけど、おそらく権限は変更されないという意味なのだと思います。

以上です。


Amazonアソシエイト

https://amzn.to/3hWqH7q

コメント

タイトルとURLをコピーしました