I required the following:

  • System user that could upload content to a directory in root web directory (default root: /var/www/html)
  • Limit user from interactive SSH
  • Limit user from other areas of OS

Specifically, I am working within the AWS distribution on a hosted EC2 instance.

I found posts online that accomplished part of what I needed. But my steps to achieving this were:

  1. Create the user. In my case, user webpub. This creates an entry in /etc/passwd as well as a home directory under /home: 
    sudo useradd webpub
  2. These next few steps I found here. Create a ‘jail’ directory that we will constrain the user. I created it in /var.
    sudo mkdir /var/jail
    
  3. An important note is that the jail directory and all directories beneath it must be owned by user root in order for the Chroot declaration to work. If you get setup and notice that you are correctly authenticating but then the connection immediately drops, this could be your problem. Now create a sub-directory that will serve as the access point for the user to the web content:
    sudo mkdir /var/jail/www
  4. The directory created above can also be owned by root. Create a sub-directory under web content root that we will restrict this user to. In this case, the same name as the user:
    sudo mkdir /var/www/html/webpub
  5. The directory created above can also be owned by root. Now create the link between the jail and the content directory by binding the two:
    sudo mount -o bind /var/www/html/webpub /var/jail/www
  6. In /etc/passwd, update the user webpub‘s home directory (where they will land upon logging in) to /var/jail/www.
  7. Update /etc/ssh/sshd_config to jail the user upon logging in. Start by commenting the line Subsystem sftp /usr/libexec/openssh/sftp-server and then adding configuration for the internal-sftp sub-system. When done, it will look like (commented line and all): 
    #Subsystem sftp /usr/libexec/openssh/sftp-server
    Subsystem sftp internal-sftp
    Match User webpub
            ChrootDirectory /var/jail
            ForceCommand internal-sftp
            X11Forwarding no
            AllowTcpForwarding no
  8. The ChrootDirectory jails the user while ForceCommand internal-sftp lists the user to only being able to login via SFTP. Now restart openssh:
    sudo /etc/init.d/sshd restart
  9. In my setup, I have password authentication disabled, so the last step is create a private/public key pair and install client/server side. Remember that authorized_keys (and its parent directory .ssh) must reside in the home directory for webpub, which we set earlier as /var/jail/www. Since that directory is bound to /var/www/html/webpub, though, these artifacts reside in the latter directory.