🌊

Linuxで拡張属性を設定してみる

2023/01/04に公開

はじめに

LPICの勉強している中で、ファイルの拡張属性まわりについて、検証しながら必要な情報をまとめてみました。

確認するコマンド

コマンド 用途
setfattr ファイルの拡張属性を設定・削除する
getfattr ファイルの拡張属性を表示する

拡張属性について

  • 拡張属性は「名前空間識別子.拡張属性="値"」という形式で記載されている。
  • 属性クラスが決まっていて、以下4つのいずれか。
属性クラス 説明
user ユーザーが自由に定義できる
system カーネルが利用する
security 主にSELinuxが使用する
trusted 信頼されるプロセスが使用する

user以外は、一般ユーザー権限で拡張属性を設定しようとしてもエラーとなりました。
 root権限だと、securitytrustedは設定できました。

一般ユーザーとrootでそれぞれの属性クラスで実行
## 一般ユーザーで設定してみる ##
# system
$ setfattr --name=system.test2 --value=test2 test2.txt 
setfattr: test2.txt: サポートされていない操作です

# security
$ setfattr --name=security.test2 --value=test2 test2.txt 
setfattr: test2.txt: 許可されていない操作です

# trusted
$ setfattr --name=trusted.test3 --value=test2 test2.txt 
setfattr: test2.txt: 許可されていない操作です

## rootで設定してみる ##
# security
$ sudo setfattr --name=security.test2 --value=test2 test2.txt 
$ getfattr -n security.test2 test2.txt 
# file: test2.txt
security.test2="test2"

# system
$ sudo setfattr --name=system.test2 --value=test2 test2.txt 
setfattr: test2.txt: サポートされていない操作です

# trusted
$ sudo setfattr --name=trusted.test2 --value=test2 test2.txt 
$ getfattr -n trusted.test2 test2.txt 
test2.txt: trusted.test2: No such attribute #一般ユーザーでは設定した値は出力されず
$ sudo getfattr -n trusted.test2 test2.txt 
# file: test2.txt
trusted.test2="test2"

SELinuxやケーパビリティの設定も拡張属性で一部確認することができます。

SELinuxやケーパビリティを拡張属性から確認してみる

SELinuxの確認

$ getfattr -n security.selinux test.sh 
# file: test.sh
security.selinux="unconfined_u:object_r:user_home_t:s0"

ケーパビリティの確認

$ getcap /usr/bin/ping
/usr/bin/ping cap_net_admin,cap_net_raw=p

$ getfattr -m security  /usr/bin/ping
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/ping
security.capability

$ getfattr -n security.capability  /usr/bin/ping
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/ping
security.capability=0sAAAAAgAwAAAAAAAAAAAAAAAAAAA=

$ getfattr -n security.capability -e hex  /usr/bin/ping
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/ping
security.capability=0x0000000200300000000000000000000000000000

setfattr

よく使うオプション

オプション 意味
-n,--name 拡張属性を指定する
-v,--value 拡張属性のを指定する(-nと合わせて利用)
-x,--remove 指定した拡張属性を削除する

※再起的に付与するオプションがないのは、そういった使い方を想定していないからなのでしょうか?

一番シンプルに拡張属性を設定してみる。

$ touch test.sh
$ setfattr -n user.test -v テストファイル test.sh
$ getfattr -d -e text test.sh 
# file: test.sh
user.test="テストファイル"

設定値を変更したい場合は、同じコマンドを実行すれば良い

$ setfattr --name=user.test --value=修正後 test.sh 
$ getfattr -d -e text test.sh 
# file: test.sh
user.test="修正後"

設定した拡張属性を削除してみる

$ getfattr -d -e text test.sh 
# file: test.sh
user.test="修正後"
user.test2="テスト"

$ setfattr -x user.test test.sh 
$ getfattr -d -e text test.sh 
# file: test.sh
user.test2="テスト"

$ setfattr --remove=user.test2 test.sh 
$ getfattr -d -e text test.sh 
$

ちなみに、属性名に全角文字も入力ができました。
ただ、全角は後々不具合の元になるので設定することはないですかね。

$ setfattr -n user.テスト -v test test.sh 
$ getfattr -d -e text test.sh 
# file: test.sh
user.テスト="test"

getfattr

よく使うオプション

オプション 意味
-d,--dump 全ての値を出力する
-n,--name 指定した値を出力する
-e,--encoding=書式 値の書式を"text","hex","base64"から指定する
-R,--recursive ディレクトリを指定した場合、サブディレクトリも再起的に確認する

何も設定していない場合は、出力されない。

$ touch test.txt

$ getfattr -d test.txt
$

上記では何も出力されなかったが、SELinuxの設定はあるため、-nで利用されるコンテキストを表示する。

$ getfattr -n security.selinux test.txt 
# file: test.txt
security.selinux="unconfined_u:object_r:user_home_t:s0"

ユーザーが設定した値を出力する。

$ setfattr -n user.test -v テスト test.txt 
$ setfattr -n user.test2 -v テスト2 test.txt 

$ getfattr test.txt #オプションをつけない場合、値までは表示されない。 
# file: test.txt
user.test
user.test2

$ getfattr -d test.txt # -dオプションをつけると、値まで表示される。
# file: test.txt
user.test=0s44OG44K544OI
user.test2=0s44OG44K544OIMg==

$ getfattr -n user.test test.txt #-nオプションで、指定した属性のみ確認できる。
# file: test.txt
user.test=0s44OG44K544OI

上記だと、値がBase64でエンコードされてしまっているため読めない。
そんな時は、-eを使う。

$ getfattr -e text -d test.txt 
# file: test.txt
user.test="テスト"
user.test2="テスト2"

$ getfattr --encoding=text -n user.test2 test.txt
# file: test.txt
user.test2="テスト2"

サブディレクトリの情報を一括で確認したい場合は、-Rを使う。

$ tree
.
└── testdir
    ├── test.txt
    └── testdir2
        └── test2.txt

2 directories, 2 files

# -Rをつけて実行してみる。
$ getfattr -R -d -e text testdir
# file: testdir
user.dir="ディレクトリ"

# file: testdir/test.txt
user.test="テスト"
user.test2="テスト2"

# file: testdir/testdir2
user.testdir2="テストディレクトリ2"

# file: testdir/testdir2/test2.txt
user.test2="テスト2"

おわりに

拡張属性の使い所がわかっていませんでしたが、SELinuxやケーパビリティの設定にも関係してくることがわかったので、より身近なものになった気がします。

Discussion