In order to use ssh agent forwarding with emacs in daemon mode, running on a remote server, I've come-up with the following.
I have an alias for the client like so:
alias emacsclient="update_agent;/usr/local/bin/emacsclient -nw"
Which is calling the following which will update a soft-link to the current agent socket each time the emacs client is started (it is not used in any other circumstance):
alias update_agent='if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then ln -sfv "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock; fi'
Providing I don't run 2 emacs clients simultaneously, and then kill the 2nd client before the 1st, this works fine.
In order to make the daemon use the updated socket I must set SSH_AUTH_SOCK
to the soft link at daemon creation time.
I came up with 2 ways of doing this.
This way works:
alias emacs="SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock /usr/local/bin/emacs --daemon"
This way does not work:
alias emacs="/usr/local/bin/emacs --daemon --eval '(setenv \"SSH_AUTH_SOCK\" \"~/.ssh/ssh_auth_sock\")'"
Both return the same value when getenv
is called on SSH_AUTH_SOCK
from within an emacs client.
But any attempt to use Dired on a remote directory eg C-x d
/ssh:servername:
or to ssh from M-x shell
returns the following using the 2nd alias:
Failing with `Permission denied (publickey).`
My question is why doesn't the 2nd alias for emacs daemon allow ssh agent to be used for authentication?
Note - the use of the soft-link is necessary to make sure that not only the emacs daemon environment is updated, but all spawned M-x shell
s within the daemon are also updated. Otherwise it would be a trivial case of just updatng the daemon's SSH_AUTH_SOCK
environment variable each time you connect to the daemon with setenv
to the value of the current terminal's socket?
Although if anyone has a better/different way of using ssh agent forwarding with emacs daemon, then I'm keen to hear it too!
References:
https://chrisdown.name/2013/08/02/fixing-stale-ssh-sockets-in-tmux.html