I have a PHP script on my web server that uses a private key so my directory structure looks like this
-- script.php
-- private-key
-- lib/
What permissions should I set my private-key file too so that it can be used by script.php but not by anyone else. I've tried setting the permission as 664, is that correct?
Setting your permissions as 664 means that anyone can read the file. For a private key file, you should at least remove last 4 (660). I would probably make the owner the user that is running script.php and then set the permissions to 400.
If your file permissions look something like this:
user#host:~$ ls -l
-rwxr-xr-x 3 apache apache 4096 Jan 6 15:32 script.php
-rwxr-xr-x 2 apache apache 4096 Dec 13 11:25 private-key
drwxr-xr-x 14 apache apache 4096 Dec 13 15:03 lib/
Then something like this would be more secure:
chown apache:apache private-key
chmod 400 private-key
This will make it so the only user that can read the file is the apache user.
To make life a little easier for you, you might want to add a group and fiddle with the group permissions so that your user can edit the file as well.
Related
I am trying a POC running a python script in a back-end implemented in PHP. The web server is Apache in a Docker container.
This is the PHP code:
$command = escapeshellcmd('/usr/local/test/script.py');
$output = shell_exec($command);
echo $output;
When I execute the python script using the back-end we are getting a permission denied error for creating the file.
My python script:
#!/usr/bin/env python
file = open("/tmp/testfile.txt","w+")
file.write("Hello World")
file.close()
This is the error I'm getting:
IOError: [Errno 13] Permission denied: 'testfile.txt'
For the directory im working with the permissions are as follows,
drwxrwsr-x 2 1001 www-data 4096 May 8 05:35 .
drwxrwxr-x 3 1001 1001 4096 May 3 08:49 ..
Any thoughts on this? How do I overcome this problem?
To start is is incredibly bad practice to have relative paths in any scripting environment. Start by rewriting your code to use a full path such as /usr/local/test/script.py and /tmp/testfile.txt. My guess is your script is attempting to write to a different spot than you think it is.
When you know exactly where the files are being written go to the directory and run ls -la and check the permissions on the directory. You want it to be writeable by the same user or group as the web server runs.
Looking at the permissions you have shown you don't have the user able to write to the directory, just everyone and the group. You need to add user write permissions - chmod u+w /tmp will do the job.
I believe the problem is that you are trying to write to an existing file in the /tmp/ directory. Typically /tmp/ will have the sticky permission bit set. That means that only the owner of a file has permission to write or delete it. Group write permissions on files do not matter if the sticky bit is set on the parent directory.
So if this is the contents of your /tmp
$ ls -al /tmp
drwxrwxrwt 5 root root 760 Apr 30 12:00 .
drwxr-xr-x 21 root root 4096 Apr 30 12:00 ..
-rw-rw---- 2 1001 www-data 80 May 8 12:00 testfile.txt
We might assume that users in the group www-data should be able to write to testfile.txt. But that is not the case, since . (the /tmp/ directory itself) has the sticky bit set (the t in the permissions section indicates this).
The reason why the sticky bit is set here is that everyone should be able to write files there, but not have to worry that other users might modify our temporary files.
To avoid permission errors, you can use the standard library tempfile module. This code will create a unique filename such as testfile.JCDxK2.txt, so it doesn't matter if testfile.txt already exists.
#!/usr/bin/env python
import tempfile
with tempfile.NamedTemporaryFile(
mode='w',
prefix='testfile.',
suffix='.txt',
delete=False,
) as file:
file.write("Hello World")
I'm having trouble handling the uploaded files on my web server.
First the file is uploaded to the temp server by user "daemon" then I copy the file to www/myapp/files folder by the "www-data" user. Everything works fine, I can read and write to the file, but when I try to delete the file I get an error. Because I'm trying to delete the file as www-data user (php script), but the owner of the file is daemon user.
My question is how can I fix this?
I'm not looking for any chmod or chown solutions, I prefer the solution to be through Apache or some other configuration files.
EDIT:
As requested file permissions:
-rw-r--r-- 1 daemon daemon 41638 Jan 19 08:59 FILE
The parent folder has 0777 permissions
You can add both users to one group like this:
usermod -a -G groupName userName
And then set up r\w permissions for that group
Avoid assumptions
Everything works fine, I can read and write to the file
This indicates that the file permissions themselves, and ownership, permit current usage. If as you say apache is running as www-data, it directly contradicts this:
As requested file permissions: -rw-r--r-- 1 daemon daemon 41638 Jan 19 08:59 FILE
Which would mean the file is not writable to www-data.
Because I'm trying to delete the file as www-data user (php script), but the owner of the file is daemon user.
The above statement is not true - ownership of a file does not affect who can delete it.
I'm not looking for any chmod or chown solutions, I prefer the solution to be through Apache or some other configuration files.
How about not ruling out solutions until you have a choice =)?
Deleting a file uses directory permissions, not file permissions
This is easily verifiable:
-> pwd
/tmp/so
-> whoami
www-data
-> ls -la
total 8
dr-xr-xr-x 2 www-data www-data 4096 Feb 18 14:34 .
drwxrwxrwt 8 root root 4096 Feb 18 14:36 ..
-rw-rw-r-- 1 www-data www-data 0 Feb 18 14:34 a-file
-> rm a-file
rm: cannot remove `a-file': Permission denied
note there is no write permissions to the folder /tmp/so - it's the only permission that matters. Here's another existing answer as a supportive reference.
So given that, the only solution is to ensure that the user attempting to delete a-file has write permission to the containing folder, which means for example:
# assuming daemon is the owner
chmod 7x7 www/myapp/files
^ www-data is not the owner or in the group daemon - so world perms apply
Or
chown www-data:www-data www/myapp/files
chmod 7x7 www/myapp/files
^ daemon needs write permission to the folder too
Or
chown www-data:sharedgroup www/myapp/files
chmod 77x www/myapp/files
^ daemon now reads the group perm, www-data is the owner
(With the upload process running as daemon:sharedgroup)
The above are one-time-only commands that need running; after which there is no need to modify the permissions for any file or folder to permit both www-data and daemon to manipulate files in www/myapp/files.
-rw-r--r-- 1 root root 514 Jan 15 04:03 curl.php
-rw-r----- 1 root root 1344 Feb 5 02:09 dbm-config.ini
-rw-r--r-- 1 root root 5149 Feb 5 02:19 mysql-connectivity-status.php
Here, Am accessing the file "mysql-connectivity-status.php" from url like http://<ip>/html/DB-Monitoring/mysql-connectivity-status.php.
In mysql-connectivity-status.php I have called the file dbm-config.ini. While am accessing via URL am getting the following Warning.
Warning: parse_ini_file(/var/www/html/DB-Monitoring/dbm-config.ini): failed to open stream: Permission denied in /var/www/html/DB-Monitoring/mysql-connectivity-status.php on line 113
So, I don't want to change the permission for the dbm-config.ini But how to I access the file using URL?
-rw-r----- 1 root root 1344 Feb 5 02:09 dbm-config.ini
The file can be read from and written to, by the user root rw- and read from by the members of the group root r--
If you access the php file using curl, this is executed most likely with your webservers user and group which is not root:root
That's why php can't read the ini file.
I recommend to move the file out of your document root so it can't be accessed directly from the web, then change the owner to your webserver user and group
determine the username php is executed with
ps aux | grep "httpd" # apache environment
ps aux | grep "php" # php fastcgi environment
chown user:group dbm-config.ini
The problem is that your webserver cannot access that file. If you cannot fix that you cannot access it remotely through that webserver. :)
Wild guess, since I don't know what you're using:
chown root:apache dbm-config.ini
chmod g+r dbm-config.ini
might help. That will set the owning group of the file to apache and give the group read access. IF your webserver is apache and that is the correct group that it is using this might help.
Is there a way to set php running under apache to create folders with the folder owned by the owner of the program that creates it instead of being owned by apache?
Using word press it creates new folders to upload into but these are owned by apache.apache and not by the site that they are running in. This also happens using ostickets. For now we have to SSH into the server and chmod the folder, but it would seem there would be a setting somewhere to override the ownership outside of any program that does it.
Safe_mode is turn on on your server. The function mkdir() creates folder with owner ("apache", "none", ..) that different of the current script owner. And scripts couldn't upload (move, copy) files into that folder with another owner (that is not like current script owner).
Disable safe_mode and that would be work.
See http://php.net/manual/en/features.safe-mode.php for details.
P.S. With enable safe_mode you can't use chmod() function in php.
Another way is to put the apache user and the "customer users" in a new group. Additional the directory should use the sticky bit SGID so each new file got the group assignment to this new group. This way the webserver and the "customer users" can work with the files without any problems
[17:57] progman#proglap /tmp/test $ ls -al /tmp/test
total 9
drwxrwsr-x 2 root users 48 Apr 1 17:55 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
As you see the directory got the stick bit SGID and the owner is the "users" group in which I (progman) am. No if another user adds a file the group automatically get set to this group
[17:55] proglap ~ # touch /tmp/test/x
This is executed from root. Now we get:
[17:57] progman#proglap /tmp/test $ ls -la /tmp/test
total 9
drwxrwsr-x 2 root users 72 Apr 1 17:59 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
-rw-r--r-- 1 root users 0 Apr 1 17:59 x
As you see the added file is from root, but the group is set to users and this way I can remove it
[18:00] progman#proglap /tmp/test $ rm x
rm: remove write-protected regular empty file `x'? y
[18:01] progman#proglap /tmp/test $ ls -la /tmp/test
total 9
drwxrwsr-x 2 root users 48 Apr 1 18:01 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
Keep in mind that you still need to change the chmod if you want to edit the file as rw-r--r-- is just group read access. But changing the chmod, maybe even working with umask, is better than dealing with root-access and using chown.
Not directly, no. You can't "give away" ownership of a file to another user, unless you're root. You could investigate using the "AssignUserID" apache directive to force that particular vhost to run as a particular user/group. With that Apache/PHP would create any files with the appropriate ownership
Check out PHP chown() function
I am trying to read and post back to the browser a file uploaded with the zend framework mechanism.
The file has been uploaded correctly to the desired location and as I have checked by
su www-data
and after an ls and a cat, the web user can read it and modify it properly.
the problem is that inside a controller when I try to:
if(!file_exists($fileName)) {
die("File ($fileName) wasnt set or it didnt exist");
}
I am always getting to die(...), although the $fileName is a string and when I display it's location I can always (as stated before) read it from the command line.
ls output:
$ ls -lah
total 112K
drwxr-xr-x 2 www-data www-data 4.0K 2009-10-07 18:21 .
drwxr-xr-x 3 www-data www-data 4.0K 2009-10-07 13:57 ..
-rw-r--r-- 1 www-data www-data 70K 2009-10-07 17:33 Eclipse_Icon_by_TZR_observer.png
-rw-r--r-- 1 www-data www-data 27K 2009-10-07 18:24 eclipse_logo2.png
Stat output:
stat() [function.stat]: stat failed for .../eclipse_logo2.png
I saw a very similar question to the "try for 30 days" site, so it is not something that has happened to me...
Any ideas?
You have to chmod the newly created file because the file owner created from PHP side will be Apache (group: www-data, httpd, www, or something similar). So next time PHP cannot access the file because www-data owns it and it has wrong permissions.
Here's how you create new files so that you can access them later.
<?php
$path = '/path/to/new/file';
touch($path)
chmod($path, 0777);
// TRY to change group, this usually fails
#chgrp($path, filegroup(__FILE__));
// TRY to change owner, this usually fails
#chown($path, fileowner(__FILE__));