in reply to Re^3: Best way to write to a file owned by root?
in thread Best way to write to a file owned by root?

System files like /etc/hosts are not owned by user root, group root (or bin) by chance, but intentionally. Making them writable for the webserver (or any other group) opens a way for remote file modification. One stupid bug in a CGI or a PHP script might be sufficient.

A much cleaner approach would be a dedicated service (i.e. a daemon) whose sole purpose is to modify files as root. An unprivileged program (like a CGI, or a user program) contacts the service, and passes either a modification command or a completely new file. Typically, this would be done via a named pipe (FIFO) or a unix domain socket. The service does three things:

  1. Check if the client is allowed to change the file
  2. Check if the modification command / new file is valid
  3. Modify / replace the file as root

The first check may prevent any user but the administrative webserver's run accound to modify files; it also prevents access to arbitary files. You usually don't want to allow anybody to overwrite /etc/passwd.

The second check prevents garbage files that may make the system unusable.

Together, this prevents direct and unverified modification by arbitary programs, without giving out privileges to an entire group of programs.

A quite large system that uses this technique (Privilege separation) is postfix. Unlike sendmail, which runs as a monolithic setuid root binary, postfix uses various services, with as few privileges as possible.

Update: Found a related PDF by Theo de Raadt of OpenBSD regarding privilege separation, enforced by the OpenBSD kernel.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
  • Comment on Re^4: Best way to write to a file owned by root?

Replies are listed 'Best First'.
Re^5: Best way to write to a file owned by root?
by nysus (Parson) on Mar 14, 2017 at 22:25 UTC

    Thanks for the good info. This is interesting to think about. Fortunately, I'm just writing a script under my total control on my own local machine and does not have processes available to the public. Basically, it's just automating a task that I would do manually with sudo vim /etc/hosts command anyway. I'm trying to figure out how to do that with the least risk of breaking something. I *think* my code accomplished that because it makes a copy of the /etc/hosts file, makes the ownership and privileges changes to copy of the file and, if those are successful, only then copies the modified file back to /etc/hosts. Also, the file is read only only by my account so no one else can look at it.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

      I'm just writing a script under my total control on my own local machine and does not have processes available to the public.

      So it has no network connection? I don't think so.

      I *think* my code accomplished that because it makes a copy of the /etc/hosts file, makes the ownership and privileges changes to copy of the file and, if those are successful, only then copies the modified file back to /etc/hosts.

      Replace the last step with a rename. Rename is atomar, copy is not. And yes, rename will work for an existing file:

      /tmp>echo bla > one /tmp>echo blubb > two /tmp>mv two one /tmp>cat one blubb /tmp>echo bla > one /tmp>echo blubb > two /tmp>perl -e 'rename "two","one" or die $!' /tmp>cat one blubb /tmp>
      Also, the file is read only only by my account so no one else can look at it.

      /etc/hosts should have mode 0644, not 0400 or 0600. Even if only you work with your computer, it still uses several different user accounts to do its job. And some of those user accounts need to resolve host names, i.e. read /etc/hosts. Even if they only need to resolve localhost to ::1 or 127.0.0.1.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        I'm no security guru (clearly) so tell me if I'm wrong. Yes, it is true my local machine is connected to the Internet. But anyone who hacked my machine would need my account access to run or even read my script. If someone has hacked my machine with my user account, it seems like they are in a very good position of changing my /etc/hosts file without my script to help them. Right?

        My /etc/hosts file is 0644. I was saying my script that I use to automate the appending to /etc/hosts has perms of 700. Sorry for the confusion.

        $PM = "Perl Monk's";
        $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
        $nysus = $PM . ' ' . $MCF;
        Click here if you love Perl Monks