ZFSのACLをNFSv4形式でいじって全ファイルに自動で実行パーミッション付けたった
はじめに
私の環境では、ファイルパーミッションは、umask付けてて、一般ファイルなら644、ディレクトリなら755になっています。これを一般ファイルも755にしてやるのが今回の目標。
ローカルでDAVを使っていますが、こいつが実行パーミッションを付けよらん。これまではSambaをかませて、smbfsをマウントしているところにDAVで書き込んで実行パーミッションを与える、というなんとも香ばしい手段でどうにかしていましたが、フルZFSにしちゃったら、なんでかsmbfsをマウントできない、という目に遭ってしまったため、この手段を捨てる時が来たのです。
手動でchmodを使ったりして755にするのは可能ですが、断言できます、絶対忘れる。
ご注意
NFSv4 です。POSIX.1e ではありません。
パーミッションを見てみる
とりあえず、touchでファイルを作ってみます。なお私の環境では 644 になるように umask 022 を設定してます。
% touch 1.txt % ls -l 1.txt -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx a.txt
このファイルのACLエントリを見てみます。getfaclを使います。
% getfacl 1.txt # file: 1.txt # owner: [ユーザ名] # group: [グループ名] owner@:rw-p--aARWcCos:------:allow group@:r-----a-R-c--s:------:allow everyone@:r-----a-R-c--s:------:allow
最後の3行がACLエントリです。
エントリは":"区切りで、各フィールドは次のような意味を持ちます。
<タグ>:<パーミッション>:<継承フラグ>:<ACLタイプ>
- タグ: "user:<ユーザ名>"などのユーザ指定(同じようにグループ指定も可能)や、特殊なタグとして"owner@", "group@", "everyone@" があります。
- パーミッション: マニュアル見て下さい。rは読み取り、wは書き込み、xは実行、です。追加(p)、属性読み書き(a/A, R/W)、ACL読み書き(c/C)などがあります。
- 継承フラグ: 一般ファイルが継承(f)、ディレクトリが継承(d)、
- ACLタイプ: "allow"か"deny"を取ります。
なお、"everyone@"については注意が必要です。"others"はownerやgroupを除いたものになりますが、"everyone@"は"owner@"と"group@"を含みます。このため、"owner@", "group@"に実行パーミッションが付いていなくても"everyone@"に実行パーミッションが付いていたら、"owner@"も"group@"も実行パーミッションが付いているのと同じになります(denyしてないという前提)。
ためしに手動で755にしてやる
644から755にするには、everyoneに実行パーミッションを付けます。setfaclを使います。
% setfacl -m everyone@:rxaRcs:allow 1.txt % getfacl 1.txt # file: 1.txt # owner: [ユーザ名] # group: [グループ名] owner@:rw-p--aARWcCos:------:allow group@:r-----a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow % ls -l 1.txt -rwxr-xr-x+ 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 1.txt
everyoneのパーミッションが変更になったことが分かると思います。
ACLを継承する設定
次にACLの設定を継承する設定を行ってみます。
その前に、d1というディレクトリと、ついでにd1/1.txtという一般ファイルを作っておきます。
% mkdir d1 % ls -ld d1 drwxr-xr-x 2 [ユーザ名] [グループ名] 2 xx月 xx xx:xx d1 % touch d1/11.txt % ls -ld d1/11.txt -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx d1/1.txt
d1のACLの状態は次の通りです。
% getfacl d1 # file: d1 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow
さて、d1に実行パーミッションを付けて、かつ子ディレクトリ、子ファイルに継承する設定にしてみましょう。
% setfacl -m everyone@:rxaRcs:fd:allow d1 % getfacl d1 # file: d1 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:fd----:allow
setfaclのエントリの3番目のフィールドを作って"fd"が付いていますが、これが継承する設定です。
これで継承できているかどうか、ファイルを作ってみます。
% touch d1/2.txt % ll d1/2.txt -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx d1/2.txt
はい、実行パーミッションが付いてませんね。
ZFSのプロパティを変更しなければならない
ACLで継承設定を用意しても、ZFSが許していなければ、継承されません。
# zfs get aclinherit NAME PROPERTY VALUE SOURCE rpool aclinherit restricted default rpool/home aclinherit restricted default rpool/root aclinherit restricted default
restrictedをpassthrougにしてやります。
# zfs set aclinherit=passthrough rpool/home # zfs get aclinherit NAME PROPERTY VALUE SOURCE rpool aclinherit restricted default rpool/home aclinherit passthrough local rpool/root aclinherit restricted default
あらためて、ファイルを作ってみます。
% touch d1/3.txt % ls -l d1/3.txt -r-xr-xr-x+ 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 3.txt
755じゃなくて555になっとるがな
ここで改めて3.txtのACL状態を見てみます。
% getfacl d1/3.txt # file: d1/3.txt # owner: [ユーザ名] # group: [グループ名] everyone@:r-x---a-R-c--s:------:allow
ownerもgroupもありません。
上のd1のACLの状態を確認して下さい、"f"と"d"が付いているのは、everyoneだけです。ownerもgroupも継承しろとは言ってないのだから、everyoneだけを継承するのは当然です。
また、上述していますが、everyoneはownerもgroupも含むので、everyoneの設定である5がownerとgroupにも影響を与え、555になってしまうわけです。
あらためて、ownerとgorupに設定します。
% setfacl -m owner@:rwxpaARWcCos:fd:allow d1 % setfacl -m group@:rxaRcs:fd:allow d1 % getfacl d1 # file: d1 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:fd----:allow group@:r-x---a-R-c--s:fd----:allow everyone@:r-x---a-R-c--s:fd----:allow
ファイルを作ってみます。
% touch d1/4.txt % ls -l d1/4.txt -rwxr-xr-x 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx d1/4.txt % getfacl d1/4.txt # file: d1/4.txt # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow
755になりました。
ここまでのまとめを ls -l で見る
% ls -l d1 total 2 -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 1.txt -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 2.txt -r-xr-xr-x+ 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 3.txt -rwxr-xr-x 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 4.txt 1.txt - ディレクトリに継承を設定する前 2.txt - ディレクトリにothers@のみ継承を設定した後 3.txt - ZFSに継承許可設定した後 4.txt - ディレクトリに全ての継承を設定した後
再帰的になっているかを見る
% mkdir d1/d1 % getfacl d1/d1 # file: d1/d1 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:fd----:allow group@:r-x---a-R-c--s:fd----:allow everyone@:r-x---a-R-c--s:fd----:allow % touch d1/d1/1.txt % getfacl d1/d1/1.txt # file: d1/d1/1.txt # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow
chmodとACL継承
ここで、ふと、不用意にchmodすると継承が途切れるのではないか、という疑念が出てきましたので、試してみます。
% mkdir d1/d2 % getfacl d1/d2 # file: d1/d2 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:fd----:allow group@:r-x---a-R-c--s:fd----:allow everyone@:r-x---a-R-c--s:fd----:allow
mkdirした時点では、"f"と"d"は付いていますので、d1/d2の配下にファイルやディレクトリを作っても継承されます。
% chmod 700 d1/d2 % getfacl d1/d2 # file: d1/d2 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:------a-R-c--s:------:allow everyone@:------a-R-c--s:------:allow
はいとれた、"f"も"d"もとれちゃったよ。
ということで、chmodをするときは要注意です。
sftpで取ってくるとき
まず、リモートで、ディレクトリ "00" を掘って、いくつかのパーミッションを持たせたファイルとディレクトリを入れておきます。こんなかんじ。
remote% ls -lR 00 total 4 -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 644.txt drwx------ 2 [ユーザ名] [グループ名] 512 xx月 xx xx:xx 700 -rwxr-xr-x 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 755.txt ./700: total 0 -rw-r--r-- 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 700_644.txt -rwxr-xr-x 1 [ユーザ名] [グループ名] 0 xx月 xx xx:xx 700_755.txt remote%
まずは、"d"と"f"が付いているディレクトリに移動。
% cd d1
sftpで取ってきました。
% sftp -p remote ... sftp> get -r 00 sftp> ^D
さてこれがどうなっているか。
% getfacl 00 # file: 00 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:fd----:allow group@:r-x---a-R-c--s:fd----:allow everyone@:r-x---a-R-c--s:fd----:allow
継承されてますね。
% getfacl 00/644.txt # file: 00/644.txt # owner: [ユーザ名] # group: [グループ名] owner@:rw-p--aARWcCos:------:allow group@:r-----a-R-c--s:------:allow everyone@:r-----a-R-c--s:------:allow % getfacl 00/755.txt # file: 00/755.txt # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow
一般ファイルの 00/644.txt と 00/755.txt はchmodされてるようです。
% getfacl 00/700 # file: 00/700 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:fd----:allow group@:r-x---a-R-c--s:fd----:allow everyone@:r-x---a-R-c--s:fd----:allow
00/700 ディレクトリが755になってます。chmodしてません。
% getfacl 00/700/700_644.txt # file: 00/700/700_644.txt # owner: [ユーザ名] # group: [グループ名] owner@:rw-p--aARWcCos:------:allow group@:r-----a-R-c--s:------:allow everyone@:r-----a-R-c--s:------:allow % getfacl 00/700/700_755.txt # file: 00/700/700_755.txt # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow
00/700/644.txt, 00/700/755.txt は、ともにchmodされてますね。
ここから言えるのは、ディレクトリはchmodしない、です。
sftpでは常にディレクトリはchmodしないのか
いやそんなことないです。
ACL継承をしていないディレクトリを作り、適当にsftpで取ってきてみます。
% cd (適当なところ) % mkdir dd % getfacl dd # file: dd # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:r-x---a-R-c--s:------:allow everyone@:r-x---a-R-c--s:------:allow % sftp -p ... ... % getfacl dd/00/700 # file: dd/00/700 # owner: [ユーザ名] # group: [グループ名] owner@:rwxp--aARWcCos:------:allow group@:------a-R-c--s:------:allow everyone@:------a-R-c--s:------:allow
ddは継承していなくて、さきほどの 00 のツリーを引っ張ってきたところです。00/700ディレクトリは、ちゃんと700になっているので、chmodをやってる。