Is it possible to set root permissions for php script
and manipulate with system folders:
For example:
I want to monitor file changes in specific folder and display it to browser
try using sudo http://www.gratisoft.us/sudo/
an example of using sudo in php.net http://www.php.net/manual/en/function.exec.php#56274
You should take the other way round: Make the script readable (and only readable) for the user PHP is running under.
Allowing PHP to run with root rights with access from outside (=> browser) is .. just stupid.
yes, it is possible but not recommended unless your server is internal. In other words, if noone will have access to your server, you can do that, such as an internal application. exposing this to the world is highly discouraged.
How you can do this is to set your process to sudoers. if you are using this via httpd you can set the httpd process to sudoers.
Related
I'm working on a VPN signup site, which is written in PHP and runs on the same Ubuntu server that the VPN server runs on. It allows users to sign up for VPN services, but currently it just emails the support staff their information, and they manually edit the config files on the server. I'm using PPP to handle authentication, so I have a file containing information like below:
# user server password ip
test l2tpd testpassword *
In order for a new user to be added to the VPN service, their details must be appended to the above table, and the command
sudo /etc/init.d/xl2tpd restart
run in order to apply the new changes. What I am looking to do is automate the process. From what I can tell, there are two options. One is to create a shell script, and then use shell_exec('./adduser test testpassword');. The other is to do it directly in PHP, by opening the file, modifying it and saving it again.
From a security and speed point of view, which approach is better, or is there another one which I haven't thought of?
sudo can be configured to execute just a specific command for a specific user, so modifying your sudoers file can mean you can use sudo in a more secure way to execute specific commands.
You could combine this with a wrapper script so that php was only executing a localised script with limited rights.
So your wrapper script, let's call it 'restart_auth.sh` may contain:
#!/bin/sh
sudo /etc/init.d/xl2tpd restart
You would then shell_exec('restart_auth.sh') from php to run that script.
You would edit your sudoers file to allow the user that the script was run as (your php user) to run /etc/init.d/xl2tpd. so if your php user is www_data edit sudoers (using visudo ) to contain:
user host = (www_data) NOPASSWD: /etc/init.d/xl2tpd
Provided no tainted data - that is unvalidated information that may contain shell escape characters - is passed through to a shell exec command then it is secure.
As someone else suggested it may be better to write the data to a pending list then read from that, rather than passing it on a shell_exec() line. However that can still introduce insecurities, so making sure the values you are writing to the file are untainted is the most important thing.
Also never run that full script as root even as a cron job, but instead use the same approach with sudoers to only permit the running script to execute specific commands as root. For instance you could allow sudo "cat changes.txt >> auth_file"
With a PHP application deployed on Elastic Beanstalk, EC2, I've been using git and eb to manage my environment instances and all files. I need to change the permissions on a file directory to make it writable but git doesn't take care of transferring directory permissions. What's the simplest/fastest way to get this done from a mac?
Filezilla takes a long time to configure. I can SSH into my EC2 instance but still not sure how to change the permissions for my directory.
Login via SSH and type next.
Change permissions:
sudo su - # log-in as superuser*
chmod 755 /path/to/your/directory
# If you just want to allow Apache to write in directory then set 666 permissions
**If you're an owner of directory, you don't need to log-in as superuser.*
Change the owner if you need:
sudo su -
chown user:group /path/to/directory
UPDATE:
Thanks to jamieb for the correction in comments. Really I've unswered to particular gtech's question:
how to change the permissions for my directory
But of course in my opinion it's better to give permissions to e.g. apache (or www-data) user to that directory which you want to write in, to avoid such problems.
You have to do this from within your application itself. In your case, it would probably make the most sense to throw a try/catch block around the write operation and if an exception is thrown, adjust the permissions using PHP's chmod() function.
FYI, there's a pretty good chance that you don't want to be doing this though. Persistent data needs to be stored either in your database or S3 (in the case of files). Storing data locally in each instance's filesystem is a good way to lose that data the next time you do a code deployment, an autoscale event happens, or your rebuilt the environment. It can also cause problems because you're never sure which instance serves each request due to the Elastic Load Balancer.
Solved
I figured out who the current user was using PHP and managed to set the new directories' owner to be the user the PHP scripts are executed from. However, this was still causing issues as some other commands (used to determine who the current user was) weren't working. This highlighted that the problem was that my PHP distribution was configured to be in safe mode.
I disabled safe mode and the commands provided by Ed Manet allowed me to add/edit/remove the files as desired, without the shortcut of just having everything be 777 permissions.
Thanks for the help!
Original Post
I have a web application that stores some data on the server. This involves creating and removing both directories and files (as well modifying existing files) in PHP. The main problem I'm having is do with the permissions required to perform such actions.
If I set existing files' permissions to 777, then the PHP script can edit them just fine (although I know this isn't an optimal solution as it's insecure). The script can also create and remove directories just fine (when they have 777 permissions at least), but no matter what I do I cannot get the script to create new files.
I've done some searching around and it appears that I need to elevate the PHP "user" to a user that has the required priviliges. However, when it comes to server configuration and permissions I'm essentially a beginner. How would I change to a different user to perform the required actions? Is it possible to do this mid-script and use PHP's fopen() and chmod() functions as normal? Or would I have to spawn an entirely new process using a shell command, somehow getting that external program executing with the correct privileges?
To summarise, I need a new of creating, modifying and deleting files/directories in a we b server using PHP, by assigning adequate permissions to the files and privileges to the PHP user. I am unsure on how to do this.
Thank you.
What I would do is change ownership of the folder that the PHP has to create files in to the account that runs the PHP process. Then you don't need to open up permissions so much.
So if this is a Linux system and the webserver is run by a user called "apache":
chown -R apache /path/to/the/files
Then change permissions to owner read/write
chmod -R 644 /path/to/the/files
I have a local server which needs to make changes to a virtual hosts apache config file and then restart apache so the new config takes effect.
Can PHP do this? I tried passthru and exec but they didn't work. Maybe the problem is that I'm trying to restart PHP's parent process?
Thanks for any help!!
I've used a cron script (written in PHP, not executed from the webserver) to check a server is up and restart the server.
However, I wouldn't do this from a server-created process, because you know you're about to kill the parent process, which has bad implications for the child.
The simplest method would be to have a file /tmp/RESTART_APACHE which PHP can create, and which the cron script checks for. If the cron script sees the file /tmp/RESTART_APACHE then it does a proper restart of Apache.
Using a cron script will introduce a delay (up to 60s if you run it each minute), but apart from that should work as you want.
Depending on how you intend using this, that may do the trick.
(You probably want to use a different directory than /tmp/ to set permissions and prevent anyone on the server being able to create the file.)
EDIT: Please see Aaron H's comment to this post. I agree with what he says: you really do want to be careful that the ability to restart your webserver is not a service generally available to the public.
Restrict access to the system which can trigger the restart; ensure that the file which triggers the restart has restrictive permissions so only the web process can create that file, and generally be smart.
I've done this for the very exactly thing. However it was solely for a development environment, to quickly create virtual host for our developers on demand. Worked very pleasing well so far.
My approach was to create a new user on the system, give this user sudo rights to reload apache and from Apache->PHP I used SSH to localhost with an authorized key without passphrase to that user, issuing the command.
The reason for this was that I didn't wanted to give the apache user (usually www-data) the power in general to reload itself. I named the new user wwwctrl.
The command I used was:
ssh -i /path/to/key-file wwwctrl#localhost sudo /etc/init.d/apache2 reload
I had to execute this command manually one time as wwwctrl user to have the local host key being added to ~wwwctrl/.ssh/known_hosts.
I used proc_open() to watch the execution of the command.
In fact I was generating a batch of virtual hosts for different Apache installations on different systems so on every system I had this wwwctrl user to reload Apache, basically doing this in a "foreach hosts as host do ... wwwctrl#host#".
Wouldn't you want to pass a 'reload' instead of a 'restart?'
To do this you would need to edit the sudo file and then execute the restart command that is used on your system, using sudo of course. If you give details, I could tell you but do you even have access to do that? Is it hosted? Cron would probably be a better choice here though.
at will be able to do that, not sure if you can schedule down to the second but I guess that depends on the implementation
I would create a daemon to monitor the sites-enabled directory and restart Apache when files are added or modified. Then you don't have to wait up to 60 seconds as with a cron job.
This sorta thing violates the standard chain of command since apache invokes php, not the other way around. I second the cron suggestion. Just set a cron job with sufficient privileges to check for changes to the host file, and restart apache if any are found.
How can you allow a PHP script to write to a file with high-security restrictions, such as only allowing a single user to write to it?
The difficulty seems to be that a PHP script is running as a low-permissions user (maybe apache, or www, or nobody?), and even if I chown apache the_writable_file, the directory it's in might not be writable for the low-level user. In general, what's the usual way that PHP can work with local files in a secure way?
Unfortunately, in shared hosts that use mod_php, there is no way to restrict access to secure files to your web app and login user.
The solution is to run your web app as your login user. When you do that, UNIX file permissions can correctly lock everyone else out. There are several ways to implement that, including SuExec, suPHP, or running PHP with FastCGI with mod_fcgid or mod_proxy_fcgid. FastCGI is my favorite way.
Another solution is to use a dedicated host or virtual private server.
Sure, chgrp apache the_writable_file and chmod g+w the_writable_file. After that, only your secure user and the apache user will be able to write to the file. Since the apache user is typically forbidden from logging in, you only have to worry about web users writing to your secure file using through the http daemon.
All the containing folders need to have execute permissions.
For example, if the file's in /foo/bar/the_writable_file, the directories "foo" and "bar" both need to have executable permission to access the_writable_file, even if they don't have read/write permission.