├── qubes.SshAgent.policy ├── ssh-add.desktop_ssh_vault ├── qubes.SshAgent ├── bashrc_client ├── rc.local_client └── README.md /qubes.SshAgent.policy: -------------------------------------------------------------------------------- 1 | $anyvm $anyvm ask 2 | -------------------------------------------------------------------------------- /ssh-add.desktop_ssh_vault: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=ssh-add 3 | Exec=ssh-add 4 | Type=Application 5 | -------------------------------------------------------------------------------- /qubes.SshAgent: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | notify-send "[`qubesdb-read /name`] SSH agent access from: $QREXEC_REMOTE_DOMAIN" 3 | ncat -U $SSH_AUTH_SOCK 4 | -------------------------------------------------------------------------------- /bashrc_client: -------------------------------------------------------------------------------- 1 | # Append this to ~/.bashrc for ssh-vault functionality 2 | 3 | # Set next line to the ssh key vault you want to use 4 | SSH_VAULT_VM="ssh-vault" 5 | 6 | if [ "$SSH_VAULT_VM" != "" ]; then 7 | export SSH_AUTH_SOCK=~user/.SSH_AGENT_$SSH_VAULT_VM 8 | fi 9 | -------------------------------------------------------------------------------- /rc.local_client: -------------------------------------------------------------------------------- 1 | # Uncomment next line to enable ssh agent forwarding to the named VM 2 | SSH_VAULT_VM="ssh-vault" 3 | 4 | if [ "$SSH_VAULT_VM" != "" ]; then 5 | export SSH_SOCK=~user/.SSH_AGENT_$SSH_VAULT_VM 6 | rm -f "$SSH_SOCK" 7 | sudo -u user /bin/sh -c "umask 177 && ncat -k -l -U '$SSH_SOCK' -c 'qrexec-client-vm $SSH_VAULT_VM qubes.SshAgent' &" 8 | fi 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qubes Split SSH 2 | 3 | These Qubes scripts allow one to keep ssh private keys in a separate VM (an 4 | "ssh-vault"), allowing other VMs to use them only after being authorized. This 5 | is done by using Qubes's [qrexec 6 | framework](https://www.qubes-os.org/doc/qrexec2/) to connect a local SSH Agent 7 | socket from an AppVM to the SSH Agent socket within the ssh-vault VM. The 8 | protections for the ssh private key should be similar to running `ssh -A` into 9 | the client AppVM. 10 | 11 | This was inspired by the Qubes [Split GPG](https://www.qubes-os.org/doc/split-gpg/). 12 | 13 | Other details: 14 | - This was developed/tested on the Fedora24 template in Qubes 3.2; it might work for other templates 15 | - For AppVMs or ssh-vault VMs based on Debian templates, you may need to install the nmap package in the template to get the ncat utility. 16 | - You will be prompted to confirm each request, though like split GPG you won't see what was requested 17 | - Assumes that the ssh-vault template automatically starts ssh-agent 18 | - One can have an arbitrary number of ssh-vault VMs 19 | - The scripts by default assumes ssh keys are kept in an AppVM named `ssh-vault`, though this can be changed by modifying $SSH_VAULT_VM in the client script. 20 | - Currently, a single AppVM can only access a single ssh-vault, though this wouldn't be hard to fix 21 | 22 | 23 | **Security note**: While in normal operation, the user will be prompted for 24 | every use of the key, it is likely possible that a malicious VM could hold onto 25 | an ssh-agent connection for more than one use. Therefore, if you authorize 26 | usage once, assume that a malicious VM could then use it many more times. In 27 | this case, though, the SSH Agent should continue to protect your private keys; 28 | only usage of it would be available to the malicious VM until it was shut down. 29 | 30 | # Instructions 31 | 32 | Copy files from this repo to various destinations (VM is the first argument). You can use `qvm-copy-to-vm $DEST_VM file` 33 | 34 | - Dom0: Copy qubes.SshAgent.policy to dom0's /etc/qubes-rpc/policy/qubes.SshAgent 35 | 36 | - Template for Ssh Vault: Copy qubes.SshAgent to /etc/qubes-rpc/qubes.SshAgent in the template image for the Ssh Vault VM. 37 | * This is because /etc is lost on every boot for the vault itself, so it needs to be added to the template 38 | * Example: 39 | ```bash 40 | # From the VM with the git repo 41 | qvm-copy-to-vm fedora-24 qubes.SshAgent 42 | 43 | # On the ssh-vault's template (in this case, fedora-24), run: 44 | sudo mv ~user/QubesIncoming/work/qubes.SshAgent /etc/qubes-rpc/ 45 | ``` 46 | - Create the ssh-vault VM (default name is "ssh-vault" in the scripts below) 47 | * It's recommended to disable network access for this VM to protect it. 48 | 49 | - Ssh-vault: Create an ssh private key or copy one in 50 | 51 | - Ssh-vault: Copy `ssh-add.desktop_ssh_vault` to `~user/.config/autostart/ssh-add.desktop` 52 | * You may need to create the .config/autostart directory if it doesn't already exist 53 | * Examine the contents of this file and adjust the ssh-add command on the `Exec` line if desired (e.g you may want to pass a specific SSH key to add to the agent) 54 | 55 | - Client VM: append the contents of rc.local_client to /rw/config/rc.local 56 | * This is what starts the client side of the ssh agent 57 | * Examine the contents and set $SSH_VAULT_VM appropriately 58 | * Be sure rc.local is executable. ie - `chmod +x /rw/config/rc.local` 59 | 60 | - Client VM: Append bashrc_client to the client VM's ~/.bashrc 61 | * This sets the user's $SSH_AUTH_SOCK to the appropriate value 62 | * Examine the contents and set $SSH_VAULT_VM appropriately 63 | 64 | # Todo 65 | 66 | - Convert the client rc.local into a systemd script in the client template, and allow the ssh-vault VM to be set using some well-known file (like /rw/config/ssh-vault) 67 | - Maybe do the above using qvm-service or qubesdb 68 | 69 | - To address the *Security Note* above, we could use `ssh-add -c` instead of just `ssh-add`, though this would mean the user would have to click "yes" twice per access in the normal case, causing fatigue/accustomization to clicking yes too much. 70 | * Note: `ssh-add -c` on the Fedora 24 template seems to be broken 71 | 72 | - Another way to address the above would be to introduce an SSH Agent proxy that only allowed one request per connection. (idea from @marmarek) 73 | 74 | - (possibly distant future) Figure out a way to display info on what is being signed 75 | --------------------------------------------------------------------------------