4

I have a basic server set-up using a RaspberryPI, Ubuntu server 20.04, and Nginx. Using ssh, I can edit the files directly in the terminal, but that becomes sloppy, so I am looking for a more elegant way. Therefore - SSHFS.

Actions:

  • Mounting the remote volume /var/www/html to a local folder ~/Work/Server.
  • Opening my text editor and trying to modify and save a file.

Problem:

  • I receive the error Unable to save file: Permission denied

Trying to solve:

  • used sshfs -o allow_other - Same result
  • user sshfs -o allow_other,default_permissions - Same result

Solution: ???

The volume mounts with no errors, I can open and view the files. The group owner of the remote /var/www is www-data, and the user I am connecting as is part of this group.

What am I missing and how can I make this configuration to actually work?

3 Answers3

2

OK a few basics, as we ran into misunderstandings:

  1. The first level of permissions comes from the remote server: here files in /var/www are owned by www-data and group is set to the same.

  2. By default only the owner has write access there, while the group is read-only. Thus mounting as your remoter user does not have the desired effect, as he is group member only and not www-data itself.

  3. Best not to change ownership of /var/www as you did - this may break a few things. E.g. users would not be able to upload files to the server as nginx is ran by www-data and thus writes would be done as this user.

So how to manage your problem?

I believe the most secure way would be to mount it as user www-data. Let's go the safe route and use key-based logins only, as well as try to restrict access too the very part we need only. I'll be detailed so other users may profit as well.

Definitions:

  • client - your PC at home
  • server - the website server with the directory you want to mount
  • www-data - the user www-data on the server
  • dan - your local user on your client

Prerequisite: root-rights on server

1) If not existing, create a keypair for dan on your client

   ssh-keygen

Just go with no password. You now should now have the files id_rsa and id_rsa.pub in ~/.ssh - If you are not familiar with passwordless ssh, there is plenty of information out there.

2) Make www-data accept dan's public key for logins

www-data has /var/www as home directory. In some cases you might want to make this directory browseable. In general you would not want to put the authorized_keys-file (which is a list of accepted public keys for ssh-logins) there despite the home of a user being the standard location. Let's go for a dedicated place then; best in /etc.

On the server: Create a file /etc/www/ssh/authorized_keys (plus parent directories). Change ownership of file AND parent directory to www-data, as well as adapt permissions. This is necessary as ssh only accepts an authorized_keys file with specific permissions on the file and parent directory and ownership by the related user:

   chown -R www-data:www-data /etc/www/ssh
   chmod 700 /etc/www/ssh
   chmod 600 /etc/www/ssh/authorized_keys

Leave ownership of /etc/www with root

Now copy the content of dan's public key (on client /home/dan/.ssh/id_rsa.pub .... pub!, the other one is your secret file and never to be shared) to this file. Make sure the entry is on one line (sometimes copying may introduce newlines). Should look similar to this:

  cat /etc/www/ssh/authorized_keys
  ssh-rsa VERY+long+KEY+from+NUMBERS+and+LETTERS+covering+SEVERAL+lines dan@client

3) Adapt ssh-server for this type of connection

www-data has no shell for security reasons (see /usr/sbin/nologin from grep www /etc/passwd). We therefore need to adapt the ssh-server settings to still allow mounting directories. For security reasons, let's also change the root directory, so www-data via ssh may not escape outside /var/www, and enforce public key authentication, as well as deactivated interactively sending commands. After all a webserver sees the internet - hackers love this.

On the server: At the END of /etc/ssh/sshd_config add these lines. Note that match blocks never end until the next match block. Also note that /var/www must be owned by root (as is default) for the ChrootDirectory command to work.

Match User www-data
    AuthorizedKeysFile /etc/www/ssh/authorized_keys
    ChrootDirectory /var/www/
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

(Sources: ArchWiki , ssh without shell , defining authorized keys)

Reload the config via systemctl reload ssh.

4. All done

Do the sshfs-mount as desired on the client

sshfs www-data@server:/html /homa/dan/WorkServer

Note that with the changed root directory, /var/www/html becomes /hmtl only as /var/www is now the root directory.

5. Additional hardening

If applicable: you are doing this in your workplace LAN only? Deny ssh-access to www-data globally and grant it on the network only. Before the match block in sshd_config:

 DenyUsers www-data

and put the work LAN (e.g. 192.168. block) in the match criteria:

 Match User www-data Address 192.168.
FelixJN
  • 2,438
0

For me adding -o uid=999 to the sudo sshfs.... command fixed it where 999 is the uid of the remote user that owns the files.

You can find the remote uid by logging into the remote via regular SSH and running id -u

This is a less automated take on the answers at sshfs is mounting filesystems as another user

-1

Update - (Possible) Fix:

I followed the tip of @Fiximan and I have mounted the volume in the local /var/www/html which is owned by www-data, just as is on the remote.

Additionally, I have changed the remote owner of /var/www/html to the user that I am logging in as (user which is part of the www-data group).