25

I have a pretty standard server set up running Apache and PHP. An app I am running creates files and these are owned by the Apache user www-data. Files that I upload via SFTP are owned by my own user charlesr. All files are part of the www-data group. My problem is that I cannot modify or overwrite any of the files via SFTP which are owned by www-data, even though charlesr is part of the www-data group. I can modify the files no problem via a SSH session.

So I'm not sure what to do. How do I give my SFTP session permissions to modify www-data owned files?

For a bit of background, these are the notes I wrote for myself when setting-up the server:

Now set up permissions on `/var/www` where your files are served from by
default:

$ sudo adduser $USER www-data
$ sudo chgrp -R www-data /var/www
$ sudo chmod -R g+rw /var/www
$ sudo chmod -R g+s /var/www

Now log out and log in again to make the changes take hold.

The previous set of commands does the following:

1. adds the current user ($USER) to the `www-data` group;
2. changes `/var/www` to belong to the `www-data` group;
3. adds read/write permissions to the group that `/var/www` belongs to;
4. sets the SGID bit on `/var/www`; this final point bears some explaining.

And then I go on to explain to myself what setting the SGID bit means (i.e. all files created in /var/www become part of the www-data group automatically).


UPDATE

It seems that the problem was caused by the app itself or, more specifically, the application framework (Kohana) setting certain files it writes to 0644 (rw-r--r--); i.e. not group writable. This, coupled with the fact that the files are also owned by www-data meant that I could not edit the files via SFTP when logged-in as charlesr. I'm not sure why I could edit the files via SSH. My guess is that I must have used sudo.

Here is the permissions strategy I now use thanks to the tireless help of Marty Fried, who pointed out the flaws in my previous strategy and also helped me marinade in the world of Linux permissions until I finally grokked it. Thanks Marty!

Overview

  • Files and directories in /var/www should be owned by root:webmasters
  • All devs should be members of the webmasters group
  • All directories in /var/www should be set to: 2775 or u=rwx,g=rwxs,o=rx (rwxrwx-r-x)
  • All files in /var/www should be set to: 0664 or ug=rw,o=r (rw-rw-r--)

The following should be owned by www-data:webmasters (i.e. these are the directories that Apache needs to be able to write to):

  • application/cache
  • application/logs
  • upload
  • client_helpers/upload

HOWTO

To set up permissions on /var/www where your files are served from by default:

  1. sudo addgroup webmasters
  2. sudo adduser $USER webmasters
  3. sudo chown -R root:webmasters /var/www
  4. sudo find /var/www -type f -exec chmod 664 {} \;
  5. sudo find /var/www -type d -exec chmod 775 {} \;
  6. sudo find /var/www -type d -exec chmod g+s {} \;
  7. sudo chown -R www-data:webmasters application/cache/ [etc...]

Now log out and log in again to make the changes take hold.

The previous set of commands does the following:

  1. Create a new group called webmasters; all users who need write access to the app files will be added to this group.
  2. adds the current user ($USER) to the webmasters group.
  3. changes the owner of /var/www to root and the group to webmasters group.
  4. adds 664 permissions (-rw-rw-r--) to all files in /var/www.
  5. adds 775 permissions (drwxrwxr-x) to all directories in /var/www.
  6. sets the SGID bit on /var/www and all directories therein; this final point bears some explaining. Note also that you can also put a 2 at the front of your chmod octal (e.g. 2644) to do the same thing.
  7. sets the owner to www-data (Apache's user) and group of the supplied directory to webmaster. This ensures the directory is writable by Apache and anyone in the webmasters group. Do the same for all other directories that need to be writable.

2 Answers2

10

Ubuntu.com has pretty good serverguides, such as Apache guide. Where did you get your procedures you so carefully wrote down? I've never had to go to that much trouble for any of the servers I've set up, although I'm open to the possibility that I haven't been doing it right - also, I haven't actually install servers for anything that is very public, or very large, so there could be security holes that I don't know about.

However, I've never needed to be a member of the www-data group, and no source files in www are owned by www-data. My understanding is that this is used by Apache only for its own files, and it will not have write permissions to any of the other files itself, because in theory, no important files will allow www-data to have write permission. I'd guess that files owned by www-data would give read-only permission to everyone else, and nobody should have write permission to its files. I could be totally wrong, of course, and if I am, I hope someone will tell me and point me to actual documentation that explains differently (not to some forum where a random internet user like me has produced instructions that worked for him).

Perhaps I'm missing something, but your problem should be fairly straightforward. The user that is logged in using sftp needs to be a member of the group www-data, and the files you are trying to modify must have write permissions for the group www-data. It doesn't make sense to me that you can modify the files using ssh, but not using sftp; are you sure you are logging in to the same account for both? In sftp, you can enter commands such as !groups to list your groups, or !whoami to check what login name you are using. The results should match what you see using ssh (with the same commands minus the exclamation point).

You also should be able to use chmod, chown, chgrp from sftp if you have permission to do so.

By the way, I think your list has at least one pretty bad command:

sudo chmod -R g+rw /var/www

This gives the world write permission to every file and folder in /var/www. This sounds like a bad idea. Normally, only root has write permission to these directories, unless specific ones need more permission, usually only single directories.

Note: This was an error on my part. Thanks to DonalLafferty for pointing this out, that it specifies "g", not "a", so it only changes group permissions. My tired old eyes (or a bad font) must have read it as "a".

Edits for clarification

Normally, files created by Apache are read-only for both the www-data group and all other users, same as the root-owned files in /var/www. So, there should be no reason to make anyone a member of www-data. The issue is giving everyone write access, which is a different case. This should be done by making specific directories available within your site, and this is done simply by using chmod, either with sudo, since it is probably owned by root, or by making the owner yourself and not using sudo.

If you have more devs that need access to the entire site, that is when you want to make a user+group such as "webmasters", make it the owner of the site, give write permissions to that group, and make all devs members of that group. So the listing for the site directories would be something like:

drwxrwxr-x  ##  webmasters     webmasters   #### ####-##-## ##:##  mysite.com

More Edits

I've since realized that you don't really need to create a user "webmasters", just a group. Then the files can be owned by root:webmasters, ie root is the owner, but webmasters is the group.

In answer to questions below, the files that Apache writes will be owned by www-data, and group www-data. These files are not normally something you write to, so non-members of www-data may have read-only access - I think it depends on the directory permissions. If you do need more than occasional write access, then adding yourself to the group might be useful. Usually you make specific directories world writable for content saved by Apache. Consider also that most shared web hosting running Apache without shell access would not even have a way to set up groups.

But, Apache can read files even owned by root. Almost all files have world-readable access, just not writable. So, unless you want to change this, Apache doesn't need to be in the webmasters group.

This is all basic Linux setup, not really Apache. Apache only cares about access from within the web server, and that's set by the config files. For this reason, the Ubuntu documentation link I included in my post should be considered a better source than a public wiki.

By the way, the O'Reilly Apache Cookbook says "Document directories, such as htdocs, cgi-bin, and icons, will have to have permissions set in a way that makes the most sense for the development model of your particular web site, but under no circumstances should any of these directories or files contained in them be writable by the web server user."

Finally, using ACLs is a good way to set file permissions if you need more control. It may even be a good way to set them all the time, and is something I should investigate.

Thomas Ward
  • 74,764
Marty Fried
  • 18,466
  • Hi @marty-fried, thanks for the answer, it gives me plenty to try out. Re. your questions. I pieced the info together from various sources (hence why I wrote it down into my own-use guide) and can't remember the exact source. Although I didn't use this particular source (solution 1) (I only just found it), it gives a good rationale for my decision. In the Apache guide you mention, it recommends creating a group called 'webmasters', but if I did that, how would Apache write to the /var/www without also adding it to that group? – Charles Roper Oct 07 '12 at 09:18
  • And I do need to give other users access to /var/www so I thought giving group access to www-data and making everyone a member of that group would be a good solution. I can see now the problem of Apache being able to overwrite any file in there, though. Given only 2 devs (which includes myself) have access to the code, it's relatively safe in the short term. – Charles Roper Oct 07 '12 at 09:24
  • Update: I'm also going to work with the other devs to ensure only those files and directories that require write permission have write permission, otherwise all files within /var/www will be set to read-only for the www-data group. – Charles Roper Oct 07 '12 at 12:42
  • I added some "edits for clarification", because it was too long to add as a comment. I hope it helps, and if you have any questions, I'll edit my answer. By the way, I read the first part of the answer in your link; doesn't it contradict rather than support your decision (Where possible, do not grant write permissions to the www-data group)? But IMHO there are some bad suggestions sprinkled throughout that discussion, so be careful. Meanwhile, I'll read it more carefully to see if there's something new I can learn. – Marty Fried Oct 07 '12 at 17:37
  • Just one clarification needed if that's okay? The files and directories that need to be writable by Apache, should they be owned by www-data and not webmasters? – Charles Roper Oct 08 '12 at 15:08
  • Actually, another clarification needed: if I make files in /var/www owned by webmasters, how will Apache read those files? Presumably I don't want to add Apache to webmasters because then I'm back in the same situation of Apache having overly permissive permissions. – Charles Roper Oct 08 '12 at 16:08
  • Update: I asked on the httpd IRC channel and someone provided the canonical advice. So in my case I need to also add Apache to webmasters so that it may read files and chown the files to myself so that I may edit them. If I need to give additional users write permissions, I'll need to use ACLs. – Charles Roper Oct 08 '12 at 16:52
  • I added "more edits" to my answer because I needed more space. One important point I made is that, in my opinion, "the canonical advice" is not worthy to be considered canonical, or even correct. It's simply a public post on their wiki. If anything, the link I provided to the Ubuntu documentation should be considered more than that wiki. Apache is concerned with security via the web server, not the file system. – Marty Fried Oct 08 '12 at 18:29
  • 1
    Thanks Marty. This part from the Apache Cookbook made me laugh: "You should be aware that if you ask 12 people for the correct ways to set file permissions on your Apache server, you will get a dozen different answers." You've given me most everything I need to make progress now. Thank you so much for your time. :-) – Charles Roper Oct 09 '12 at 14:17
  • 1
    I've learned a little, too, which is why I enjoy the in-depth discussions - it usually helps clarify some of the hazy parts. I'm mainly a programmer who gets asked to fix problems and set up web sites, so I'm always learning better ways to do things. Feel free to ask if there are any other questions. – Marty Fried Oct 09 '12 at 21:41
  • 1
    AFAIK, sudo chmod -R g+rw /var/www gives 'group' access. Use 'a+rw' for world access. – Donal Lafferty Apr 20 '15 at 15:40
  • @DonalLafferty, good catch. Don't know what I was thinking back then, but maybe I somehow misread the g as a or something. Surprised nobody mentioned it in all this time. I may try to make a note about that. – Marty Fried Apr 20 '15 at 19:06
  • @MartyFried thanks for the quick update! Given your expertise, could you have a glace at this question on deployments http://serverfault.com/questions/684278/nginx-gunicorn-flask-www-data-user-file-lockdown – Donal Lafferty Apr 22 '15 at 08:32
7

I noticed you hadn't used chown.

To properly set the ownership of the files/folders you can set the whole directory this way: chown -R www-data:www-data

This sets ownership to group www-data and user www-data

Also, you can do this as a temporary workaround :

chmod 777 /var/data/<filename> or chmod 777 /var/data/<foldername>

edit the file(s) as needed, then

chmod 644 /var/data/<filename> or chmod 755 /var/data/<foldername>

Be careful of using the "-R" switch, as it changes the permissions of all the sub files and folders as well.

664 is the Apache standard file permissions, and 755 the standard folder permissions.

Hope this helps :)

Star

  • Hi, thanks for taking the time to answer, it's much appreciated. However, it doesn't really help. Chowning the files makes ALL of them unmodifiable when using SFTP (so kind of the opposite of what I'm after!). I can't really use the chmod workaround because a) I don't have permissions to chmod in SFTP; b) I don't really want to log in via SSH, change permissions, do my SFTPing, change back, etc.; and c) some files have different permissions for security reasons, so I can't chmod en masse anyway. – Charles Roper Oct 04 '12 at 12:36
  • What is /var/data? Also, what directory are you suggesting he use the command chown -R www-data:www-data? Hopefully not /var/www. – Marty Fried Oct 06 '12 at 00:47