Purpose of gpg-agent in gpg2
Asked Answered
L

2

16

I have been using gpg for encryption for a while. Someone suggested that I should use gpg2 instead. When I went to use gpg2, I could do almost nothing; it would complain that access to private keys was required, but I could not seem to get it to use the private keys without gpg-agent running.

It turns out that I intentionally disabled gpg-agent (by using chmod -x /usr/bin/gpg-agent); this caused gpg2 to have very limited functionality and complain to stderr.

The reasons I disabled gpg-agent was following a chain of events.

First, I would SSH into a remote machine and "an agent" would open a popup asking for me to unlock my SSH keys. I did not like this because:

  • A pop-up on my screen interrupts my workflow
  • A pop-up on my screen is unlikely to be noticed, so it would appear instead that the connection is stalling instead of querying to unlock an encryption key
  • The agent appeared to cache my password when I absolutely do not want my password cached (much like sudo's annoying use of password caching, I can disable that in its config); I will always want to enter the passphrase for my encryption keys every time they are used for whatever program is using them.
  • The pop-up appeared to be owned by a separate process, while I want the specific process using the key to query for the passphrase (even if it's a library that does the actual querying); since I spend most of my activities using command-line tools, that means a GUI application isn't ideal because not everything I do will have access to X11
  • Automatically starting a separate process in the background removes the concept of "one command, one process", especially if that backgrounded process then lingers after the original command has exited

It turned out to be GNOME's key agent and that I could not uninstall the agent without uninstalling GNOME. So I simply disabled it by chmod -x /usr/bin/gnome-keyring*. I then found that SSH would fall back to another agent so I disabled that too using the same method chmod -x /usr/bin/ssh-agent*

When I started using gpg, I found it had a similar agent, the same one I am asking about. I disabled it immediately for the same reasons; I want software to always ask me for passphrases in order to use a private key. I do not want the passphrase to be cached for any reason whatsoever.

So with gpg2 appearing to require gpg-agent, I would like to ask:

  • Am I being overly paranoid about the use of passphrase caching? I would be curious to see or be pointed to a discussion of it.
  • Is there a best practice that enables a better way to avoid even accidentally enabling the use of a cached passphrase?
  • Is there a way to use gpg2 without gpg-agent ever running?
  • Given that agents are daemons which are expected to be able to answer queries, what prevents another user or service running on the local machine from being able to access my cached or stored credentials?
Larkins answered 13/11, 2017 at 21:33 Comment(2)
Just want to point out that I emphatically agree with the sentiments here. This is the reason why I still continue to use and install only gpg instead of gpg2 where I can.Unrealizable
Besides the possibility of a rouge processes accessing the socket, there is possibility of installed tools monitoring everything that goes over d-bus. d-bus is used to enable socket communication. When I installed Ubuntu 16.04, I found a lot information being stored automatically in a database file about what applications and files were being used, and also another database file which seemed to be storing information about what went over the dbus. Of course I disabled them all.Talkingto
C
9

Am I being overly paranoid about the use of passphrase caching? I would be curious to see or be pointed to a discussion of it.

Your concerns are certainly valid IMO. The good news is that there are ways to customize gpg-agent behaviour to suit your needs. For example, use a terminal-based passphrase prompt (PIN entry) instead of a GUI prompt and do not cache passphrases.

Is there a best practice that enables a better way to avoid even accidentally enabling the use of a cached passphrase?

A quick solution, likely not a best practice, is to customize your ~/.gnupg/gpg-agent.conf with the following options:

# Expire cached PINs (passphrases) after zero seconds
default-cache-ttl 0
max-cache-ttl 0

# If you use your GPG keys for SSH auth...
default-cache-ttl-ssh 0
max-cache-ttl-ssh 0
enable-ssh-support

# Use TTY-based PIN entry program (I see pinentry, 
# pinentry-curses, pinentry-gnome3, pinentry-tty and 
# pinentry-x11 on my system)
pinentry-program /usr/bin/pinentry-tty

I found the following guides on GPG key best practices (more of a general guide around key management, not exactly what you're asking) fairly informative and easy to follow:

Is there a way to use gpg2 without gpg-agent ever running?

Not with gpg 2.x as far as I am aware of. The man page states the following:

   --use-agent
   --no-use-agent
          This is dummy option. gpg always requires the agent.

I have gpg 2.1.15.

Given that agents are daemons which are expected to be able to answer queries, what prevents another user or service running on the local machine from being able to access my cached or stored credentials?

Good question... By default, gpg-agent uses a socket, so technically any process running as your user could in theory hijack your keys. Don't quote me on this, though. Here's an overview of how the gpg-agent works that will hopefully get you started on finding out the real answer: https://unix.stackexchange.com/questions/188668/how-does-gpg-agent-work

Corwin answered 28/11, 2017 at 8:11 Comment(9)
I have gpg2 provided by Ubuntu 16.04 LTS as 2.1.11; I have already set all options except the pinentry program. It seems that gpg-agent does not respect these options. Setting the pinentry program to /usr/bin/pinentry-tty seems to invoke the pinentry program on the daemon's terminal (or else fail to use agent if the agent's daemon doesn't have an attached terminal) and it nukes the terminal's ability to be interacted with (even to enter the PIN it's asking for). This whole process seems really clunky and feels as if it's not designed well.Larkins
...after writing that comment, pinentry-tty segfaulted which certainly doesn't help foster feelings of it being a good programLarkins
One thing I forgot to mention is that you will need to restart gpg-agent after editing its config file. You can do it using the usual kill method, or use this command to do it nicely: gpg-connect-agent reloadagent /byeCorwin
@Larkins I hear you, I’m not a big fan of the new gpg architecture myself. I prefer the single binary approach to having multiple executables that do specialized things (for example key server/directory manager to get keys from keyservers), gpg-agent, etc all talking to gpg vs. just having a capable gpg binary.Corwin
With regards to TTY woes, the comments in this question may prove useful. You can either use X forwarding with SSH or try and control TTY ownership if invoking gpg with su or sudo... superuser.com/questions/520980/… How are you invoking gpg exactly to cause the TTY ownership issue?Corwin
I did killall -9 gpg-agent and restarted it. It still caches my PIN even after a reboot.Larkins
Invoking gpg? All I do is call ssh <remote host>. OpenSSH client then queries its agent (which is gpg-agent, as pointed by environment variable SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh in my .bashrc as described in man gpg-agent). GPG agent then notices I have a Yubikey (GPG card) authentication token and wants to present that; this is when the pinentry is invoked. Previously, an X11 window would pop up. With pinentry-tty, the terminal I had started the gpg-agent daemon on is queried (which isn't the same terminal as the one I'm trying to use SSH with).Larkins
Thanks for the overview. After some digging, I found an answer, but it’s a rather clunky one: unix.stackexchange.com/questions/280879/…Corwin
@RoubenTchakhmakhtchian gpg-agent will never give out your keys to any process. It simply performs operation with the use of cached key, e.g. signing. So some nasty process can sign something on your behalf (theoretically), but will not get your keys.Escalate
M
4

According to https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase in order to provide password directly to gpg - without gpg-agent running - you need to run with following options:

gpg --passphrase-fd 0 --pinentry-mode loopback ...

You need to provide password in console right after running this command. No password prompt will be visible during typing, but you will see typed password.

To hide password while typing you can wrap command in stty:

stty -echo ; gpg ... ; stty echo

I tested this with GnuPG v. 2.2.4: killed gpg-agent, shredded /usr/bin/gpg-agent, then run as described above. Worked well.

Magruder answered 25/6, 2018 at 18:34 Comment(3)
Using GNuPG 2.2.7 and using --passphrase-fd 0 --pinentry-mode loopback doesn't work for me: Password: gpg: failed to start agent '/usr/local/bin/gpg-agent': No such file or directory // gpg: can't connect to the agent: No such file or directory // gpg: problem with the agent: No agent runningTalkingto
The documentation you mentioned (Unattended passphrase) does say "Restart the gpg-agent process if it is running to let the change take effect. " . This seems to imply that gpg-agent is still serving as the receptor of input (via console instead on GUI) and that it will be passed via the socket. How does one feel about the zeitgeist of that?Talkingto
@CraigHicks As I wrote: I shredded gpg-agent executable and removed it. It was impossible for gpg-agent to run after that, so it did not serve as an input receptor.Magruder

© 2022 - 2024 — McMap. All rights reserved.