「Linux プログラミングインタフェース」再び。

輪読やりながら「こんな機能使うのか?」って、みんな文句言いながら読んでいた章。ここで触っとかないと、今後「ACL とか知らねぇ。」ってなりそうなので、まとめておく。

17章 ACL

ACL はユーザもしくはグループ単位でのパーミションを設定可能にするもので、ユーザ、グループ数を制限しません。Linux ではバージョン 2.6 で ACL を導入しました。

refs: https://www.oreilly.co.jp/books/9784873115856/

ACL(access control list) とは

簡単に言うとファイルやディレクトリのパーミッションに +αのアクセス権 を設定できる機能。

ACL を設定すると下記例のように、通常のパーミッション的には root しか読めないファイルに、vagrant ユーザの参照権限を追加することができる。

# ls -l aclfile
-rw-r-----+ 1 root root 5 Jun 29 15:13 aclfile  #拡張ACLが設定されたファイルには + がつく
#
# sudo -u vagrant cat aclfile
root
#
# sudo -u harasou cat aclfile
cat: aclfile: Permission denied
#
# grep root /etc/group  #2ユーザ共に rootグループには属していない
root:x:0:

ACL の設定方法

ACL の表示や変更は、getfaclsetfcal を使用する。

  • ACL の表示

    # getfacl -c acl_file
    user::rw-
    user:vagrant:r--
    group::---
    mask::r--
    other::---
    
  • ACL の変更

    setfacl -m user:vagrant:r acl_file  #ACLエントリの設定
    setfacl -x user:vagrant   acl_file  #ACLエントリの削除
    setfacl -b                acl_file  #全ての拡張ACLエントリを削除
    

ACL の基礎

ACL のテキスト表現

setfacl で指定するパラメータは、以下のような感じで、ACLエントリ(テキスト表現)を,区切りで並べたものを指定する。

setfacl -m u::rw,u:paulh:rw,u:annabel:rw,g::r,g:teach:rw,km::rwx,o::- acl_file

各ACLエントリは タグ種類:タグ修飾子:パーミッション といった形式になっていて、上記 ACLを ACLエントリごとにわけると以下のようになる。

ACLエントリ タグ種類
u::rw ACL_USER_OBJ
g::r ACL_GROUP_OBJ
o::- ACL_OTHER_OBJ
u:paulh:rw ACL_USER
u:annabel:rw ACL_USER
g:teach:rw ACL_GROUP
m::rwx ACL_MASK

上記 ACL を言葉で説明すると以下のような感じになる。

acl_file に、通常のパーミッション 640 を設定し、追加で paulhユーザ と annabelユーザ、teachグループに rw のアクセス権を設定する。

タグの種類

タグの種類は、通常のパーミッションに相当する基本ACLと、追加で設定するイメージの拡張ACLに分類される。

  • 基本ACL
    • ACL_USER_OBJ : 従来パーミッションの owner に相当
    • ACL_GROUP_OBJ : 従来パーミッションの group に相当
    • ACL_OTHER : 従来パーミッションの other に相当
  • 拡張ACL
    • ACL_USER : エントリのパーミションをタグ修飾子に指定されたユーザへ適用する
    • ACL_GROUP : エントリのパーミションをタグ修飾子に指定されたグループへ適用する
    • ACL_MASK : グループクラス(ACL_GROUP_OBJ,ACL_USER,ACL_GROUP)で設定されている権限の最大値

ACL の動作確認

準備

ACL はファイルシステムの拡張機能として実装れていて、デフォルトでは無効になっているため、mount オプションで有効にする必要がある。

ここでは、パーティション準備するのが面倒なので、ファイルを loop mount してテスト。

  1. ファイルシステムとなる image ファイルを作成

    # dd if=/dev/zero of=image bs=10M count=1
    # ls -l image
    -rw-r--r-- 1 root root 10485760 Jun 28 23:26 image
    
  2. フォーマット

    # mke2fs -t ext4 -F image
    
  3. マウント

    # mkdir acltest                
    # mount -o loop,acl image acltest/ 
    # mount | tail -1              
    /home/vagrant/image on /home/vagrant/acltest type ext4 (rw,acl)
    

動作確認

  • root オーナのファイルaclfile に、vagrant ユーザの rw を設定

    # ll aclfile
    -rw-r--r-- 1 root root 5 Jun 28 23:31 aclfile
    #
    # setfacl -m user:vagrant:rw aclfile
    # ll aclfile
    -rw-rw-r--+ 1 root root 5 Jun 28 23:31 aclfile
    #
    # getfacl -c aclfile
    user::rw-
    user:vagrant:rw-
    group::r--
    mask::rw-
    other::r--
    
    # sudo -u vagrant sh -c "echo vagrant > aclfile"
    # cat aclfile
    vagrant
    
    • 拡張ACL を設定したので、ls で表示されるパーミッションの横に + がつく
    • root オーナファイルに vagrant ユーザで書き込み可能になる
  • ACL の削除

    基本ACL は削除できない

    # setfacl -x user:: aclfile
    setfacl: aclfile: Malformed access ACL `user:vagrant:r--,group::r--,mask::r--,other::---': Missing or wrong entry at entry 1
    # setfacl -x groupt:: aclfile
    setfacl: aclfile: Malformed access ACL `user::rw-,user:vagrant:r--,mask::r--,other::---': Missing or wrong entry at entry 3
    # setfacl -x other:: aclfile
    setfacl: aclfile: Malformed access ACL `user::rw-,user:vagrant:r--,group::r--,mask::r--': Missing or wrong entry at entry 5
    

    拡張ACL の削除。一つでも残っていると ls のパーミッションに +

    # setfacl -x user:vagrant aclfile
    #
    # ls -l aclfile; getfacl -c aclfile
    -rw-r-----+ 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    group::r--
    mask::r--
    other::---
    
    # setfacl -x mask aclfile
    # ls -l aclfile; getfacl -c aclfile
    -rw-r----- 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    group::r--
    other::---
    
  • ls で表示されるグループのパーミッションは mask の値

    ACLの設定を行っていない状態。グループは r

    # ls -l aclfile; getfacl -c aclfile
    -rw-r----- 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    group::r--
    other::---
    

    拡張ACL を設定。 グループのパーミッションは mask の値と一致する。mask の値は、拡張ACLの最大のパーミッションになっている。

    # setfacl -m user:vagrant:r aclfile
    # ls -l aclfile; getfacl -c aclfile
    -rw-r-----+ 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    user:vagrant:r--
    group::r--
    mask::r--
    other::---
    
    # setfacl -m user:harasou:rw aclfile
    # ls -l aclfile; getfacl -c aclfile
    -rw-rw----+ 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    user:vagrant:r--
    user:harasou:rw-
    group::r--
    mask::rw-
    other::---
    

    拡張ACL を全て削除すると、ls の表示は、もともとのグループパーミッション r に戻る

    # setfacl -b aclfile
    # ls -l aclfile; getfacl -c aclfile
    -rw-r----- 1 root root 5 Jun 29 15:13 aclfile
    user::rw-
    group::r--
    other::---
    

所感

なかなか使い所が難しい(運用しづらい)感があるが、例えば、レンサバなどは、各ユーザ権限で基本、ファイルを作成するが、apache ユーザでも読み込みができる必要がある。こういったところで使うとわりとシンプルに権限周りを管理できるのかもしれない。