Linux защита файла от удаления

Как запретить удаление файла в Linux, даже для Root

Оригинал: How to Make File and Directory Undeletable, Even By Root in Linux
Автор: Aaron Kili
Дата публикации: 10 октября 2017 года
Перевод: А. Кривошей
Дата перевода: июль 2018 г.

В Unix-подобных операционных системах, включая Linux, root — это имя учетной записи или пользователя, который по умолчанию может изменять все каталоги и файлы в системе. В этой статье мы покажем, как сделать каталоги или файлы в Linux недоступными для удаления даже пользователем root.

Чтобы сделать файл неуязвимым для любого пользователя системы, включая root, вам необходимо сделать его неизменяемым с помощью команды chattr. Эта команда изменяет атрибуты файлов в файловой системе Linux.

Приведенная ниже команда делает файл /backups/passwd файл неизменяемым. Это означает, что файл нельзя изменить любым образом: его нельзя удалить или переименовать. Вы даже не можете создать ссылку на него, и никакие данные также не могут быть записаны в файл.

Обратите внимание, что вам нужны привилегии суперпользователя, чтобы установить или удалить этот атрибут:

Для просмотра атрибутов файла используется команда lsattr, как показано ниже:

Теперь попробуйте удалить неизменяемый файл, как от имени обычного пользователя, так и как root.

Как сделать каталог неизменяемым в Linux рекурсивно

Используя флаг -R, вы можете рекурсивно изменять атрибуты каталогов и их содержимого.

Чтобы снова изменить файл, используйте флаг -i, чтобы удалить вышеуказанный атрибут, как показано ниже.

Подробнее о команде chattr вы можете узнать из следующих статей на нашем сайте:

Источник

Блокировка удаления открытого файла

Столкнулся с одной такой вот проблемой: когда я открываю /создаю файл через open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); То почему-то я могу его удалять через консольные команды типа rm А вот как сделать так, чтобы файл нельзя было удалить до тех пор пока я его не закрою? Вообще файл используется для последующего отображения в память через mmap и постепенного изменения некоторых данных в нем. При этом если файл удалить, то маппинг нормально работает и не выдает ошибок. В конце работы даже munmap и close без ошибок выполняются и при этом данные которые изменялись уже никуда не записываются

Имхо без хаков так не сделать. По rm удаляется только ссылка на файл, а сам файл существует, пока открыт хотя бы один дескриптор или существует хотя бы одна ссылка. Хотя может и есть какой-нибудь ядрёный модуль или патч (или можно самому написать), который не даёт удалять ссылки, пока есть открытые дескрипторы.

Насколько мне помнится, файл на самом деле не удаляется, пока открывшая его программа этот файл не закроет.

В том-то, и дело что файл удаляется. т.е.
rm /tmp/test.txt
echo test>/tmp/test.txt
файл удаляется, затем создается с уже новыми данными. А надо чтобы вообще ничего нельзя было сделать с файлами.
P.S. файловая система Ext4

С диска он при этом все равно не удаляется

Читайте также:  Форматирование диска во время установки windows

Ну а смысл что он не удаляется? Если на деле его уже не как нельзя использовать. т.е. после закрытия программы, попытка повторного открытия проваливается. А необходимо чтобы данные были сохранены, и при дальнейшем запуске программы она их могла использовать. т.е. надо чтобы файл мог быть удален только в том, случае если программа которая с ним работает была бы не запущена

Зачем это нужно? Если пользователь хочет сделать rm, то ему виднее.

>А необходимо чтобы данные были сохранены, и при дальнейшем запуске программы она их могла использовать.

Ну можно перед закрытием программы проверять, существует ли ещё этот файл. Если нет, то просто пересоздать его и сохранить данные в него.

Пользователи всегда чего то хотят и постоянно вводят то, что не надо и то о чем их не просили.
Ну если по обычному никак нельзя заблокировать файл, то придется по старинке: пригрозить пользователю сломать пальцы или удалит файл во время работы программы.

unlink удаляет ссылку, а сам индесный дексриптор удаляеться. Когда вы делаете unmap & close, вот тогда драйвер и дескриптор удаляет из файловой системы.

Как вариант, можно после open попробовать поменять права доступа к файлу. Но во-первых, это не атомарно, т.е. существует вероятность, что кто-то удалит файл после open(2) и до fchmod(2), и во-вторых, в домашней папке пользователя удалить файл можно даже если chmod a-rwx filename.

В том-то и дело, что за счет того, что юзается маппинг, то данные периодически автоматически сохраняются в файл. т.е. выходит такая хитрая защита от сбоя. Важные рабочие переменные таким образом сохраняются в файле. И если вдруг по различным причинам программа вырубиться, комп повиснет, свет вырубится, etc. То при следующем старте программы выполнение действий продолжится с последней позиции, если конечно юзверь не удалит файл во время работы.

>Ну а смысл что он не удаляется? т.е. надо чтобы файл мог быть удален только в том, случае если программа которая с ним работает была бы не запущена

Если сделать как в венде, то нельзя будет например обновлять систему без перезагрузки.

Я, признаться, впервые вижу человека, который считает такое поведение неправильным. Зачем тебе держать файл всё время открытым? При запуске открыл — прочитал, перед завершением программы открыл/создал — сохранил, и никаких проблем.

7 лет программирования под Win дают о себе знать, по этому как-то не привычно такое видеть. Тут главное дело — не потерять все данные при сбое. По этому такой метод не подходит.

>Тут главное дело — не потерять все данные при сбое

Ну тут не Win, так что количество сбоев несравнимо меньше. Но если уж очень надо, то можно как во всяких текстовых редакторах: сохранять резервную копию например каждую минуту. И в скрытый файл, чтобы никто случайно не удалил.

man файдовые блокировки (mandatory lock)

По-умолчанию, все файловые операции в unix — неблокирующие, поэтому можно читать и удалять файл, открытый на запись. Делается это для того, чтобы былиотеки и исполняемые файлы можно было обновлять без остановки системы. Если Вам нужно другое поведение — ставьте блокировку.

Читайте также:  Выбираем графическую оболочку linux

Я уже понял что тут не Win. Да и в винде сбоев не так много, больше сбоев когда кое-кто ногами/швабрами провода выдергивает)). Так что лучше всего смериться с тем что файл могут удалить во время работы. Linux вроде такая гибкая система, а простейших вещей нет.

> Так что лучше всего смериться с тем что файл могут удалить во время работы. Linux вроде такая гибкая система, а простейших вещей нет.

Еще раз, Вам сказали, что такие средства есть. Осильте их, пожалуйста и не распространяйте заведомо ложную информацию

> при следующем старте программы выполнение действий продолжится с последней позиции, если конечно юзверь не удалит файл во время работы.

А если удалит – то он ССЗБ, в чем проблема-то?

> man файдовые блокировки (mandatory lock)

flock разве спасает от rm -f?

от него спасает chattr +i

Прекратите лезть со своей BDSMной идеологией в мой уютненький линукс. Если пользователь решил сделать rm, ему действительно виднее и не надо городить дурацкие грабли, которые знающий человек при желании всё равно обойдёт за несколько минут, а заодно знатно обматерит того, кто их придумал. Если не хочешь чтобы файл мозолил пользователю, сделай его скрытым или положи его в /var/tmp/program_name или в

/.config/program_name/ или в какую-нибудь другую подходящую по стандарту FHS директорию. И в мане не забудь описать, что это за файл и зачем он нужен, чтобы потом у пользователя глаза на лоб не лезли от размера

Ставить блокировку? Ну тогда она будет распространяться на все файлы данной ФС, а как то не охото для каждого компа это изменять. От fchmod толку мало. Потому что файл всё равно можно удалить, потому как владелец один и тот же.

> от него спасает chattr +i

Который можно только от рута сделать. И от sudo chattr -i && sudo rm -f он таки не спасет 🙂

Вообще изначально задумка не очень красивая, ибо AFAIK есть ФС, которые ‘теряют’ все открытые файлы в случае неожиданного отключения питания. Ты ведь не станешь говорить пользователям, какую ФС им использовать?

Ладно, тему можно закрыть. Всё равно ни до чего путного не дойдем, как написал anonymous — пользователь у нас всегда прав и всегда знает что делает. Так что все косяки будут с его стороны)

Ладно, подходим тогда с другой стороны: Данных порядка 16 метров. И ты предлагаешь через определенный интервал записывать их на винт? Так система сама бы решала какие участки и когда надо было бы скидывать на винт, а тут придется полностью всё данные записывать. Вообще прога собирается использоваться только для ФС ext3/4

>Данных порядка 16 метров. И ты предлагаешь через определенный интервал записывать их на винт?

Так система сама бы решала какие участки и когда надо было бы скидывать на винт, а тут придется полностью всё данные записывать

> Который можно только от рута сделать. И от sudo chattr -i && sudo rm -f он таки не спасет 🙂

Читайте также:  Нет звука с ноутбука через hdmi windows

Если прога — демон, она может себе и такое позволить. А если не демон, то постановка задачи с затыканием дырки соской в корне неверна. Не могу найти ни одного use case (кроме вирусни), когда пользователь не мог бы удалять файл без ведома проги.

> А если не демон, то постановка задачи с затыканием дырки соской в корне неверна.

Да и если демон, то тоже, вобщем-то.

> лучше всего смериться с тем что файл могут удалить во время работы

Если я решил удалить файл — это мое право, кто ты такой, дабы запрещать мне?

Допустим, ты таки как-то решишь проблему с удалением файла во время работы программы. Но если пользователь захочет удалить файл, то что ему помешает завершить программу и таки удалить его?

ИМХО, проблему защиты данных от пользователя можно решить лишеним пользователя прав на удаление/редактирование файла с данными. Можно сделать демона, который будет выполняться под другим пользователем. Этот демон будет писать в файл, прав на изменение этого файла пользователю-удаляльщику не давать. Пользователю-удаляльщику написать клиент, который будет работать с демоном.

Оставь как есть, это мегафича. Если прям сильно нужно то подправь код файлухи, думаю что это несложно реализовать.

А если ссылок ДВЕ — какую можно удалять, а какую нельзя? 🙂

Очевидно никакую нельзя. Но можно подойти творчески, и сделать проверку: если удаляемая ссылка не является последней, то удалять можно, а если последняя — то нельзя.

А если удаляемый файл является символьной ссылкой? 🙂

в общем небольшой ликбез.

В линукс файл — это грубо говоря индексный дескриптор на разделе с файловой системой (грубо говоря inode с которого начитается файл). А в директории прописаны связки между именами и этими дескрипторами (т.е. файлами). После того, как ты открыл файл по имени, ты уже работаешь с индексным дескриптором, т.е. с файлом и тебе не важно, существует ли в директории связка между именем и этим фалом. Далее, если ты стираешь эту связку, то удаляется имя из директории и уменьшается количество ссылок на файл. Если при закрытии файла количество ссылок 0, то файл удаляется физически драйвером файловой системы с диска.

Так вот. Ты можешь создать жесткие ссылки на один и тот же файл. В этом случае один файл (индексный дискриптор) будет иметь несколько имен. И количество ссылок на файл будет равно количеству имен. При этом, открывая файл по любому имени работать будешь с одними и теми же данными.

Короче, ты можешь создать ссылку (hardlink) на файл, с которым работаешь на той-же файловой (и при этом позаботиться, чтобы ее не так просто было удалить) и перед закрытием проверять, что нужное тебе имя файла еще существует. Если нет, копировать созданный хардлинк в нужное имя.

Решение это кривое, в нем есть куча race conditions, и скорее всего твою задачу можно решить как-то по другому, без защит файла от удаления.

Вот кстати свеженькая заметка о блокировке файлов. Там всё расписано.

Источник

Оцените статью