named should have a dedicated configuration directive to define the server working directory
Recent changes in BIND (most likely, DNSSEC NTA support) have made it such that named creates various temporary/transient files in the
Before these changes, it was possible (at least in configurations that served only static zones) to locate all files that named writes in other directories (typically, subdirectories of
directory). On Linux systems that employ SELinux, this makes it possible to create SELinux policy that prevents named from modifying the
directory directory (traditionally
/var/named). And indeed, this has been the default SELinux policy for multiple years.
The fact that named now insists on writing temporary/transient files into
directory, with no way to override the location, is poor design that compromises security.
Named writes to the directory in the
directoryclause if you don't supply a more specific location for the item needing to be written named.conf (BIND 8, BIND 9) or named.boot (BIND 4). This directory has always been documented as needing to be writable. This was well before Linux existed let alone SELinux.
I would argue that
directory is not documented as needing to be writable. Its entry in the ARM states only:
It is strongly recommended that the directory be writable by the effective used ID of the named process.
That's it. Strongly recommended ≠ required. Furthermore, there is no explanation why this needs to be the case, except for a passing mention in the
managed-keys directive documentation, which makes no claim to be inclusive.
It is perfectly reasonable to conclude, from reading the ARM, that as long as one explicitly locates files which need to be writeable in some location other than
directory, then named does not require
directory to be writable.
But even if the requirement for
directory to be writable were explicitly listed as a requirement in the ARM, this is not the correct solution.
As it currently stands,
directory has two functions:
- It is the base directory for any non-absolute pathname in the configuration file.
- It is the working directory of the server, where transient files or other output files that are not explicitly located elsewhere are created.
These are distinct and unrelated roles. The decision to combine them was made in the days before Canter and Siegel, when sendmail had the WIZ and DEBUG commands, and everything available on the Internet was listed on a 4-page text file available at Rutgers' FTP site. It was a decision that was a product of the security thinking of its time—which is to say, none at all.
But the Internet of 2019 is a different place than the Internet of 1989. Security tools like SELinux are a reflection of that. Today, designing a piece of software that requires the root directory of its configuration/data tree to be writable is recognized as a poor design decision from a security perspective. And while I do not wish to place words into the mouths of SELinux policy authors, I suspect this is why SELinux policy attempts to block named from writing to the
named should divorce the "this is the directory where I will write random temporary files to" role from the "this is the parent directory of any non-fully-qualified filename" role. The
directory directive should retain the latter role, and a new directive (e.g.,
temporary-directory, or perhaps
working-directory) should be created to instruct the server what directory to use as its working directory, which includes transient files.
Backwards compatibility can be assured by defaulting
working-directory is not explicitly specified in the configuration file.
And yes, it is possible to separate these roles without an additional configuration directive, by (e.g.) defining
directory as a subdirectory of
/var/named. But doing so requires specifying absolute paths everywhere in the configuration file. This is repetitive and error-prone.