# Extended attributes (xattr) - произвольные метаданные файла _Файловая система · LinuxLab Knowledge Base_ **TL;DR:** xattr - key-value метаданные на inode помимо stat. 4 namespace: user (свободно), trusted (root), system (ACL), security (SELinux, capabilities). getfattr читает, setfattr пишет. ## Зачем xattr Стандартный stat() даёт inode'у фиксированный набор: размер, владельцы, mtime, права. Иногда хочется хранить ещё что-то рядом с файлом - **подпись, хеш, тег, mime-type, Origin URL загрузки**. xattr - стандартный механизм для этого. Классические users xattr: - **`user.mime-type`** - GNOME / KDE для иконок - **`user.charset`** - apache mod_mime для статики - **`user.com.dropbox.attributes`** - Dropbox-метки - **`user.checksum.md5`** - кастомные хеши Системные xattr **активно используются ядром**: - **`security.selinux`** - метка SELinux ("user_u:object_r:..._t") - **`security.capability`** - file capabilities (cap_net_bind_service) - **`system.posix_acl_access`** - [[posix-acl|POSIX ACL]] хранятся именно тут - **`system.posix_acl_default`** - default ACL директорий ## Namespaces | Namespace | Кто пишет | Кто читает | Что | |-----------|-----------|------------|-----| | `user.*` | любой с правом write на файл | владелец и подобные | свободные данные приложений | | `trusted.*` | только root (CAP_SYS_ADMIN) | root | системные tools, FUSE-драйверы | | `system.*` | ядро | ядро | ACL и подобные структуры | | `security.*` | LSM (SELinux, AppArmor, IMA) | LSM | метки безопасности и capabilities | Лимиты: - Имя ≤ 255 байт - Значение ≤ 64 KiB на одной ext4 без `-O ea_inode` (на больших - в отдельном блоке) - Суммарно на ФС - сильно зависит от inode size; на xfs с `-i size=1024` помещается больше встраиваемых ## getfattr - чтение ```bash $ getfattr -d file.txt # все user.* (по дефолту) # file: file.txt user.mime-type="text/plain" $ getfattr -d -m '.*' file.txt # все namespace (нужен root для security/trusted) # file: file.txt user.mime-type="text/plain" security.selinux="unconfined_u:object_r:user_home_t:s0" $ getfattr -n user.mime-type file.txt # file: file.txt user.mime-type="text/plain" $ getfattr -n security.capability /usr/bin/ping # file: /usr/bin/ping security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAAA ``` Опции: | Опция | Что | |-------|-----| | `-d` | dump - все атрибуты | | `-n NAME` | конкретный | | `-m PATTERN` | regex для имени; default `^user\.` | | `-h` | если symlink - не следовать | | `-R` | recursive | | `--only-values` | только значение, без шапки | ## setfattr - запись ```bash setfattr -n user.tag -v "important" file.txt setfattr -x user.tag file.txt # удалить setfattr -n user.json -v "$(cat data.json)" file ``` Бинарные значения (hex): ```bash setfattr -n user.bin -v 0xdeadbeef file.txt ``` ## Реальные применения ### File capabilities Linux capabilities делят root-привилегии на ~40 битов. `security.capability` xattr на бинарнике даёт ему **только нужные**: ```bash # Дать ping право слать ICMP без setuid setcap cap_net_raw+ep /usr/bin/ping getcap /usr/bin/ping # frontend поверх getfattr # То же напрямую getfattr -n security.capability /usr/bin/ping ``` Это безопаснее `setuid` - подробнее в [capabilities](/kb/capabilities.md). ### SELinux метки ```bash $ getfattr -n security.selinux /etc/passwd # file: etc/passwd security.selinux="system_u:object_r:passwd_file_t:s0" ``` При `cp` без `--preserve=context` SELinux-метка **теряется** и ставится дефолтная для целевой директории. На прод-сервере это частая причина "файл скопировался, но программа не может прочитать". ### ACL POSIX ACL **физически хранятся** как xattr: ```bash $ getfattr -m '^system' file.txt system.posix_acl_access=0sAgAAAAEABwD/... ``` Не редактируй напрямую - используй [[posix-acl|setfacl]]. ### IMA / EVM Integrity Measurement Architecture хранит подписи в `security.ima` и `security.evm`. Используется в hardened-системах для measured boot и runtime-integrity. ## xattr и cp / tar / rsync По дефолту **не переносятся**. Это самый частый баг: - `cp -a` (archive) - **переносит** xattr - `cp` без флагов - **не переносит** - `tar` - нужен `--xattrs` (и `--xattrs-include='*.*'` чтобы захватить все namespace, иначе только `user.*`) - `rsync` - нужен `-X` (`--xattrs`); включи также `-A` для ACL Скопировать SELinux-context при cp: ```bash cp --preserve=context file new # или для всего дерева cp -a /src /dst # -a включает -p со всеми атрибутами ``` ## Поддержка по ФС | ФС | xattr | |----|-------| | ext4 | да; для больших значений `-O ea_inode` | | xfs | да; помещаются в крупный inode | | btrfs | да | | tmpfs | да (с ядром >= 6.0 для security namespace) | | nfs | NFSv4 - частично | | fat/vfat | нет | | iso9660 | нет (старая RR-extension - частично) | При `mount -o nouser_xattr` - user namespace отключён, остальные работают. ## Размер и производительность - В inode-резервированном пространстве - бесплатно (часть RAM/IO для inode) - Большие values - в отдельном блоке = +1 IO на чтение - При очень многих xattr на одном файле - заметные тормоза `ls -l`, т.к. ядро может проверять каждый ## Когда что-то пошло не так - **`Operation not supported`** - mount без `user_xattr` или ФС не умеет (vfat). На ext'е это default давно, но тонкие FUSE-mount'ы могут не уметь. - **`Permission denied`** при `setfattr -n trusted.*` или `security.*` - нужен root и соответствующая capability (`CAP_SYS_ADMIN` для trusted). - **xattr пропали после cp/tar/rsync** - не было соответствующего флага. - **SELinux denied** после переноса - метки не скопировались. `restorecon -Rv` вернёт дефолтные для целевой директории. - **`No space left` при свободном диске** - ext4 может упереться в лимит на ea-блоки. `tune2fs -l | grep -i ea`. Возможно нужен `-O ea_inode` (требует remkfs). - **`Argument list too long`** - имя или value превысили лимиты. ## Альтернативы - **Resource forks (macOS)** - схожая идея, не переносится в Linux - **Side-car файл** (`file.metadata.json`) - простой, переносится через cp/scp без флагов, но риск рассинхрона - **БД** - если метаданных много и они часто запрашиваются - **xfs project IDs** - для квот на поддерево, не для произвольных тегов ## Команды ```bash getfattr -d -m '.*' /etc/passwd ``` Все xattr файла включая security/system - нужен root ```bash setfattr -n user.tag -v 'review' file.txt ``` Поставить пользовательский тег - простой случай ```bash setfattr -x user.tag file.txt ``` Удалить конкретный xattr - не значение, а саму запись ```bash getcap /usr/bin/ping ``` File capabilities (через xattr security.capability) - что разрешено бинарнику без setuid ```bash rsync -aXA /src/ /dst/ ``` Скопировать с xattr (-X) и ACL (-A) - иначе всё потеряется ```bash tar --xattrs --xattrs-include='*.*' -cf backup.tar /etc ``` tar с переносом ВСЕХ xattr namespace (по дефолту только user.*) ```bash find / -xdev -exec getfattr -h -d -m security {} \; 2>/dev/null | head ``` Найти все файлы с security xattr на корневой ФС - аудит SELinux/IMA ## См. также - [POSIX ACL - расширенные права доступа](/kb/posix-acl.md) - [File permissions: rwx и chmod](/kb/file-permissions.md) - [Linux capabilities - биты привилегий](/kb/capabilities.md) - [SELinux и AppArmor - Mandatory Access Control](/kb/selinux-apparmor.md) - [Inode](/kb/inode.md)