Restarting a job (upstart) in a php script - php

I am currently writing the admin portal for my most recent project. I have been fighting with my computer to get upstart working, and now that it is, I wanted to be able to operate upstart from the web. I need to execute the following in my php script
sudo restart job
sudo start job
sudo stop job
as you can see sudo is the theme of those commands, so I need to somehow run sudo from this php script. How can I attack this problem, or is there a work around for this.
in case it matters:
# which start
/sbin/start
# which stop
/sbin/stop
# which restart
/sbin/restart

I see several approaches. You could certainly add www-data to the sudoers list, and then either hard-code www-data's password into your script (not so good) or read it from a file (a little better) to make sudo work. If you go this route, you'll probably need to manually override www-data's password, since it doesn't really have a usable password. Either of these approaches should be discouraged because www-data is deliberately stripped of most privileges as a security measure. Granting it a big one (like sudo) and putting its password in a file or script creates a significant security vulnerability.
You might be able to grant www-data very limited sudo privileges that enable the functionality you need without opening up too many security holes. Read up on sudo and the sudoers file for more information.
A better approach might be to write a script that takes a start/stop/restart argument and invokes the appropriate upstart command. The trick is to make this script setuid root (chown root:root script.sh; chmod +s script.sh), so that it runs as root instead of www-data. Give this script 755 permissions so only root can change it. This limits the security risk and still gives you the powers you need, but no more.
The setuid approach probably won't work directly on your system (try it first), since most Unix systems these days deliberately disable setuid for working as advertised on shell scripts since the security risk is too high. Here is an article that explains a workaround that uses a C program (on which setuid still works) to invoke your script. It is a little convoluted, but it should work.
Possibly the best approach would be to leverage upstart's event mechanism and have your web code fire events that upstart would catch and forward to your .conf file. I am just learning upstart myself, so I can't give you more specifics, but I get the sense it is meant to be used this way.

Related

Is the "--no-scripts" option enough to account for the security concerns about running composer as root?

I would like to make .sh file for automatic deploy web pages from github to production. I need to run composer install in it but as I run it, it throws me a warning:
"Do not run composer install as root super user!"
I found out this is because of security reasons. But I need to run also other commands which needs to e.g. delete some files and directories.
The solution I found to fix this is:
composer install --no-scripts --no-interaction
The question is: Is it enough? Is --no-script the solution or not? What is the best practice regarding running composer as root?
Best practice is not to use sudo for composer commands at all. If you need sudo for composer, it usually points at your project's file permissions not being setup correctly.
E.g. you should have a non-root user owning the projects directory, and you should run the needed commands as that user, without requiring sudo. If you need to run as root, it probably means that you did so in one of your previous runs, and already messed up your file permissions.
(Best practice is also not running install in production in any case, but at least you are not running update)
In the rarer cases where you need to run composer as a superuser, and you are not on a very constrained environment (say, building a Docker image), you should pay attention to the official guidance and not only use --no-scripts, but also the parameter --no-plugins, so you are only doing file copying and not executing other scripts.
Run as a user who has privileges to delete the "files and folders" you're talking about.
If such a user does not exist, create one, assign ownership/privileges and then run composer under that user.
Simply running it as root just to delete a handful of known folders is a weak argument.
I do not know the security implication of the following code but it seems to stop the issue; at least it removes the notice. I could be dangerous and if so please let it be noted in the comment or the answer be edited by anyone having the authority:
export COMPOSER_ALLOW_SUPERUSER=1; composer show;

Restart Nginx through a PHP Script

I'm currently working to make a WordPress plugin of mine compatible with nginx. This plugin requires access to a .conf file in the wp-content/uploads directory, so that it can add in the required rules. Currently, it updates an .htaccess file in the same directory, and the changes take effect immediately without intervention. Because nginx requires service nginx reload to allow configuration changes to take effect, I am looking for a way to do that in my script. I'm not sure that even exec() would work for this, as service nginx reload is required to be run as root or using sudo. I've searched far and wide on StackExchange, Google, and everywhere else that I know of, and I can't even find a starting place.
Security wise, it would be a VERY bad thing to give the user that runs the web server sudo/root access. Rather, you could use a semaphore file and have a cron job run by root that runs every 5 minutes (or higher frequency if required) that looks for the presence of this file. If present, it issues the service nginx reload command and deletes the file.
My Suggestion
Overall I think the best solution would be to have your plugin create specific instructions for the user to edit any Nginx config manually and then reload Nginx themselves.
I believe this because giving PHP the ability to run a command that usually requires sudo requires opening up a large security hole.
On top of that, the methods that a user would have to do in order to allow PHP to run the service nginx reload command is not something you can accomplish in PHP alone, and may be equally, if not more, complex than having them update Nginx config and reloading themselves. The user needs to do extra work regardless!
If you really want to do this:
If you still choose to go down this course of action, I suggest having users of the plugin edit the server's /etc/sudoers file, which can allow user www-data (or any other user) to run that one specific command using sudo without requiring a password. This also means that the user (perhaps www-data) would NOT have permission to run any other command, which is at least a bit more secure.
Use the sudo visudo command to edit the /etc/sudoers file. Don't edit it directly.
Here's the line to add to that file for user www-data:
www-data ALL=(ALL:ALL) NOPASSWD:/usr/sbin/service nginx reload
Here's an example of allowing a user (group) to run similar commands, with some more explanation. Here's more on Sudoers and how /etc/sudoers works.
Lastly, note that user www-data is specific to installing Nginx on Debian/Ubuntu Linux distributions. Other very common distributions (centos, redhat, fedora, arch, etc etc etc) may not be running Nginx/PHP-FPM as user www-data unless the sysadmin creates those users manually.
Short answer: Bad idea. Don't do it.
Long answer: What you try do to cannot be compared with editing a .htaccess file simply because it does not work the same way. .htaccess files are made to be edited and reloaded on the fly and can be created and accessed almost in every directory inside your public directory.
That is not the case for Nginx configurations. Configuration files are made to be loaded when Nginx starts or manually when needed. Their location is related to the configuration defined by the administrator.
Even if you knew where the file was, it could be impossible for you to update it or write in that specific directory.
More than that, you'll have to figure out what user can write and read where the configuration files are located.
In the end, there are so many thing that can go wrong. In my humble opinion, the idea is really bad.
What most plugins do is display the Nginx configuration that should be included so the website administrator can copy and paste it. Or, they create a .conf file that the website administrator must copy somewhere before restarting Nginx.
What you try to achieve is doable. It can be coded. Don't get me wrong. BUT your plugin will become about handling every specificty of every Nginx configuration there is out there. You really don't want that.
As you don't know every configuration (and honestly, you don't want to know), I'd suggest you focus on developing a great plugin and offering the right Nginx configuration via the plugin. The last part (where the website administrator copies it to the right location and reloads the configuration) is his job.
The other answers I read in that question suggest ways of "trying" to achieve what you are asking. I think they will create more problems than they'll help. By changing permissions and running crons, it may work. But you'll also open the door to security vulnerabilities as your www-data user or website user owner will now be considered as root and could run things that should not be run. I would not advise you to do that.
You must add correct permissions to account www-data which is used to execute commands on Linux webservers. You see which account is executing script with PHP by using <?php echo exec("whoami"); ?>

create a web application that could one-click install, uninstall packages on my ubuntu server

I just need to create a web application that could one-click packages on my ubuntu server, I really no idea, where to start.. Thought of doing it by php, and due to security issues, it wasn't a fair idea.
Sorry, I'm new to this.
Thanks for any help.
You should not do this.
To answer your question, yes, it is possible. It can be done with doing "sudo apt-get ..." within shell_exec(). This would require that the webserver has passwordless access to root powers.
Did I mention that you should not do this?
If you are trying to remotely manage a computer, you should use SSH to log in to it and avoid the unnecessary gymnastics of using PHP, or use a web-based interface like Webmin that can properly do these things for you.
You are on the right track using system()/shell_exec().
I think it "does not work" on your side because your Apache process owner does not have root permission (and you need root to be able to install packages). By the way, its the same for any other programming language implementation you use: you need root to be able to install packages.
You can set your Apache process owner to 'root', but then you'll get this when you try to restart it:
Error: Apache has not been designed to serve pages while
running as root. There are known race conditions that
will allow any local user to read any file on the system.
If you still desire to serve pages as root then
add -DBIG_SECURITY_HOLE to the CFLAGS env variable
and then rebuild the server.
It is strongly suggested that you instead modify the User
directive in your httpd.conf file to list a non-root
user.
You can compile Apache yourself to allow running Apache with root user as indicated above.
To summarize, what you're trying to do is possible BUT you are opening a really big security hole.
YOU SHOULD NOT DO THIS.
Use SSH instead.

editing in /var/www/html

I am not much of a web developer, so apologies in advance for this dumb question.
I have a test server (Centos 6.3) with LAMP set up for me to play around. From what I understand, the server executes whatever is in /var/www/html directory. How do you edit source files in that directory ? Do you do a sudo vim "foo.php" each time you want to fix something (or add something ) ? I'd imagine that would be a pain when you are building a complex application with many files and directories .
This is what worked for me. For the record this is a Centos 6.3 server running LAMP (On Rackspace).
First, I found out that apache runs as user "apache" and group "apache" on centos systems. In other distros, I believe it runs as "www-data" in group "www-data". You can verify this by looking at /etc/httpd/conf/httpd.conf. We need to change ownership of /var/www to this user. Replace "apache" below with "www-data" if that is the case for you.
chown -hR apache:apache /var/www
Now lets make it writable by the group:
chmod -R g+rw /var/www
Add yourself to the apache group:
usermod -aG apache yourusername
Replace apache with www-data in the above if thats the case for you.
Now log out and log in - you can now edit the files, ftp them to this directory or do whatrever you want to do.
Comments welcome. TNX!
There are many approaches to modifying and deploying websites/web apps.
CentOS 6 is, by default, accessible with SSH2 on port 22. If you are on Windows you can use a combination of PuTTY and WinSCP (to manage your server, and its files, respectively). If you're on Linux or Mac OS X, SSH is already built into your system and can be accessed with Terminal. I find that using SSH is favourable over other methods because of how widely supported, secure and lightweight it is.
You'll also need a decent text editor or IDE to edit the files if you want proper syntax detection. There's tons of choices, my favourites are Notepad++ and Sublime Text 2. Not to say that I haven't edited my PHP files from time to time using the nano text editor package directly in PuTTY (yum install nano).
If you're using a edit-save-upload approach, just remember to back up your files regularly, you will find out the hard way if you fail to do so. Also, never use root unless you need to. Creating a user solely to modify your websites is good practice (adduser <username>, and give that user write access to /var/www/html).
To answer your second question:
Once you get into heavier web development you will probably want to use something like Git. Deploying with git is beyond the scope of this question so I won't get into that. In brief, you can set it up so your development environment sits locally and you can use a combination of git commit and git push to deploy.
I use a FTP client (FileZilla) to download files, edit them and then re-upload them. If you're a one (wo)man show, and on a test setup and just playing around to learn, this is probably sufficient. With more than 1 person, or going to a (test and) production setup, you should look at some more control with svn like #Markus mentioned in another answer.
You should change the permissions of that directory (with chmod) so you have write permissions, and can then read and write to that directory. Then, you don't need sudo.
dude. read up on version control and source code control systems like subversion and git. the idea is to develop on your machine, revision control the result, then deploy a known working version on the production server.

How to run a .php file over and over...cron perhaps?

I have a php file that calls exec() on a c++ exe.When the .exe is finishing running I need to run the php file again,repeat .
I am wondering what is the best way to do this? This .php file has no user interaction and needs to be completely automated.
EDIT:Found another solution that would kill the process if it is already running which will cover this issue well.See posts on this page.
http://php.net/manual/en/function.getmypid.php
Here's a simple Linux line that starts up the script in the background and uses the watch command to restart the script whenever it finishes running:
watch -n 0 php /path/to/script.php &
Once you've started it like this, you can use the ps command to list running processes and find the process ID for watch, and then use kill process_id to stop watch.
It's probably not best practice to run commands like this, but it's a quick and easy solution that doesn't require any special access privileges on the system (whereas using cron might), and doesn't involve editing your code (whereas a codeigniter solution will).
I haven't used codeigniter before but there seems to be a solution as described in the wiki.
Depending on how you can access the system (if you are admin or not) and depending on how you are planning to update the automated commands, IMHO, you could use both solution (Linux crontab or codeigniter cron script).

Categories