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.

Related posts

Leave a Reply

4 comments

  1. 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.

  2. 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.

  3. 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.

  4. 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"); ?>