Using a VPS service, can I prevent my data from being accessible by the VPS host?

Using a provider like Digital Ocean, if I store private/sensitive information on the VPS, is there a way to protect that information (preventing the VPS host for gaining access) while still retaining SFTP and SSH access?


Unfortunately it is not possible at all. Here you are few short explanations about this:

  • Even with encryption, the provider could snapshot the current state of memory and disk and clone a new instance to get as much access you did. (source)

  • Even if you're running a VPS with encrypted filesystems, all of the in-RAM data will be unencrypted, which the VPS host sysadmins would have access to, including the decryption passphrase. If you really have this stringent of security requirements, it sounds like you need to run your own physically-secured systems or find a dedicated server hosting company that specializes in this sort of thing. (source)

  • ...bear in mind that anyone with access to the VPS image can potentially add bug your code to detect the pass phrase you use. (source)

  • [Encryption] makes some sense if you have control over the hardware; when someone else controls the hardware there's little point in it unless you trust that the host doesn't really want to look at it ... (source)

  • Physical access is root access, so if someone has physical access to the server, regardless on if it is on a VM or bare metal, they have root access. In the case of KVM the owner of the bare metal host can access the guest. You can always encrypt the data, but, that may be of limited benefit as the data will be decrypted when you access it.

    Same with the network. The owner of the VM can see your network traffic. Again you can encrypt some of the traffic (https, ssh, etc). (source)


Here is a particular solution in case you want just to store some sensitive data on your VPS:

How to create and use encrypted directory via eCryptfs and mount it remotely

Pre-requirements

Install the packages ecryptfs-utils and sshfs and reboot the system:

sudo apt update && sudo apt -y install ecryptfs-utils sshfs
sudo apt update && sudo systemctl reboot

Standard Setup and Usage

Open a terminal window and run this command:

ecryptfs-setup-private

Then you will be asked to:

  • Enter your login passphrase [<user>]: this passphrase must match with the current user's password and will be used to unlock (decrypt) your encrypted information.

  • Enter your mount passphrase [leave blank ...]: this passphrase will be used automatically when your encrypted data is mounting, but you need it in case there is an emergency situation and you must recovery your data, so write it down on a safe place.

The above command will create two directories:

  • ~/.Private where your encrypted data will be stored.
  • ~/Private where the directory ~/.Private will be mounted as decrypted.

While ~/.Private is not mounted within the directory ~/Private has two files with instructions.

When you login to the system via user's password (login passphrase) the directory ~/.Private will be automatically mounted to ~/Private and you will be able to work there. When you logout or exit, the directory ~/.Private will be unmounted. To achieve this manually you can use the commands: ecryptfs-mount-private and ecryptfs-umount-private. More about these options can be found in the article eCryptfs from ArchLinux Wiki. See also: how to use ecryptfs with a random directory.

If you authenticate your SSH/SFTP connection via password, the above shall works. But if you authenticate yourself via SSH key pair you need to use ecryptfs-mount-private to mount ~/.Private. In this case first you need to SSH to the system and run ecryptfs-mount-private then you will be able to use SFTP to the directory ~/Private. You can add the command ecryptfs-mount-private to the bottom of ~/.bashrc to automate this process:

echo -e "\n# Mount my Private directory\necryptfs-mount-private\n" | tee -a ~/.bashrc

Mount a remote encrypted directory and unlock (decrypt) it locally

On the remote machine (VPS) and on the local machine execute the following command and enter identical data for login passphrase and for mount passphrase on both machines:

ecryptfs-setup-private --nopwcheck --noautomount

The option --nopwcheck enables you to choose a passphrase different to the user login passphrase and the option --noautomount is self-explanatory.

On the remote machine:

  • Run the command:

    ecryptfs-mount-private
    

    Note: While I testing this approach I had to perform the above command two times!

  • Create some simple content:

    echo "Hello Word!" > ~/Private/hello.txt
    
  • Unmount ~/.Private:

    ecryptfs-umount-private
    
  • Further you can remove the directory ~/.ecryptfs (from the VPS), where your decryption data is stored.

On the local machine:

  • Mount the remote encrypted folder ~/.Private to the local folder ~/.Private via sshfs, and masque the ownership to the files (replace <user>@<host_name_or_ip>):

    sshfs -o idmap=user,uid=$(id -u),gid=$(id -g) <user>@<host_name_or_ip>:.Private ~/.Private
    

    To unmount, use the command: fusermount -u ~/.Private or sudo umount -l ~/.Private.

  • Then mount (and decrypt) the local directory ~/.Private to ~/Private

    ecryptfs-mount-private
    
  • Check if the file hello.txt is there:

    $ cat ~/Private/hello.txt
    Hello Word!
    
  • If you face a trouble with the command ecryptfs-umount-private (umount.ecryptfs_private) you can unmount the local ~/Private directory by the command sudo umount -l ~/Private.

  • eCryptfs has bugs and sometimes ecryptfs-mount-private and ecryptfs-umount-private don't work properly.

  • According to the above you can create two functions within ~/.bashrc that will automate the entire (mount/unmount) process (replace <user>@<host_name_or_ip>):

    function ecryptfs-remote-mount {
            sshfs -o idmap=user,uid=$(id -u),gid=$(id -g) <user>@<host_name_or_ip>:.Private ~/.Private > /dev/null 2>&1
            sudo keyctl clear @u
            sudo ecryptfs-insert-wrapped-passphrase-into-keyring $HOME/.ecryptfs/wrapped-passphrase
            # Attempt to mount, and loop the function unless it is true - due to  CLI usage bug
            ecryptfs-mount-private && echo "Done!" || ecryptfs-remote-mount            
    }
    
    function ecryptfs-remote-umount {
            ecryptfs-umount-private > /dev/null 2>&1 || sudo umount -l $HOME/Private
            fusermount -u $HOME/.Private > /dev/null 2>&1 || sudo umount -l $HOME/.Private
            echo "Done!"
    }
    
    export -f ecryptfs-remote-mount ecryptfs-remote-umount
    

    Then source ~/.bashrc and you will be able to use ecryptfs-remote-mount and ecryptfs-remote-umount as commands.

References and further reading

  • Create an encrypted archive file (tar), where your sensitive data is hiding:

    • Encrypt tar.gz file on create
    • How to Create an Encrypted (Password Protected) Tar or Zip Archive in Linux
    • How to password protect gzip files on the command line?
    • How do I password protect a .tgz file with tar in Unix?.
  • Create an encrypted directory:

    • Encrypted backup to an SFTP server (WebSpace) with ecryptfs
    • Secure Encrypted Remote Volume How-to
    • How to encrypt individual folders?
    • How to Encrypt Directories with eCryptfs on Ubuntu 16.04
    • YouTube: How to Encrypt Folder in Ubuntu
  • Use encryption of user's home directory:

    • Encrypted Home Folder
    • Encrypted Home Directory How-to
    • HOW-TO encrypt your home directory
    • Accessing your encrypted home directory in Ubuntu
    • Migrating to an Encrypted Home Directory
    • SSH message after login, then restrict the user from using account