Is there a way to protect a file in such a way that even
root cannot delete it or rewrite it after creating it?
I have a file which is created by
/var/log/ and I want to restrict all users (including
root) so that they can just read this particular file after it has been created.
Is there a way to protect a file in such a way that even
No there is no way to do this, to my knowledge. The answer about
chflags pertains to BSD variants. A similar command for Linux is
The concept of the root user is that they can do anything on the system.
You may be looking for the "system immutable" flag. The details may depend on precisely which operating system you're running, but the basic idea will be the same. You'll want something like this in BSD (or OSX):
# chflags schg /path/to/file
or the equivalent in Linux:
# chattr +i /path/to/file
Note that root can always remove the system immutable flag in order to change the file, so your next option is to place the file on a read-only filesystem. Even so, with root access one might still be able to unmount a read-only filesystem and mount it read-write.
The next step would be to put it on a physical disk that has a write protect switch. Check with your vendor to see if this is available with your hardware. If it is not, you could consider putting the files on a WORM drive of some sort. A CD-R is an option.
What about putting the file on a read-only NFS filesystem stored on another server?
Probably easier to figure out a better solution to this XY problem.
Generally speaking, root can do everything. Whatever steps you take to prevent root from doing something (such as setting file attributes), root can undo.
OpenBSD and FreeBSD have a notion of security level, also known as securelevel. The securelevel is an integer value. If the value is negative or 0, only the usual unix security rules apply. At securelevel 1 and above, a number of restrictions come into place, in particular:
- It is impossible to reduce the value of the securelevel.
- It is impossible to load or unload any kernel module. Thus the code running in kernel mode cannot change anymore.
- Raw access to the memory or block devices is disabled.
- The chflags system call denies attempts to remove the immutable or append-only flags from any file.
Securelevels 2 and 3 add additional restrictions. The important thing is that it is impossible to reduce the security level without rebooting, even with root access. Thus securelevels bring in restrictions to what root can do, at the expense of making certain maintenance tasks impossible (such as repairing or reconfiguring a RAID array).
Of course these restrictions are only effective against users who do not have access to the physical machine or to a console during boot. The bootloader data (including the kernel file) must be immutable, otherwise a root user could introduce a backdoor and trigger or wait for a reboot.
It may be possible to configure something like this with Linux's security frameworks (AppArmor, SELinux, …), but these are primarily tools to set restrictive policies for processes that are not running as root. If it is at all possible, it would require a lot of care in defining the policy (even in the ordinary case, designing useful policies is hard).
If you don't have the option to restrict root's power in this way, the way to make a file read-only for root is to store it on a different system. Options include:
- Run the system in a virtual machine and store the file on the host.
- Store the file on another system accessible via the network.
- Store the file on a physically read-only media.
Seems like the only valid way is to use
chattr command as follows:
chattr +i /var/log/file
This way even root cannot modify the file unless it removes the
i attribute from the file.
So it is just one step toward a better protection I think.
Will the file be frozen, or do you need to keep writing to it? In the first case, you could put the file on a read-only medium: CD-ROM, flash drive with a physical write-protect switch, etc. (That protects the integrity of the file, but wouldn't prevent root from unmounting it and/or masking it with a fake).
If you want to continue writing to the log file, there's no solution unless you can find a write-once-read-many physical medium: If a file can be written to, it can be overwritten. (For completeness: It is possible to set a file's "append-only" attribute with
chflags, which will protect the file contents from being overwritten. But it is not possible to block root from unsetting this attribute.)
chattr can do this, or at least something pretty close to it. There are two attributes that may be relevant, depending on what exact behavior you want.
For example, you may want to set the
a attribute, using
chattr +a filename:
A file with the `a' attribute set can only be open in append mode for writing. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
Since this would seem to be a log file, that may be the more appropriate option. Or you can use the
A file with the `i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file. Only the superuser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.
Note that the superuser can clear these attributes with the corresponding
chattr -X command.
This doesn't answer the exact question asked, but an alternate solution is to have the log live on a different server / VM, make it append-only using
chattr +a and then mount it over the network. This is not without drawbacks, but in my opinion is one of the best approaches to solving this problem.