Open Gottox opened 8 years ago
The main point with dropping the privileges is not running tinyproxy as root, so that the process can afterwards not do any serious harm to the system.
Now nobody is a user that can be expected to exist on most linux/unix systems. So that is a natural choice by default.
Linux distributions packaging tinyproxy usually create a tinyproxy user and use this one for running tinyproxy.
I myself am maintainer at void linux and noticed this bug while packaging tinyproxy.
This is not a problem in distributions, we can fix this kind of stuff and I did so for tinyproxy. Anyway, I'd like report such behavior back to the upstream developers to make a better product for everyone.
Thanks for the input. As explained above, this behaviour is intended, and on a generic unix system, there is not much else one can do. Any packager / distributor will create a specific user to use instead of nobody. This is not a fix but the intended process.
What is your proposal of how to make vanilla tinyproxy better?
any thoughts?
@obnoxxx I am observing exactly the same problem on FreeBSD. As @Gottox pointed out, it is not port related but rather present in the packaged itself, similar for many (all?) OSes. Sorry, it seems looks like you might be misunderstanding what @Gottox is asking/suggesting: "nobody" user is not a problem. [*]
The problem is that the dropping root privileges is done before .pid file is created. Since the default location for the pid file on many (all?) systems, /var/run/tinyproxy.pid is in the directory that is owned by root, upon starting, tinyproxy is unable to create that file, and just fails silently, without leaving anything in the logfile.
The first inclination is to create the .pid file before dropping the privileges. But I suspect the problem with that is that then the program might not be able to delete that file upon exiting.
I see that tinyproxy is capable of writing to the logfile (when configured that way, instead of piping it to syslog) even though it is owned by root:
-rw------- 1 root wheel 5942 Nov 18 09:42 /var/log/tinyproxy.log
I suspect it might be keeping the file open with the original privileges. (By the way, if that's the case, that might lead to a problem when the log file is rotated by the system tools (such as newsyslog in FreeBSD)).
If I understand correctly, apache web server deals with this type of probelm by keeping a "control" thread that runs as root. I don't know what type of solutions
The workaround that many people using tinyproxy seem to be implementing is to create a directory /var/run/tinyproxy owned by nobody:nobody with u+w permissions, and to write the pid file into that directory. And this is what e.g. ClamAV seems to be doing. Maybe that's the way to do this?
Additional information: A strange thing though is that the pid file created by tinyproxy is owned by root:nobody, which suggests that may be the root is not dropped completely when the file is created?
>ls -al /var/run/tinyproxy/
total 12
drwxr-xr-x 2 nobody nobody 512 Nov 18 06:12 ./
drwxr-xr-x 14 root wheel 1024 Nov 18 09:41 ../
-rw------- 1 root nobody 6 Nov 18 06:12 tinyproxy.pid
But I see that EUID is changed:
/* Switch to a different user if we're running as root */
if (geteuid () == 0)
change_user (argv[0]);
else
log_message (LOG_WARNING,
"Not running as root, so not changing UID/GID.");
/* Create log file after we drop privileges */
if (setup_logging ()) {
exit (EX_SOFTWARE);
}
/* Create pid file after we drop privileges */
if (config.pidpath) {
if (pidfile_create (config.pidpath) < 0) {
fprintf (stderr, "%s: Could not create PID file.\n",
argv[0]);
exit (EX_OSERR);
}
}
So, I am a bit confused here. Is the file creation assuming uid instead of euid?
Just in case, here are a few examples of what other daemons do. Spam Assassin does something similar:
ls -al /var/run/spamd
total 12
drwxr-xr-x 2 spamd spamd 512 Oct 14 09:40 ./
drwxr-xr-x 14 root wheel 1024 Nov 18 10:41 ../
-rw-r--r-- 1 root spamd 4 Oct 14 09:40 spamd.pid
But ClamAV has all files in its /var/run/clamav directory owned by clamav:clamav:
> ls -al /var/run/clamav
total 20
drwxr-xr-x 2 clamav clamav 512 Oct 14 09:41 ./
drwxr-xr-x 14 root wheel 1024 Nov 18 10:41 ../
-rw-rw-r-- 1 clamav clamav 5 Oct 14 09:41 clamav-milter.pid
-rw-rw-r-- 1 clamav clamav 5 Oct 14 09:41 clamd.pid
srw-rw-rw- 1 clamav clamav 0 Oct 14 09:41 clamd.sock=
srwxrwxrwx 1 clamav clamav 0 Oct 14 09:41 clmilter.sock=
-rw-rw---- 1 clamav clamav 5 Oct 14 09:41 freshclam.pid
Spamd has one of the threads running as root, while all threads of ClamAV are running as clamav user.
[*] From the security point of view, a better solution is to have a separate "dedicated" user for each daemon: clamav for ClamAV, spamd for Spam Assassin, etc. -- to minimize cross-access in case one of the daemons has a vulnerability.
The reports of root owned pid or log files is definitely worth checking out carefully. I'm guessing there is an unhandled exception in change_user().
That said, I'm FAR MORE concerned about this:
You SHOULD set a UserName in the config file. Using current user instead.
There should be no question about it - if EUID=0 and User is not specified, then change to 'nobody' and quit immediately if unsuccessful, Even in debug mode.
Frankly I don't much like that it's parsing configuration file(s) as root. If you have to run root in order to bind a low port, the directive should be required on the command-line: '-p port'. Same with Listen. I would also add a '-u uid:gid' command line option.
I strongly disagree with writing log or pid files as anything but the non-privileged user. TinyProxy is small/simple and running a dozen instances on the box is entirely reasonable. So having a non-priv directory for PID and LOG files is the correct answer.
Since this issue's title is about the log files, I decided to open another issue for the PID files: issue #106.
To combat the idea that the PID file should be created as a non-root user: if the PID file is writable by the non-root user, it is useless, because you can't trust its contents when you want to kill the daemon! The restricted "tinyproxy" user can write "1" to its PID file, and when the admin tries to stop tinyproxy, it will reboot the machine.
The default config uses nobody as uid/gid. This results in an odd behavior that if I use the default config provided by tinyproxy I have allow rw access for the user nobody to the log and pid files. From a security point of view I'd like to avoid any files to be accessible from the nobody user.
main.c
explicitly mentions, that log and pid files are opened after dropping privileges. So I guess it's a desired behavior. What's the reason for this and is there a chance to change the behavior?