How do I create a safe and secure cron job for running PHP scripts of my website?
I'm creating a PHP installation script for Ubuntu 16.04.3 LTS Server. The script copies files from my installation package to /var/www/mysite
and sets appropriate read/write permissions for default Apache web user account, which is www-data
:
setfacl -R -m u:www-data:rX /var/www/mysite
setfacl -R -m u:www-data:rwX /var/www/mysite/storage /var/www/mysite/bootstrap/cache
setfacl -dR -m u:www-data:rwX /var/www/mysite/storage /var/www/mysite/bootstrap/cache
Now, as the final step of my installation script I have to install cron jobs that call PHP commands on my site, for example, like this one:
php /var/www/mysite/artisan notifications:send
I have done some research and found multiple options and possible complications, so I'm not sure what would be the most correct and error free way to create a cron job in my situation.
Specific thoughts and questions:
it seems, the best place to install cron jobs that do not belong to a specific user but to services running in background would be
/etc/cron.d
, right? It also seems safe choice for automated installation process because I won't have to change any existing cron config file from my installation script but just add a new file, if it doesn't exist yet.I don't want to run my jobs as root; that might be not good idea for websites, right? So I will need a dedicated user. At first I thought - hey, I already have
www-data
user created for Apache server and with all required permissions for my site, so I could use that, right? But I've read thatwww-data
user actually has no permissions to execute shell commands! So, I would have to change the permissions ofwww-data
(which seems not a good idea) or I should create a new user account specifically for my cron jobs, such asmysite-jobs
. But how do I safely check existence of this user and if it does not exist then create the user from my installation script? And how do I specify its permissions so cron can runphp /some/command
as this user but the user itself does not have/home
nor password and cannot normally login?also, I've read that environment variables are not automatically available for jobs in
cron.d
, so I have to specify them in my cron file. Technically, it might look like this, right?SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
My guess is that this might also automatically fix the problem of launching PHP commands in the previous point, but I'm not sure if I'm not giving too much permissions here - I don't want the user to execute any shell command or any command from those bin and sbin directories but php /some/command
only. And also this makes me wonder - if I have to specify SHELL and PATH variables for cron to use for this job only, then maybe it's safe to use www-data
after all - those environment variables won't leak out of the cron job, right? But I'm not sure if they will be effective for www-data
at all, considering that it is a "special" account.
- after I create a cron job in
/etc/cron.d
, will it be picked up by cron immediately or do I have to somehow notify cron about new (or possibly updated when I update websites) file?
So, considering all of the above, how should the final cron job look and how do I specify user account with minimal permissions to run my php commands?