4

I'm setting up a shared hosting. My users have SFTP access to the server to upload their contents. I'm using separate PHP processes running as respective users (one per site). I want the users to not see other users' contents by default (except via the web server as any other unprivileged client), but the web server (running as www-data user/group) should be able to read everything. Right now I'm giving the ownership of files in www to particular users and group ownership to www-data and using the set GID bit to propagate the group ownership to new files/directories (users are not in www-data group).

It worked fine, but now I'm facing a problem. Some of the sites are using wordpress and when they upload files the set GID bit is lost meaning that the web server has no access to it. Is there some way to configure either PHP or wordpress (more likely) to chmod files and directories into the right permissions?

Note: I'm not using safe mode in PHP, so it should be able to add the set GID bit.

Update: I've tried tweaking the FS_CHMOD_DIR and FS_CHMOD_FILE values in wordpress config. I assumed that this would allow me to chmod the uploaded files to whatever I wanted. However, it did not affect the permissions of newly uploaded files. From the info in codex I guess these settings apply to core update function only.

Thanks!

Giedrius Kudelis
  • 258
  • 2
  • 10
  • you can use .htaccess and .htpasswd for protect directories per user **OR** create virtual directory per site. – omid Feb 20 '13 at 13:55
  • The problem is I want to give users access via SFTP, so they have access to files outside of the HTTP server. htaccess and htpasswd would not help in that case. – Giedrius Kudelis Feb 20 '13 at 14:06
  • why talk about php and www-data? SFTP is a protocol for file transferring. you can create a directory and set file system permissions for user or sftp group users. – omid Feb 20 '13 at 14:24
  • SFTP is used to transfer files to the server. Then the HTTP server has to display them, this is where PHP comes in. I'm using PHP-FPM instances running as these users, whereas the web server has to serve static content. Does that make it a bit more clear? – Giedrius Kudelis Feb 20 '13 at 15:04
  • 1
    you can set permissions for access user to SFTP directories,right? you said,php can access to files in any directories,how to limit this? everyone use virtual directory for fix this problem. one user,one document root in server. but you can create server space directory into user home directory and create link for this into server for access web server to user data. – omid Feb 20 '13 at 15:34
  • OK, so if the web server is accessing files that are not owned by it or its group then I have to give read permissions to "other" (i.e. not owner or group). The problem I see then is configuration files which other users should not be able to access. I honestly do not believe my users are smart enough to figure out how to set permissions properly so I'd like to set up a system that would not give any access to other users and the web server would have to be in the group. Ideally I wish to set the permissions to 750 for directories and 640 for files (this is not including SGID bit). – Giedrius Kudelis Feb 20 '13 at 15:59
  • can you tell me your server info?(os,local home pc or server in datacenter) I really recommend to use [webmin](http://www.webmin.com/deb.html). – omid Feb 20 '13 at 16:18
  • The server is running CentOS (linux) in a virtual server dedicated to web services in the organisation. Web server is nginx (only serves static media) and I mentioned I am using php-fpm services to run PHP. Why webmin? How would it solve my problem? – Giedrius Kudelis Feb 20 '13 at 16:45
  • webmin can help you for configure server. you can use [file manager](http://www.nilambar.net/2012/10/best-free-web-based-file-management-scripts-in-php.html) script(fast way). – omid Feb 20 '13 at 17:26
  • I'm sorry, but are you serious? I am fully able to do file management from a terminal. I am fully able to set up the hosting and all that as well. I could do what you suggested, but that would simply compromise security. Please either answer the actual question or show what other setup I could use that would give me the same kind of security. As I mentioned, I don't want the users to have to set permissions themselves to stay secure either. – Giedrius Kudelis Feb 20 '13 at 17:51
  • I'm really sorry, I did not have any bad intentions. now,you can set user permissions to access your own directory in sftp? you want set same permissions for web server? or any more(i'm don't know your target!) – omid Feb 20 '13 at 18:05
  • OK, maybe I did not explain this well. My users access the server via SFTP. They upload content into their respective directories and that content is basically PHP web pages. My requirements are: (a) no user can read other user's files (by default, of course they can set permissions to what they want later); (b) web server has read access to the www files, including static content, php files and any uploaded content; (c) no 777 directories. – Giedrius Kudelis Feb 20 '13 at 18:19
  • How can users access to other users files?(url,web file manager,...) – omid Feb 20 '13 at 18:28
  • Well, there are different possibilities. Total disaster would be allowing them to access each other's files via SFTP. On the other hand, since they can upload whatever PHP code they want another option is to use that to gain access. These are probably my two main concerns. I do not think concealing the global path to directories would solve anything, I am not a believer in security through obscurity. Access through URL is normal, they can see it after being parsed by the web server. This is fine of course. – Giedrius Kudelis Feb 20 '13 at 18:35
  • if you use virtual directory per user,user can't access other directory with php code in server side. you can set username and password for sftp user. – omid Feb 20 '13 at 18:49
  • Please write up your suggestion as a solution including what permissions I would have to put on files/directories and what the user/group ownership would be. We can discuss it in the solution comments then. – Giedrius Kudelis Feb 20 '13 at 19:19
  • please see [this](http://www.rackspace.com/knowledge_center/article/how-to-add-linux-user-with-document-root-permissions) article. and [this](http://www.rackspace.com/knowledge_center/article/installing-nginx-and-php-fpm-setup-for-nginx). – omid Feb 20 '13 at 19:35
  • Well, the first article uses set GID bit as well. Same problem as I am having would occur. This article also describes adding users to the www-data group, so they would be able to see each other's files. It also gives write privileges to users in www-data group. I fail to see how this would be secure. – Giedrius Kudelis Feb 20 '13 at 19:51
  • dear,if you set username and password for sftp: how can user access to other user files via sftp? if you configure your server and virtual directory per user: how can php access to other virtual directories? if you want to disable direct access to file(url),you can use htaccess file and other solutions(this is simple) – omid Feb 20 '13 at 20:11
  • What about set GID? This is what this question was about... Also, since PHP scripts are running with user privileges what prevents them from opening a file using an absolute path? Or doing chdir()? I understand that in SFTP you could restrict the user to his directory, but that does not apply to PHP. – Giedrius Kudelis Feb 20 '13 at 20:29
  • ok,now set two virtual directory and get file in dir(a) from dir(b) with php. if you limit php to access parent of document root and define document root for virtaul directories,can't access file in virtaul (b) from vitaul (a). see [this](http://www.kavoir.com/2009/06/php-open_basedir-in-phpini-to-limit-php-file-accesses-to-a-certain-directory.html) – omid Feb 20 '13 at 21:11
  • Right, using open_basedir is one possible solution. It is not completely bombproof, but I would not worry too much about that. More datails can be found in http://www.hardened-php.net/advisory_082006.132.html. Together with restriction of SFTP this could be a viable solution. – Giedrius Kudelis Feb 20 '13 at 21:25
  • A little bit of exploration reveals that open_basedir does not apply to external commands executed using system() and friends. Therefore, it does **not** provide enough security. – Giedrius Kudelis Feb 20 '13 at 22:50

1 Answers1

3

This is not the answer to the exact question, but rather a solution to the problem in general. Assign the ownership of user's web directory to user/www-data and set the permissions to 750, no SGID bit. Users must not belong to the www-data group. However, inside that directory the group ownership can be set to the users' main group (e.g. users). The permissions inside can be 644 and 755 for files and subdirectories respectively. The security is provided by the fact that other users will not be able to enter or traverse this web directory and therefore will not be able to access any files inside even though they have enough permissions to access the files themselves. This will restrict both users connecting via SFTP and executing PHP commands.

Since this solution does not use the set GID bit it solves the original issue. Uploaded files can be left with their default ownership and permissions.

A little demonstration:

transistor# mkdir www
transistor# chown :www-data www
transistor# chmod 750 www
transistor# ls -l
total 4
drwxr-x--- 2 root www-data 4096 Feb 20 20:59 www
transistor# touch www/file1.txt
transistor# mkdir www/subdir
transistor# touch www/subdir/file2.txt
transistor# ls -l www
total 4
-rw-r--r-- 1 root root    0 Feb 20 21:00 file1.txt
drwxr-xr-x 2 root root 4096 Feb 20 21:00 subdir
transistor# ls -l www/subdir 
total 0
-rw-r--r-- 1 root root 0 Feb 20 21:00 file2.txt
transistor# exit
giedrius@transistor:/tmp/sandbox$ cd www
bash: cd: www: Permission denied
giedrius@transistor:/tmp/sandbox$ ls www/subdir
ls: cannot access www/subdir: Permission denied
giedrius@transistor:/tmp/sandbox$ cat www/file1.txt
cat: www/file1.txt: Permission denied
giedrius@transistor:/tmp/sandbox$ cat www/subdir/file2.txt
cat: www/subdir/file2.txt: Permission denied
giedrius@transistor:/tmp/sandbox$ sudo -su www-data
transistor% ls www 
file1.txt  subdir
transistor% cat www/file1.txt 
transistor% cat www/subdir/file2.txt 
transistor% 
Giedrius Kudelis
  • 258
  • 2
  • 10