In Apache webserver I have user www-data, and all files in /var/www are owned by www-data. Isn't that for security? Sometimes I need to upload files via FTP to /var/www/*, but with my own user I don't have write permission to it.

Let's say I use WordPress which recommends the permission to be 644 for files and 755 for folders. What is the best way to do this securely? I need still be able to upload file via FTP.

marked as duplicate by Jenny D, kubanczyk, Ward, Andrew Schulman, Esa Jokinen May 10 '18 at 10:22

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • @JennyD: Please read my answer. While this is almost an exact duplicate, the other question is almost nine years old and far from current best practices. Therefore, the answers there aren't completely relevant today. – Esa Jokinen May 8 '18 at 9:45
  • @EsaJokinen I'm afraid that people searching for this info will still find that question first since it's got so many upvotes. Perhaps it'd be better to either improve the answer(s) there or post a new one with updated info? – Jenny D May 8 '18 at 9:54
  • Your point is valid. There's a dilemma: both solutions do have the same problem. None of the answers there take this approach, so it would be unethical to modify them so far from the original, and the new answer possibly never gets much attention, despite how good it is. Also, mentioning FTP and security makes this question a bit more broad. – Esa Jokinen May 8 '18 at 10:17
  • 2
    @EsaJokinen I've asked on meta what would be the best way to handle this, to increase the likelihood that visitors find the best answer. – Jenny D May 9 '18 at 14:10

While the What's the best way of handling permissions for Apache 2's user www-data in /var/www? discuss through the permission issue quite well, it's almost 9 years old and doesn't follow the current best practices. I'll answer the question: What is the best way to do this securely?

As discussed on meta, the moved and improved version of this answer is here.

  • Have separate user for every site i.e. don't serve all sites using www-data. This is important, as with your WordPress (or any other CMS) your Apache is not serving static content files, but running PHP. If you have a security problem on a single site, it can spread to every site that is running as the same user.

  • Uploading files via FTP is not secure as it sends both the passwords and the content in plain text. E.g. the WordPress you are hosting has database login information in wp-config.php. You should be using SSH File Transfer Protocol (SFTP), instead.

    This way you can also add public keys of your site administrators to ~/.ssh/uthorized_keys, making it unnecessary for them to know the password for the user the site is running on. (See How To Set Up SSH Keys on Ubuntu 16.04). The personal public SSH key can be used across multiple sites for easy & fast access, reducing the extra burden of having multiple accounts.

  • Use PHP-FPM. It's the current approach for running PHP as the user. Create a new pool for every user i.e. one pool per every site. This is the best for both security and performance, as you can also specify how much resources a single site can consume.

    See e.g. NeverEndingSecurity's Run php-fpm with separate user/uid and group on linux. There are tutorials like HowtoForge's Using PHP-FPM with Apache on Ubuntu 16.04 that doesn't use PHP-FPM for increasing security through user separation, guiding to use a single FPM socket across the server.

  • Thank you for your answer, i'm trying to change the owner of wordpress website file to myuser:www-data. Now i can upload with sftp to any folder in wordpress while wordpress also run fine. the problem is i can't install new plugin through wordpress, seems like WP doesn't want me to change the owner other than www-data – mbuhasu May 8 '18 at 6:13
  • It might be about the folder permissions. That's why it's better to use DocumentRoots where the user has access to the parent folder, e.g. /home/user/public_html/example.com/ or /var/www/sites/example.com/. – Esa Jokinen May 8 '18 at 6:36

Tom deserves a medal for this answer on ServerFault.

Setting group ID the way he explains made it work!

  • Create a new group (www-pub) and add the users to that group

    groupadd www-pub

    usermod -a -G www-pub usera ## must use -a to append to existing groups

    usermod -a -G www-pub userb

    groups usera ## display groups for user

  • Change the ownership of everything under /var/www to root:www-pub

    chown -R root:www-pub /var/www ## -R for recursive

  • Change the permissions of all the folders to 2775

    chmod 2775 /var/www ## 2=set group id, 7=rwx for owner (root), 7=rwx for group (www-pub), 5=rx for world (including apache www-data user)

    Set group ID ([SETGID][2]) bit (2) causes the group (www-pub) to be copied to all new files/folders created in that folder. Other options are SETUID (4) to copy the user id, and STICKY (1) which I think lets only the owner delete files.

    There's a -R recursive option, but that won't discriminate between files and folders, so you have to [use find][3], like so:

    find /var/www -type d -exec chmod 2775 {} +

  • Change all the files to 0664

    find /var/www -type f -exec chmod 0664 {} +

  • Change the umask for your users to 0002

    The umask controls the default file creation permissions, 0002 means files will have 664 and directories 775. Setting this (by editing the umask line at the bottom of /etc/profile in my case) means files created by one user will be writable by other users in the www-group without needing to chmod them.

Not the answer you're looking for? Browse other questions tagged or ask your own question.