POSIX compliant Unix file permissions can be reinforced by additional filesystem protections called "file flags" on FreeBSD. Chad Perrin explains in detail what these flags do.
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 -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 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:
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)
set the system append-only flag (super-user only)
schg, schange, simmutable
set the system immutable flag (super-user only)
set the system undeletable flag (super-user only)
set the user append-only flag (owner or super-user only)
uchg, uchange, uimmutable
set the user immutable flag (owner or super-user only)
set the user undeletable flag (owner or super-user only)
The following explains in slightly more detail what each flag does:
archivedflag is not used by FreeBSD's standard UFS filesystem, and is only relevant to legacy filesystems.
opaqueflag 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.
nodumpflag is of particular use for people using the standard
dumputility to make backups of the system. If a particular file should not be backed up by the
dumputility, setting the
nodumpflag will ensure that it is ignored by
dump. Unfortunately, an additional step must be taken to get the
dumpcommand to completely honor the
-hoption must be used with
dump. 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 0option with
sappendflag 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 the
securelevelto 0 or less.
schangeflag 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 the
securelevelto 0 or less, as with the
sunlinkflag prevents everyone, including the root user, from deleting (unlinking) the flagged file. This overrides any Unix filesystem permissions that otherwise might allow file deletion.
uappendflag is similar to the
sappendflag, but it can be set and unset by both the root user and the file's owner without limitation.
uchangeflag makes a file "user immutable", just as the
schangeflag makes a file "system immutable". As with
uappend, the "user" version of the "change" flag can be set or unset by both the root user and the file's owner without limitation.
uunlinkflag is similar to the
sunlinkflag, 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.