In addition to standard Unix file permissions, FreeBSD offers an additional layer of file-level security that applies to non-directory files, known as “file flags.”
File flags can be used even to prevent the root user account from altering or deleting files — something that POSIX compliant Unix file permissions cannot do. To check the flags set for a given flag, use the -lo
options for ls
:
> ls -lo foobar.pdf
-rwxrwxr-- 1 bob bob - 0 Nov 19 12:47 foobar.pdf
That dash shows that there are no file flags set for the file foobar.pdf
. Flags can be set using the chflags
utility:
> chflags sunlink foobar.pdf
> ls -lo foobar.pdf
-rwxrwxr-- 1 ren ren sunlnk 0 Nov 19 12:47 foobar.pdf
In the case of each flag, a flag that has been set can be cleared by attaching “no” to the beginning of the flag name:
> chflags nosunlink foobar.pdf
> ls -lo foobar.pdf
-rwxrwxr-- 1 ren ren - 0 Nov 19 12:47 foobar.pdf
A set of octal values may be used to set and unset file flags, using numeric codes rather than longer names. The most useful of these is probably 0
, which clears all file flag settings. The chflags
manpage for FreeBSD provides a complete listing of the octal codes.
Normally, an article like this could point out a few cases where a given set of commands might be useful and direct the reader to the manpage for the relevant utility — in this case, the chflags
utility. In this case, however, the manpage is especially cryptic about what the various flags actually do. It says of them:
arch, archived
set the archived flag (super-user only)
opaque set the opaque flag (owner or super-user only)
nodump set the nodump flag (owner or super-user only)
sappnd, sappend
set the system append-only flag (super-user only)
schg, schange, simmutable
set the system immutable flag (super-user only)
sunlnk, sunlink
set the system undeletable flag (super-user only)
uappnd, uappend
set the user append-only flag (owner or super-user only)
uchg, uchange, uimmutable
set the user immutable flag (owner or super-user only)
uunlnk, uunlink
set the user undeletable flag (owner or super-user only)
The following explains in slightly more detail what each flag does:
- archivedThe
archived
flag is not used by FreeBSD’s standard UFS filesystem, and is only relevant to legacy filesystems. - opaqueThe
opaque
flag ensures that when unionfs is used to mount another directory over the top of the flagged directory, the contents of the flagged directory will not show. - nodumpThe
nodump
flag is of particular use for people using the standarddump
utility to make backups of the system. If a particular file should not be backed up by thedump
utility, setting thenodump
flag will ensure that it is ignored bydump
. Unfortunately, an additional step must be taken to get thedump
command to completely honor thenodump
flag: the-h
option must be used withdump
. This will see to it that the flagged file is omitted from incredmental dumps, but not from full dumps. To omit the file from even full dumps, use the-h 0
option withdump
. - sappendThe
sappend
flag ensures that the flagged file cannot be truncated, and cannot be written to at any point other than at the end of the file. In other words, the only changes that are allowed for that file are changes that are appended to it. This applies to all users, including the root user, without taking the system to single-user mode or reducing thesecurelevel
to 0 or less. - schangeThe
schange
flag makes a file “system immutable,” so that nothing about the file can be altered at all, including metadata. Be very careful setting this flag; even root cannot remove this flag without either taking the system to single-user mode or reducing thesecurelevel
to 0 or less, as with thesappend
flag. - sunlinkThe
sunlink
flag prevents everyone, including the root user, from deleting (unlinking) the flagged file. This overrides any Unix filesystem permissions that otherwise might allow file deletion. - uappendThe
uappend
flag is similar to thesappend
flag, but it can be set and unset by both the root user and the file’s owner without limitation. - uchangeThe
uchange
flag makes a file “user immutable”, just as theschange
flag makes a file “system immutable”. As withuappend
, the “user” version of the “change” flag can be set or unset by both the root user and the file’s owner without limitation. - uunlinkThe
uunlink
flag is similar to thesunlink
flag, but it only prevents the user account that “owns” the file (and those with lesser permissions for the file) from deleting it. The root user account will not be prohibited from deleting the file, unless the root user is the owner of the file — in which case the root user is then prevented from deleting the file.
Some use cases for FreeBSD servers are more suitable to use of file flags, and desktop systems are somewhat less than perfectly suitable to use of file flags. Because the X Window System and certain other pieces of software do not work properly at any securelevel
greater than 0, it is unlikely that such systems would be run at a higher securelevel. Because at securelevel 0 and below the root user can change any file flags on the system, anyone who can achieve root level access to the system can change any file flags, thus circumventing the security value of those flags.
There are ways to work around this problem in some cases. For instance, the X Window System can be started, then the securelevel
increased from 0 to 1, but if you must restart X for some reason you will then have to restart the system to get the securelevel
back to 0.
Under the right circumstances, however, FreeBSD’s file flags can provide a significant improvement to security, particularly for public-facing servers. For instance, it may be appropriate in some cases to run a Webserver at securelevel
1 and use the schange
flag to protect static files that do not ever need to be altered to protect against alteration by malicious security crackers. In fact, in some cases, you may not need anything but your logfiles to be mutable on a public-facing server — and there are even ways around that when logging to another system on the local network, sometimes.