I've come to realize this feature is needed after encountering two bug reports ([1][br1] and [2][br2]) and a [stackoverflow question][1]. I'm a GnuPG user and I use the ssh support of gpg-agent. It is documented in [GnuPG's website][2] and on [Arch Linux' wiki][3] the following: > SSH has no way to tell the gpg-agent what terminal or X display it is running on. So when remotely logging into a box where a gpg-agent with SSH support is running, the pinentry will get popped up on whatever display the gpg-agent has been started. The workaround used by gpg-agent (with ssh support) users is telling gpg-agent to update the tty it is connected to (using the command: `gpg-connect-agent updatestartuptty /bye`). The [stackoverflow question][1] relates to authentication of the user on the local machine to the network (using `kinit`) right before connecting. What if there was actually a 'BeforeHook' configuration option that will enable users to run a certain command right before connecting to a certain host or in general? It could help gpg-agent users and kinit users as well. Right now, users of gpg-agent with ssh agent emulated need to run these commands every time they want to authenticate themselves. In my case, because I use tmux most of the time and because the tty is changed for every pane I use, I need to update the tty gpg-agent is connected to every time I change the pane. That's really annoying and it can easily be fixed with a hook like above. [br1]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=851440 [br2]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854376 [1]: https://stackoverflow.com/questions/32574142/can-i-set-up-a-before-hook-on-certain-ssh-hosts [2]: https://www.gnupg.org/documentation/manuals/gnupg/Common-Problems.html [3]: https://wiki.archlinux.org/index.php/GnuPG#SSH_agent
This has been worked around in the past by use of ProxyCommand. if your ProxyCommand does something and then subsequently exec's nc or socat to make the actual connection, you can get this behavior without changing OpenSSH at all. this does make things slightly less efficient, but that's not the end of the world. as for using gpg-agent as ssh-agent, please note that the gpg-agent has a different conception of key "unlock" and retention duration, and of agent-lifetime than does the standard ssh-agent. these subtle differences end up meaning that your workflow doesn't quite match up. You describe using ssh-agent in tmux, but one approach you can use there is to ensure that gpg-agent only runs in one tmux pane, and that you just need to switch to that pane to interact with the agent -- it *won't* follow you from pane to pane, and you can be sure that you're interacting with the agent -- the remote host can't pretend to be the agent in the current pane and ask you to deliver it your passphrase (which would be a bad thing).
That's an interesting idea, I had no idea the `ProxyCommand` was there when I wrote this request but I'm not sure it is possible to actually make it work. From what I understand from `ssh_config(5)`, the directive `ProxyCommand` can be used to eventually replace the default `ssh` command (the client program) and connect to an `sshd` server by itself. I tried adding to `~/.ssh/config` the following: ProxyCommand /usr/bin/gpg-connect-agent UPDATESTARTUPTTY /bye && ssh -p %p %r@%h with `ssh -vvv` the result was the following: OpenSSH_7.6p1, OpenSSL 1.1.0g 2 Nov 2017 debug1: Reading configuration data /home/doron/.ssh/config debug1: Reading configuration data /home/doron/.ssh/config.d/hosts/LAN debug1: Reading configuration data /home/doron/.ssh/config.d/hosts/git debug1: /home/doron/.ssh/config.d/hosts/git line 1: Applying options for github.com debug1: Reading configuration data /home/doron/.ssh/config.d/hosts/vps debug1: Reading configuration data /etc/ssh/ssh_config debug1: Executing proxy command: exec /usr/bin/gpg-connect-agent UPDATESTARTUPTTY /bye && ssh -vvv -p 22 git@github.com debug1: permanently_drop_suid: 1000 debug1: identity file /home/doron/.ssh/github type 0 debug1: key_load_public: No such file or directory debug1: identity file /home/doron/.ssh/github-cert type -1 debug1: Local version string SSH-2.0-OpenSSH_7.6 debug1: ssh_exchange_identification: OK ssh_exchange_identification: Connection closed by remote host I tried replacing `;` with `&&` and the result was the same and in both cases no connection was established. I also tried putting a `ProxyCommand` that is calling a shell script that runs those two commands (with the `TOKENS`) and I received the following error (the same line repeats itself until I `^c`): Pseudo-terminal will not be allocated because stdin is not a terminal. Is it even possible to have `gpg-connect-agent UPDATESTARTUPTTY /bye` run automatically with `ProxyCommand` the way I wanted?
A small fix to my last comment: Having `&&` vs `;` in the `ProxyCommand` does matter, I forgot to set `${SSH_AUTH_SOCK}` when I tested it. With `&&`, the verbose result is as reported in the last comment. As for having `;` instead, the result is almost identical except the last line (`ssh_exchange_identification: Connection closed by remote host`) is not there and again no connection is made.
I don't think you can use shell metacharacters or arbitrary variable expansion in ProxyCommand. Perhaps try writing a shell script and setting ProxyCommand to point to the script?
As I pointed out in my previous comment, I tried putting a `ProxyCommand` that is calling a shell script that runs these two commands (including the `TOKENS`) and I received the following error (the same line repeats itself until I `^c`): Pseudo-terminal will not be allocated because stdin is not a terminal. This is the shell script I wrote: ```sh #!/bin/sh REMOTE_HOSTNAME="${1}" REMOTE_PORT="${2}" REMOTE_USERNAME="${3}" /usr/bin/gpg-connect-agent UPDATESTARTUPTTY /bye ssh -p "${REMOTE_PORT}" "${REMOTE_USERNAME}@${REMOTE_HOSTNAME}" ``` And this is how I configured `ProxyCommand` for that script: ProxyCommand /home/doron/.ssh/proxycommand.sh %h %p %r
part of the problem might be that ssh is getting confused because the "OK" from the gpg-connect-agent is going to stdout. but mainly, your problem is that the proxycommand should take the place of a TCP connection, not the SSH connection itself. You don't want ssh to recursively invoke ssh to the same host here. try replacing your last line with: exec nc "$REMOTE_HOSTNAME" "$REMOTE_PORT" or the socat equivalent or whatever you like.
`nc` doesn't work for me whether I use it inside `ProxyCommand` or not. Besides that, It's pretty understandable that `gpg-agent` isn't going to enable a shell script's tty to be the tty on which it will ask for the password. So I'm pretty sure that using a shell script won't work at all.
I think you can use "Match exec" for this: Match host foo exec "/path/to/command" [more options if you like]
That could have been an interesting workaround but for some reason it doesn't work. I tried to add this line to my `~/.ssh/config`: Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye" So that for every host ssh will run this command but I still get this response when I switch tty (inside tmux of course): sign_and_send_pubkey: signing failed: agent refused operation
*** Bug 2798 has been marked as a duplicate of this bug. ***
(In reply to Doron Behar from comment #9) > That could have been an interesting workaround but for some reason > it doesn't > work. > I tried to add this line to my `~/.ssh/config`: > > Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye" > > So that for every host ssh will run this command but I still get > this response > when I switch tty (inside tmux of course): > > sign_and_send_pubkey: signing failed: agent refused operation Doron, This exact line actually worked perfectly for me.
Svyatoslav I. Maslennikov, I've tested this again and it works! I'm positive this didn't work in version 7.6p1 as I reported initially in this bug report. I suspect that back then ssh would run the commands from `Match host` in a pseudo tty and not the current so that's why it didn't work.
I'll add an additional note to my last comment: This really works only when `GPG_TTY` is set as well to `$(tty)`. Perhaps this specific issue can be resolved if ssh will set the environmental variable GPG_TTY by itself? What do you guys think? BTW now that I'm thinking about it it's possible that this was my problem in the first place.
closing resolved bugs as of 8.6p1 release