The following takes place on Ubuntu 18.
I need to automate the remote seeding of a
gpg-agent with a passphrase stored in a file on my local machine using SSH.
The passphrase needs to be handled in such a way so that it cannot be easily viewed by other nosey users - principally on the remote server, but also it should be secure on the local box too.
The problem is a general one, rather than being GPG specific - how do I pass a string securely into a programming running on a remote server using
I know that putting the password on the command line means is visible using
ps -ef on both local (
ssh) and remote machines (
bash -c). So I must avoid this.
I also know that storing the password in environment variables means a process' initial env can be see as
cat /proc/<pid>/environ and
gdb can be used to look at current state. So details can be seen on the local machine or the remote machine if local environment variables are forwarded. So this is not ideal, especially as I can't control tightly other people's access to the SSH user account on the remote machine.
After a bit of reading and experimentation I've come-up with the below - it certainly works! You can assume
chmod 400 so short of someone having root access on the local server, the file is secure (or at least as secure as my SSH keys).
seed.txt does not exist on the remote server, only on the local server, so it's contents must be sent to the remote server.
SSH connection is using keys so no password is need for that.
#!/bin/bash ssh -T my-server <<EOSSH > /dev/null printf '%s\n' "$(cat seed.txt)" | /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 EOSSH
ps -ef on the local machine will only yield
ssh -T my-server as the actual commands to be remotely executed are piped into stdin, rather than using the
ssh command line.
cat command line displays only the filename.
printf, I believe, is a built-in command so will not show-up in
ps. I believe the
printf is being executed on the remote machine?
On the remote server
ps will only show
/usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 as the passphrase is piped in again using stdin.
I'm making no direct use of environment variables so there shouldn't be any issue here. I'm a little anxious that something will be exposed from the SSH environment variables?
My question is - is my method sensible/simple/safe (assuming root access is not compromised), are there any obvious issues, and if yes, what are the suggested workarounds?
The only other options I've managed to get working is to use
expect but given both
gpg-preset-passphrase seem to be happy to accept input as stdin rather than interactively, it seems overkill to use
Some really helpful answers below, thanks! The more I think about this, I'd reframe the question ever so slightly - Perhaps I have to accept that ring-fencing stuff inside a single Linux account from other users of that account is always unachievable if the other users are determined? That seems usually the right logical premise, but if I want to spin-up a (per account) gpg-agent for other users (of that account) without them having access to the credentials to do the actual spinning-up themselves (gpg-agent is always per user I think?), I have to do that from within the account itself, right? How do I do that without users of the same account being able to peak at what I'm doing... the short answer seems to be - you can make it hard for them to peak, but probably never impossible? And as far as I can see seeding a
gpg-agent from a different account for use of users of another account isn't possible?