vaeth / sshstart

Start ssh-agent/ssh-add only if you really use ssh or friends
http://www.mathematik.uni-wuerzburg.de/~vaeth/download/index.html#sshstart
5 stars 1 forks source link

Comments and Questions #1

Open Konfekt opened 4 years ago

Konfekt commented 4 years ago

This looks interesting. I could not get gpg to work managing ssh keys with keychain. A problem was that SSH_AUTH_SOCK contains a random string /run/user/1000/gnupg/d.i1dgf43f4i8amn9wrrm95cki/S.gpg-agent.ssh which was not taken into account by keychain, given always an empy ~/.keychain/...sh-gpg file.

There is some redundancy in the documentation of sshstart. For example adding eval "$(sshshtart -e)" to the shell startup file coincides with these instructions given by sshstart -h:

In order to set correct environment variables for non-wrapped commands, put
        unset SSH_AGENT_PID
        eval test -t 0 && GPG_TTY=`tty` && export GPG_TTY; SSH_AUTH_SOCK=`gpgconf --list-dirs agent-ssh-socket`&& test -S "$SSH_AUTH_SOCK" || SSH_AUTH_SOCK=`gpgconf --list-dirs | sed -n -e 's/^agent-socket://p'`; export SSH_AUTH_SOCK; [ -z "${GPG_TTY:++}" ] || gpg-connect-agent updatestartuptty /bye >/dev/null
in your shell startup file.

I am confused whether

It might also be convenient to put e.g.
        alias ssh='ssh-wrap --'
        alias rsync='rsync-wrap --'
        ...
in your shell startup file to let 'ssh' ask for your keys only once.

is mandatory to achieve what keychain achieves for ssh-agent, or is this only necessary if

In order to set correct environment variables for non-wrapped commands,
put

unset SSH_AGENT_PID
eval "`sshstart -e`"

in your shell startup file. 

is omitted? If it is, how come this wrapping is necessary, whereas in keychain it is not?

Note that after all what keychain achieves, as far as I understand, is storing SSH_AUTH_STOCK persistently in a file that can be accessed across terminals (and cron jobs). Is the approach sshstart takes different?

vaeth commented 4 years ago

or is this only necessary if [...] is omitted?

IIRC it depends on whether you might have new keys which might need to be added.

Is the approach sshstart takes different?

Yes. sshstart does not store anything by itself: It completely relies on gpg-agent. gpg-agent in turn store into ~/.gnupg and is able to output a matching SSH_AUTH_SOCK.

Konfekt commented 4 years ago

Thank you! I am sorry, but despite these three explanations

It might also be convenient to put e.g. alias ssh='ssh-wrap --' alias rsync='rsync-wrap --' ... in your shell startup file to let 'ssh' ask for your keys only once.

IIRC it depends on whether you might have new keys which might need to be added.

This script acts as a frontend for ssh and friends which asks you for the passphrase of keys automatically, running gpg-agent and ssh-add if necessary (but usually only once).

it is still not clear to me, which steps are necessary to ensure to be asked in an X11 session for an SSH key only once? (Even though possibly multiple terminals and cron jobs spawned.)

vaeth commented 4 years ago

I honestly do not remember - this script is so many years old. I have a variant of the aliases in my shell startup file but no

eval "`sshstart -e`"

The latter I use e.g. in scripts which are possibly called with sudo. (See e.g. my rather personal git-wrappers-mv.) I do not remember whether I ever tested it with cron jobs - I do not have any requiring remote access since years - but there should not be anything different except that there is the danger that the cron job is executed immediately after the start before you had a chance to execute sshstart; ssh localhost (the latter for triggering the password request) for the cron-job user manually in a terminal.

Konfekt commented 5 months ago

May I add another question: If one happens to use systemd, then, looking at graphical-session-pre.target does adding an SSH key for the graphical-session-pre.target export SSH_AUTH_SOCK for a session that includes all logins to desktop environments, such as spawned terminals ? Or does it still fall short for unattended spawned processes, such as cron jobs? Just trying to understand what they wanted to achieve with the introduction of this target...

    This target contains services which set up the environment or global configuration of a graphical session, such as 
SSH/GPG agents (which need to export an environment variable into all desktop processes) or migration of obsolete 
d-conf keys after an OS upgrade (which needs to happen before starting any process that might use them). This 
target must be started before starting a graphical session like [gnome-session.target](http://gnome-session.target/).

    Added in version 234.
vaeth commented 5 months ago

I guess that you have to try or ask somewhere else. I do not use systemd for security reasons, neither for system start nor for desktop logins.

Konfekt commented 5 months ago

Thank you! Do other init systems, such as sysvinit or OpenRC not allow one to configure GPG agents before graphical session login?

Just wondering whether, in case this is possible, as Systemd seems to claim, the number of entries of a passphrase will be minimized. Ideally, one per session across graphical sessions (such as desktop environments or window managers).

Maybe keychain, and to some extent sshstart try to work around this problem? Or do they solve a different one?

vaeth commented 5 months ago

Graphical session login has nothing to do with an init system. In fact, this is just yet another completely independent thing which systemd has assimilated. (Actually, session management is already a questionable concept to start with, but that's a different story.)

keychain, sshstart, or actually the gpg deamon (which makes keychain and sshstart superfluous to some extent) or whatever somebody wants to use on their personal accounts: This is the right approach if one prefers to have a daemon running to enter a passphrase only once. Actually, this choice - having a daemon running which can decrypt everything or login anywhere - is the less secure alternative over entering a passphrase whenever you need it. As usual, one has to choose between more convenience (less typing) or more security. And yes, I agree that using X is not a good idea for entering a passphrase (no matter where and when or how often) and that you should better use wayland or other things for this.

Konfekt commented 5 months ago

Thank you for your helpful explanations.

Yes, it's a compromise security-wise. My heuristic is that the agent keeps the key in memory, which is hardened, that is, measures are taken that it's not as easily read as persistent storage, say a file on a hard drive.

the gpg deamon (which makes keychain and sshstart superfluous to some extent)

Does ReviveGpg() not have to reassign $SSH_AUTH_SOCK every time that sshstart is called, say wrapping rsync ? While this information is contained in the output of gpgconf, somehow ssh expects this environment variable to be accurately set?

vaeth commented 5 months ago

measures are taken that it's not as easily read as persistent storage

Yes, but also when typing the passphrase, measures are taken that it's not as easily read. Moreover, when $BAD_GUY accesses another machine, the damage is already done, even if they cannot repeat the trick.

Does ReviveGpg() not have to reassign $SSH_AUTH_SOCK every time that sshstart is called, say wrapping rsync?

I am not sure what you mean. Maybe you are missing this: https://www.gnupg.org/%28en%29/documentation/manuals/gnupg/Agent-Examples.html

Konfekt commented 5 months ago

The bottom half of the linked page reads

If you enabled the Ssh Agent Support, you also need to tell ssh about it by adding this to your init script:

unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

I was under the impression that SSH needs to have $SSH_AUTH_SOCK set. I am not sure what I am missing.

From the code of sshstart, but also the above snippet, it seems that gpgconf guards the value of $SSH_AUTH_SOCK.

Your approach with sshstart seems to replace all programs using ssh by aliases that call sshstart, which reads gpgconf; whereas keychain seems to store $SSH_AUTH_SOCK instead in a file that is read whenever ~/.keychain/$HOSTNAME-sh is sourced; so that instead all scripts using ssh commands need to ensure this.

vaeth commented 5 months ago

it seems that gpgconf guards the value of $SSH_AUTH_SOCK.

Actually, gpg-agent keeps this value: gpgconf just connects to the gpg-agent to get it. The latter is possible, because the socket to the gpg-agent is in ~/.gnupg with a fixed name (as only the user owns the directory, there is no reason for a random path name).

So in a sense the mechanism is very similar to keychain which also relies on a fixed path in the home directory, only that the “secret path” is kept in RAM which avoids a lot of problems (e.g. after a restart, there is no “broken” file left). That's why I think that this approach is much better than keychain (besides, you will probably want to let the gnupg keys manage by gpg-agent anyway if you do the same for ssh).