SFTP user chrooted to wwwroot subfolder (Nginx): Difference between revisions

no edit summary
(Created page with "First, we need to change the location of the public keys for users. Otherwise we will never set the user's home folder properly. The common place for all users' authorized_ke...")
 
No edit summary
Line 2: Line 2:


The common place for all users' authorized_keys files will be in /usr/share/sshkeys:
The common place for all users' authorized_keys files will be in /usr/share/sshkeys:
mkdir /usr/share/sshkeys
mkdir /usr/share/sshkeys


Then we change the sshd config to look here for the public keys:
Then we change the sshd config to look here for the public keys:
vi /etc/ssh/sshd_config
vi /etc/ssh/sshd_config
Find and edit this line (create if doesn't exist):
Find and edit this line (create if doesn't exist):
AuthorizedKeysFile /usr/share/sshkeys/%u
AuthorizedKeysFile /usr/share/sshkeys/%u
Move all users' authorized_keys here. There is no way around this. And this must be done in the future for each new user who will want to use key authentication:
Move all users' authorized_keys here. There is no way around this. And this must be done in the future for each new user who will want to use key authentication:
mv /home/someuser/.ssh/authorized_keys /usr/share/sshkeys/someuser
mv /home/someuser/.ssh/authorized_keys /usr/share/sshkeys/someuser
Repeat the above for all users with SSH key-based access, also copy here a public key of our new SFTP user (lets call him sftpuser)
Repeat the above for all users with SSH key-based access, also copy here a public key of our new SFTP user (lets call him sftpuser)
Set the permissions (or check them) and create a symlink back to the /home/someuser/.ssh (for all users):
Set the permissions (or check them) and create a symlink back to the /home/someuser/.ssh (for all users):
chown someuser /usr/share/sshkeys/someuser
chown someuser /usr/share/sshkeys/someuser
chmod 600 /usr/share/sshkeys/someuser
chmod 600 /usr/share/sshkeys/someuser
ln -s /usr/share/sshkeys/someuser /home/someuser/.ssh/authorized_keys
ln -s /usr/share/sshkeys/someuser /home/someuser/.ssh/authorized_keys
If you already have the SFTP home folder created, do it for the SFTP user as well, if not, ignore the following 3 lines:
If you already have the SFTP home folder created, do it for the SFTP user as well, if not, ignore the following 3 lines:
chown someuser /usr/share/sshkeys/sftpuser
chown someuser /usr/share/sshkeys/sftpuser
chmod 600 /usr/share/sshkeys/sftpuser
chmod 600 /usr/share/sshkeys/sftpuser
ln -s /usr/share/sshkeys/sftpuser /var/www/siterootfolder/sftp(sub)folder/.ssh/authorized_keys
ln -s /usr/share/sshkeys/sftpuser /var/www/siterootfolder/sftp(sub)folder/.ssh/authorized_keys
Once happy, restart the sshd to apply the changes:
Once happy, restart the sshd to apply the changes:
systemctl restart sshd
systemctl restart sshd


Then, add the user. He will need to be in the nginx group (usually www-data) and his home folder will be set to the desired site subfolder:
Then, add the user. He will need to be in the nginx group (usually www-data) and his home folder will be set to the desired site subfolder:
useradd -m -d /var/www/siterootfolder/sftp(sub)folder/ -G www-data -s /usr/sbin/nologin sftpuser
useradd -m -d /var/www/siterootfolder/sftp(sub)folder/ -G www-data -s /usr/sbin/nologin sftpuser
The /usr/bin/nologin shell is there because we don't want the user to be able to log in via SSH
The /usr/bin/nologin shell is there because we don't want the user to be able to log in via SSH
The www-data user also needs to be added to the sftpuser's group:
The www-data user also needs to be added to the sftpuser's group:
Usermod -a -G sftpuser www-data
Usermod -a -G sftpuser www-data


Edit the /etc/ssh/sshd_config file again to add chroot:
Edit the /etc/ssh/sshd_config file again to add chroot:
vi /etc/ssh/sshd_config
vi /etc/ssh/sshd_config
Add (or uncomment) the sftp paragraph:
Add (or uncomment) the sftp paragraph:
Match User sftpuser
Match User sftpuser
     ChrootDirectory /var/www/siterootfolder/sftp(sub)folder/
     ChrootDirectory /var/www/siterootfolder/sftp(sub)folder/
     X11Forwarding no
     X11Forwarding no
     AllowTcpForwarding no
     AllowTcpForwarding no
     ForceCommand internal-sftp
     ForceCommand internal-sftp
This way the user will only have access to his 'home' folder, seeing it as a root folder.
This way the user will only have access to his 'home' folder, seeing it as a root folder.


Unfortunately the sshd's internal sftp engine is very restrictive about folder permissions here. The chrooted folder, as well as its each parent (up to /) must be owned by root:root with permissions 755. To achieve this:
Unfortunately the sshd's internal sftp engine is very restrictive about folder permissions here. The chrooted folder, as well as its each parent (up to /) must be owned by root:root with permissions 755. To achieve this:
First, make sure the permissions on your site folder, subfolders and files are set correctly (particularly Magento can have problems here). Then start changing the permissions:
First, make sure the permissions on your site folder, subfolders and files are set correctly (particularly Magento can have problems here). Then start changing the permissions:
cd /
cd /
chown root:root var/
chown root:root var/
chmod 755 var/
chmod 755 var/
cd var/
cd var/
chown root:root www/
chown root:root www/
chmod 755 www/
chmod 755 www/
cd www/
cd www/
chown root:root siterootfolder/
chown root:root siterootfolder/
chmod 755 siterootfolder/
chmod 755 siterootfolder/
cd siterootfolder/
cd siterootfolder/
ls -l
ls -l
The above command is to determine the current permissions of the sftp(sub)folder. Record the owner(u) and the others'(o) permissions. Why? Remember, it's not just the sftpuser in the www-data group but vice versa. This way we will have his home folder but make sure the www-data account (which Nginx is running under) will have still the same permissions.
 
The above command is to determine the current permissions of the sftp(sub)folder. Record the owner(u) and the others'(o) permissions. Why? Remember, it's not just the sftpuser in the www-data group but vice versa. This way we  
will have his home folder but make sure the www-data account (which Nginx is running under) will have still the same permissions.
 
chown -R sftpuser:sftpuser sftp(sub)folder/
chown -R sftpuser:sftpuser sftp(sub)folder/
In the next command make sure the owner(u) and the group permissions(g) are the same, the (o) permissions can stay as they were:
In the next command make sure the owner(u) and the group permissions(g) are the same, the (o) permissions can stay as they were:
chmod -R xxx sftp(sub)folder/
chmod -R xxx sftp(sub)folder/
And change the owner and permissions to comply with the sshd chroot conditions:
And change the owner and permissions to comply with the sshd chroot conditions:
chown root:root sftp(sub)folder/
chown root:root sftp(sub)folder/
chmod 755 sftp(sub)folder/
chmod 755 sftp(sub)folder/
Note the missing -R parameter when we are changing the parent folders' owner and permissions. We don't want to mess up the permissions on the content of these folders, just the folders themselves.
Note the missing -R parameter when we are changing the parent folders' owner and permissions. We don't want to mess up the permissions on the content of these folders, just the folders themselves.


Now create the .ssh folder and link the already created public key there (if you didn't do it yet):
Now create the .ssh folder and link the already created public key there (if you didn't do it yet):
cd sftp(sub)folder/
cd sftp(sub)folder/
mkdir .ssh
mkdir .ssh
chown -R sftpuser:sftpuser .ssh/
chown -R sftpuser:sftpuser .ssh/
chmod -R 700 .ssh/
chmod -R 700 .ssh/
ln -s /usr/share/sshkeys/sftpuser /var/www/siterootfolder/sftp(sub)folder/.ssh/authorized_keys
ln -s /usr/share/sshkeys/sftpuser /var/www/siterootfolder/sftp(sub)folder/.ssh/authorized_keys


Once you've double-checked that all permissions are as they should be, apply the sshd_config changes:
Once you've double-checked that all permissions are as they should be, apply the sshd_config changes:
systemctl restart sshd
systemctl restart sshd