How should I log from a non-root Debian Linux daemon? - linux

I'm writing a new daemon, which will be hosted on Debian Linux.
I've found that /var/log has root only write permissions, so my daemon cannot write log files there.
However, if it writes there, it appears it will gain automatic log rotation, and also work as a user might expect.
What is the recommended way for a daemon to write log entries that appear in /var/log, without having to be run as root?
The daemon is a webserver, so the log traffic will be similar to Apache.

You should create a subdirectory like /var/log/mydaemon having the daemon's user ownership

As root, create a logfile there and change the files owner to the webserver user:
# touch /var/log/myserver.log
# chown wwwuser /var/log/myserver.log
Then the server can write to the files if run as user wwwuser. It will not gain automatic log rotation, though. You have to add the logfile to /etc/logrotate.conf or /etc/logrotate.d/... and make your server reopen the logfile when logrotate signals it should.
You might also use syslog for logging, if that fit's your scenario better.

Two options:
Start as root, open the file, then drop permissions with setuid. (I don't remember the exact system calls for dropping permissions.) You'll have to do this anyway if you want to bind to TCP port 80 or any port below 1024.
Create a subdirectory like /var/log/mydaemon having the daemon's user ownership, as WiseTechi said.
Files under /var/log aren't automatically rotated; instead, rotation is controlled by /etc/logrotate.conf and files under /etc/logrotate.d.

use the "logger" command
http://linux.die.net/man/1/logger

Related

Linux AWS EC2 Permissions with rsync

I am running a default t2.nano ec2 linux ami. Nothing is changed on it. I am trying to rsync my local changes to the server. There is a permissions issue that I don't know enough about to fix.
My structure is as follows. I'm trying to push my work to the technology directory. The technology directory is mapped to a staging domain. i.e. technology.staging.com
:/var/www/html/technology
this is from the root, and it does work fine, it's the rsync that is failing.
when I push locally to that directory I get a "failed: Permission denied (13)" error.
I'm running an nginx server and assigned permissions to the www directory as follows:
sudo chown -R nginx:nginx /var/www
My user is ec2-user which is the normal default. Here is where I am tripped up. You can see the var directory is given root access.
You can see that the www directory then has permissions set to nginx so our server can access the files. I believe I need to add the ec2-user to this directory as well as the nginx user so that I can rsync my files there and the server will still have access I'm just unsure of how to do that.
As a test, I created a test directory at this location and it worked successfully.
:/home/ec2-user/test
you can see the permission here are set for the ec2-user which is why it works i'm sure.
Here's the command I'm running on my local machine to rsync my files which fails.
rsync -azP -e "ssh -i /Users/username/devwork/company/comp.pem" company_technology/ ec2-user#1.2.3.4:/var/www/html/technology
Here's the command that was working.
rsync -azP -e "ssh -i /Users/username/devwork/company/comp.pem" company_technology/ ec2-user#1.2.3.4:/home/ec2-user/test
I have done enough research and testing to know that it's a permissions error, I just can't figure out the right way to solve it. Do I need to create a group and assign both the nginx and ec2-user to the group and then give that group the same permissions level on the :/var directory.
Side note, what permissions level do I set for the chown to make these permissions that are currently set?
I have server config files in the :/etc/nginx/conf.d/ directory that map to the directories I create inside of :/var/www/html directory so I can have multiple sites hosted on the server.
So in this example, I have a config file at :/etc/nginx/conf.d/technology.conf which maps to the directory at :/var/www/html/technology
Thank you in advance, again, I do feel like I have put forth the research and effort to show that I've gone as far as I know how to do.
The answer made sense after I spent roughly a day playing around. You have to give access to both the ec2-user and the nginx group. I believe you never want to put a user in a group that involves the server itself, I think things would go south.
After changing the owner to both the ec2-user and nginx group, it still didn't work exactly the way I wanted it to. The reason was, I needed the nginx permissions to be updated to what they had when they were assigned the user role.
Basically, theec2-user had write permissions and the server did not. we wanted the user to have write permissions so they could rsync my local files to the directory on the server, and the nginx group needed the same level of permissions to display the pages. Now that I think about it, the nginx group may have only needed read permissions to display things, but this at least solved the problem for now.
Here is the command I ran on the server to update the ownership and the permissions, as well as the output.
modify ownership
sudo chown -R ec2-user:nginx :/var/www/html/technology
modify permissions
sudo chmod -R o=rwx,g+rwx,o-w technology
The end result looks like this
You can see the permissions match, and the ownership is as we expected. The only thing I have to figure out is after I rsync new files to the server, I need to run the previous code to update the permissions again. I'm sure that will come to me later, but I hope this helps anyone in the same situation.

How to run php-fpm as root

I know the risks about running php-fpm as root.
However there are situations where one would need to do it, like appliances,
accessing operating system resources or even for testing purposes.
I have tried to change the user and group of php-fpm.d/www.conf to root
when I restart the php-fpm process it raise an error:
Starting php-fpm: [26-Jun-2014 00:39:07] ERROR: [pool www] please specify user and group other than root
[26-Jun-2014 00:39:07] ERROR: FPM initialization failed
[FAILED]
What should I do. Anyone help?
See:
# php-fpm --help
...
-R, --allow-to-run-as-root
Allow pool to run as root (disabled by default)
Just adding -R (like this ans. suggests) to your command may not work. It depends how your running the command to start php-fpm.
If you're using service php-fpm restart and it's using /etc/init.d instead of systemctl (see here), then you'll have to add -R to the DAEMON_ARGS variable located in the /etc/php/<phpversion>/fpm/php-fpm.conf script. (This variable is used in the do_start() function. See here).
If it's using systemctl then you'll have to edit the script used by systemctl which should be located in /lib/systemd/system/<phpversion>-fpm.service. Append -R to the ExcecStart variable. Then run systemctl daemon-reload and systemctl start php<version>-fpm (See here)
I used the following questions/answers/resources to help me compile this solution.
https://serverfault.com/a/189961
https://serverfault.com/q/788669
https://stackoverflow.com/a/52919706/9530790
https://serverfault.com/a/867334
https://www.geeksforgeeks.org/what-is-init-d-in-linux-service-management/
These 3 steps will fix the error.
Locate php-fpm.service. For me it's /usr/lib/systemd/system/php-fpm.service. If you're not sure where it is, type find / -name php-fpm.service.
Append -R to the ExecStart variable. Eg ExecStart=/usr/sbin/php-fpm --nodaemonize -R.
Restart php-fpm. If systemctl restart php-fpm throws an error, run systemctl daemon-reload.
To anyone else wondering how to make php run as root, you also need to modify /etc/php-fpm.d/www.conf or modify a copy of it. Both user and group need to be changed to root. If you've made a copy of www.conf, you'll also need to modify this line listen = /run/php-fpm/www.sock.
By default, php-fpm is shipped with a "www.conf" that contains, among others, the default www-data user configuration:
[www]
user = www-data
group = www-data
So, you need to create another file, loaded after www.conf, that will overwrite that default config. For example, create a file docker.conf in the same path as your php-fpm's Dockerfile and containing the following:
[www]
user = root
group = root
Then, in your Dockerfile, inject that file in your container with a name that will be loaded after the default www.conf:
COPY ./docker.conf /usr/local/etc/php-fpm.d/zzz-docker.conf
Update 2018
Running it within a container is a possible valid reason to run php-fpm as root. It can be done by passing the -R command line argument to it
Original answer:
However there are situations where one would need to do it, like appliances, accessing operating system resources
You never need to do it. That's it. If you are managing system resources, grant permissions for the php-fpm user to that resources rather than running the whole process as root. If your question would be more specific I could show how to do that in a certain situation.

php5-fpm can't open file for reading

I'm trying to get my php cgi processes to read from a file on my filesystem. Both the file and parent folder have all rwx permissions allowed and the file has the same owner and group id as the php processes, www-data.
No matter how I try to open the file (read(), file_get_contents(), stream_get_contents()) I always get the same error:
failed to open stream: Permission denied
I have no problem opening the file in the php interactive session, using cat on the command line, or with python.
What is going on?
I've seen this problem before on Linux systems with SELinux enabled. The httpd process is typically given its own security context that only allows certain files to be accessed.
You can check to see if SELinux is enabled by running ls --scontext on the file and on the php script. If the two files have the same context or if ls complains about the argument then SELinux is probably not the cause of the problem.
Assuming SELinux is the cause of problem then you could try setting the file in question to have the same security context as your php script with the chcon command. For example:
chcon --reference=/var/www/html/page.php /data/filetoread
where /var/www/html/page.php is your php script and /data/filetoread is the file that you want to access.
It turns out this file was under a FUSE filesystem which had not been mounted with the allow_other option.

Apache access log automatically set permissions

For some tests I'm doing, I'm required to remotely tail the apache access log via ssh. I can successfully do that only when the permissions are accurately set for the log. I've noticed that once a week, a new apache access.log is created and the permissions are reset.
My current work around is editing the permissions on the log once a week:
chmod 644 /var/log/apache2/access.log
I was wondering if there was a more permanent solution such as extending the time that the old log remains or automatically setting permissions when the new log is created.
If it matters, I'm running the server on Ubuntu 11.10
Edit your logrotate.conf file to set the correct owner/permissions for the apache.log file. Something like this:
/var/log/apache2/access.log {
weekly
create 0644 root utmp
rotate 1
}
(Edit: Changed mode from 0744 to 0644. No need to set the execute bit.)
Maybe another application, like logrotate, is altering the logs? (Sounds like it, as it only happens weekly) I don't think Apache itself is responsible for the permissions chance.
A good place to start is check /etc/cron./* to see if any cron jobs are touching the access.log
Good luck!

Must my pidfile be located in /var/run?

I'm asking in both contexts: technically and stylistically.
Can my application/daemon keep a pidfile in /opt/my_app/run/?
Is it very bad to do so?
My need is this: my daemon runs under a specific user, and the implementor must mkdir a new directory in /var/run, chown, and chgrp it to make my daemon run. Seems easier to just keep the pidfile local (to the daemon).
I wouldn't put a pidfile under an application installation directory such as /opt/my_app/whatever. This directory could be mounted read-only, could be shared between machines, could be watched by a daemon that treats any change there as a possible break-in attempt…
The normal location for pidfiles is /var/run. Most unices will clean this directory on boot; under Ubuntu this is achieved by /var/run an in-memory filesystem (tmpfs).
If you start your daemon from a script that's running as root, have it create a subdirectory /var/run/gmooredaemon and chown it to the daemon-running user before suing to the user and starting the daemon.
On many modern Linux systems, if you start the daemon from a script or launcher that isn't running as root, you can put the pidfile in /run/user/$UID, which is a per-user equivalent of the traditional /var/run. Note that the root part of the launcher, or a boot script running as root, needs to create the directory (for a human user, the directory is created when the user logs in).
Otherwise, pick a location under /tmp or /var/tmp, but this introduces additional complexity because the pidfile's name can't be uniquely determined if it's in a world-writable directory.
In any case, make it easy (command-line option, plus perhaps a compile-time option) for the distributor or administrator to change the pidfile location.
The location of the pid file should be configurable. /var/run is standard for pid files, the same as /var/log is standard for logs. But your daemon should allow you to overwrite this setting in some config file.
/opt is used to install 'self-contained' applications, so nothing wrong here. Using /opt/my_app/etc/ for config files, /opt/my_app/log/ for logs and so on - common practice for this kind of application.
This away you can distribute your applications as a TGZ file instead of maintaining a package for every package manager (at least DEB since you tagged ubuntu). I would recommend this for in-house applications or situations where you have great control over the environment. The reasoning is that it makes no sense if the safe costs more than what you are putting inside (the work required to pack the application should not eclipse the effort required to write the application).
Another convention, if you're not running the script as root, is to put the pidfile in ~/.my_app/my_app.pid. It's simpler this way while still being secure as the home directory is not world-writeable.

Resources