6

I know about the chattr +i filename command which makes a file read only for all users. However, the problem is that I can revoke this by using chattr -i filename.

Is there a way to make a file readable by everyone on the system, but not writable by anyone, even the root, and with no going back (No option to make it writable again)?

  • 12
    I don't think there is a way to do that. You would always be able to "go back" if you are root. What is it you are trying to accomplish with this? Maybe we can come up with another solution. Does someone else have root access to your system but you don't trust them? – Malte Skoruppa Dec 23 '17 at 16:28
  • 2
    Depending on what you're trying to accomplish, you might want to digitally sign the file using public key encryption, so that although someone could modify it, other people would be able to detect that. – Ben Crowell Dec 24 '17 at 1:19
  • Honestly, it just doesn't make sense to do this in practice. It's a perfectly good question to ask out of curiosity, but if you actually have a situation where you want to prevent a person with root access from modifying a file, you have much bigger problems than can be solved with filesystem permissions. – David Z Dec 24 '17 at 8:13
17

Put it on a CD or a DVD. The once-writable kind, not the erasable ones. Or some other kind of a read-only device.

Ok, I suppose you want a software solution, so here are some ideas: You could possibly create an SELinux ruleset that disables the syscall (*) that chattr uses, even for root. Another possibility would be to use capabilities: setting +i requires the CAP_LINUX_IMMUTABLE capability, so if you can arrange the capability bounding set of all processes to not include that, then no-one can change those flags. But you'd need support from init to have that apply to all processes. Systemd can do that, but I think it would need to be done for each service separately.

(* maybe it was an ioctl instead.)

However, if you do that, remember that a usual root can modify the filesystem from the raw device (that's what debugfs is for), so you'd need to prevent that, too, as well as prevent modifying the kernel (loading modules). Loading modules can be prevented with the kernel.modules_disabled sysctl, but I'm not sure about preventing access to raw devices. And make all the relevant configuration files also immutable.

Anyway, after that, you'd also need to prevent changing the way the system boots, otherwise someone could reboot the system with a kernel that allows overriding the above restrictions.

  • 7
    And don't forget about mount --bind modified-file original-file, which often achieves the same result as modifying the file without actually doing so – Fox Dec 23 '17 at 17:15
  • 1
    chatter +i is advisory as well. /dev/sd?? are writable as root and I can think of a host of other ways. SELinux kind of works. – Joshua Dec 23 '17 at 22:04
  • 1
    If you are root you can revert the changes anyway (you just need to be more capable). – Thorbjørn Ravn Andersen Dec 24 '17 at 1:56
  • Yeah, that's pretty much the point, you'd need to first prevent modifying the file, and then prevent making changes to the restrictions. – ilkkachu Dec 24 '17 at 13:22
3

There is no way to do this. SOMEONE will always be able to revert the file to a writable status, unless it's on read-only media like a CD-ROM. You can effectively prevent root from doing so using SELinux permissions (I don't know how to do so, or I would provide an example), but then the user that does have permissions would still be able to undo things.

  • A funny twist would be to put the file on a file system that can only be read. So, the medium itself can be anything, if the fs is read only. However, good luck with putting the file there initially. – Oleg Lobachev Dec 23 '17 at 22:12
  • @OlegLobachev: maybe a FUSE mount of a tar.gz archive? Or any filesystem where the Linux driver doesn't support read-write mounts. But then you've only shifted the problem to modifying the underlying block device or file directly, instead of through the mount. Still potentially useful depending on your "threat model" or whatever it is you want this for, but physically write-once (or write-once outside the control of the hardware of this machine; e.g. a storage server or a custom USB device) is the only way to e.g. protect log files from an attacker that gets in. – Peter Cordes Dec 24 '17 at 3:22
3

What you want is Mandatory Access Control. It allows you to specify a set of permissions which the kernel will not allow to be overridden, even by root. SELinux is one well-known such system, Smack is another example, and AppArmor is a third such system. In Linux, they are implemented as Linux Security Modules, a general-purpose facility for controlling access outside the traditional UNIX-like security model. In addition to the existing general-purpose systems, you could of course create your own for a special purpose.

Of course, root has the ability to turn the entire facility on or off or change the MAC permissions of files, and some of these systems even allow those capabilities to be granted to non-root users. However, it's also possible, depending on the system, to disable this ability. I know SELinux and Smack make this possible; I doubt all LSMs do. Once disabled, the only way to regain the ability is to reboot the kernel. You will then want your boot process to disable the capability before user access is enabled. If your kernel and boot process are secure, such a configuration could (at least in theory) be changed only by physically removing the storage media to change it.

As an example, if you were using SMACK, you could do:

chsmack -a _ <file>

This would set the file to have the special label "_" which allows only read or execute access, but never write. Now even root cannot write this file (once SMACK has been activated and the security override capability has been disabled, as mentioned above).

However, you must also ensure that your kernel is secure. By default, it is easy for root to subvert the kernel, because the kernel trusts the root user. If root can just remove the security module, it doesn't help very much. A list of such methods is here, but note that no such list can ever truly be complete for all circumstances.

Finally, depending on your circumstances, you may need to secure your boot process. For a machine where you have sole physical access, this might not be needed, but for maximum security you really want encrypted filesystems and a secure way of booting the kernel, such as UEFI Secure Boot.

1

For completeness, BSD securelevel feature allows doing what you want. Linux doesn't have an equivalent option.

0

"Is there a way to make a file readable by everyone on the system, but not writable by anyone, even the root, and with no going back"

Couple of thoughts on this:

(1) If you use a writeable CD or DVD, it becomes readonly for everyone. There is no going back.

(2) Some external media have WriteProtect Switches and WriteProtect flags, which even root user can not disable; It requires a human to remove the WriteProtect switch, and WriteProtect flag can not be reset.
If you can use that WriteProtect Switch with your card hardware, you can control the writes; Even root can not control it.
If you set the WriteProtect flag, there is no going back.
(thanks to @fluffysheap for making this more accurate)

(3) If you have the file on a file system on the local machine, then who-ever wrote it initially can undo the changes and then change the file. Hence it is not possible to satisfy your conditions.

(4) With local file, the nearest you can get is to use a virtual Disk or ISO Image file; When it is mounted, it will not allow writes. But root can make a new ISO with new content, and write that new ISO onto the original.

(5) If the file is on some other server, then here is a solution. Configure a web (HTTP or HTTPS) server or FTP server or NAS server on a remote machine. All local users (including root) should be allowed to access it either by mounting (remote server should give only readonly access) or over HTTP or FTP (for example) ; there will be no way for local users to write to that server or to disable this restriction. Even local root can not write there. You require root access on remote server to change the file.

  • SD cards are a bad example, as the physical write-protect switch simply sets a flag to be read by software. The write-protect switch was more meaningful on floppies where it was enforced by the drive hardware. You can set a permanent write protect flag, if supported by your hardware, with software such as SDTool (github.com/BertoldVdb/sdtool) - however this setting is irreversible. – fluffysheap Dec 24 '17 at 9:24
  • @fluffysheap , thanks for the comments. I was not aware of this flag. Also, while I did not want to mention the floppy (which is too old) I did mistakenly think that the switch was enforceable like that on the floppy. I will update the answer. – Prem Dec 24 '17 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.