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--
となります。実際の権限を実効権
といい、mask
をACLマスク
といいます。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
を付与して確認したから行いましょう。ユーザーでなくグループでも同様にできると思います。
ファイルは適度なタイミングで作成される一方で、ディレクトリは手動で作成しない限り作成されないため、このような方法をとることにしました。
もっといい方法があるような気がします。
おわり
わかってない部分もありますが、とりあえず目的は達成できました。また使うこともあると思うので、ここにまとめておいて参考も載せておきます。
日本語資料も多いですが、結構動かして見ないと分からないかもしれないです。短縮表記の*,*
もよくわかってないけど、おそらく権限は変更されないという意味なのだと思います。
- Ubuntu Manpage: getfacl - ファイルのアクセス制御リスト (access control list) を取得する
- Man page of SETFACL
- Man page of GETFACL
以上です。
Amazonアソシエイト
コメント