9 ms·
The pitfalls of using SSH-agent, or how to use an agent safely
- miohtama 5y agoAre there yer any two-factor companion mobile apps that would increase SSH agent security locally (asks permission to use the agent key) or remotely (extra factor of authentication when login)?
- phonethrowaway 5y agoI've seen PAM modules for otp/totp, but that really only adds security if authenticating against a remote machine, if you validate the second factor locally doesn't that still open you to mitm or other exploits? Can you trust your own environment?
- InvaderFizz 5y agoFor Mac users, there is this: https://github.com/TimidRobot/mac-ssh-confirm https://github.com/TimidRobot/mac-ssh-confirm Doesn't add 2FA so much as it prompts you for each agent use. On the remote end, you can enable 2FA for logging into the server with libpam-google-authenticator.
- metafunctor 5y agoThere's also this to use a key in the Secure Enclave and Touch ID to confirm authentication: https://github.com/sekey/sekey https://github.com/sekey/sekey
- judge2020 5y agoDuo also has a PAM module if you'd rather use a push notification https://duo.com/docs/duounix https://duo.com/docs/duounix
- benlivengood 5y agohttps://www.stavros.io/posts/u2f-fido2-with-ssh/ https://www.stavros.io/posts/u2f-fido2-with-ssh/ goes over using FIDO2 devices with ssh, including storing the secret keys on the hardware. In that sense the passphrase becomes the second factor I guess.
- keithwinstein 5y agoObPlug for Guardian Agent, which is basically "safe" ssh-agent forwarding (and works with Mosh and SSH): https://github.com/StanfordSNR/guardian-agent https://github.com/StanfordSNR/guardian-agent The basic story is that ssh-agent really just exposes a primitive of "please sign this challenge," which is useful locally, but the protocol wasn't designed to be forwarded. If requests are coming from a semi-trusted intermediary host, the protocol doesn't tell the agent (a) "what remote server is being authenticated to [i.e., who generated the challenge?]", or (b) "what command is going to be executed?" It doesn't even really know (c) "what (semi-trusted) host forwarded the challenge and is asking to authenticate to the remote server?" (although this one you can approximate today by running lots of agents and giving each local ssh command a different agent to forward requests to). Guardian Agent is a sort of hack that allows the agent to know (a), (b), and (c) before deciding whether to grant or deny the request, so the user can set up policies like, "I'd like to allow `semi-trusted host x` to use <SSH identity i> to run "git pull from <repository name y>" when talking to `git server z`, but that's it." The basic ssh-agent protocol just doesn't have enough info to be able to do something like that.
- pritambaral 5y agoBut this doesn't solve the trust problem, though; only papers over it with a false sense of security. The problem with traditional Agent Forwarding is that an intermediary may be compromised. A compromised intermediary can still fool Guardian Agent with false values for (a), (b), and (c). The only way Guardian Agent is more secure than unmodified ssh is that it's relatively unknown. Obscurity, however, isn't a defensible security perimeter.
- keithwinstein 5y agoNo, a compromised intermediary can't fool Guardian Agent with false values for (a), (b), or (c). The client checks/enforces these. The details of how it works are in the linked paper.
- sillystuff 5y ago> 3. Only forward your agent connection to machines you trust. You can get the convenience of agent forwarding without the negatives by using openssh's ProxyJump (or, in old versions ProxyCommand). Either allows you to transparently forward your ssh connection via another host (or chain of hosts).
- jffry 5y agoProxyJump can also be pretty magic. If you have machines all on a subnet (in my example below, 10.1.0.0/24) that you need to use the same SSH jumpbox to reach, you can easily set up a wildcard to transparently proxy jump to any of them: Host jumpbox-10.1.0.x HostName jumpbox.example.com Port ... User ... Host 10.1.0.* ProxyJump jumpbox-10.1.0.x Then you can just run any random command like ssh 10.1.0.4 and it will just transparently jump through the jumpbox without you needing to specify it! (Of course, if you have a local subnet that collides and you are also trying to SSH to local hosts then this won't be the right approach for you).
- sillystuff 5y agoYou can add exclusions for the hosts in your local colliding subnet with something like: Host 10.1.0.* ProxyJump jumpbox-10.1.0.x !host hosta,hostb.example.org,hostc,10.1.0.23
- jffry 5y agoInteresting, would there be any reason to prefer that style over exempting them from the Host pattern? Host 10.1.0.* !hosta !hostb.example.org !hostc !10.1.0.23 ProxyJump jumpbox-10.1.0.x Doing it at the Host level would also make it easier if there were other config you wanted to apply for the group of machines (like IdentifyFile or Port)
- sillystuff 5y agoSorry, I made two mistakes when I wrote my response. The !host bit should be in the line above I've only used it in a Match block. I think your syntax is correct for a Host block exclusion. e.g., Match !exec "test1 -h %h -p %p >/dev/null 2>&1 || test2 >/dev/null 2>&1" host 10.1.0.*,*@example.org !host 10.1.0.4,10.1.0.11,hostb@example.org ProxyJump jumpbox-10.1.0.x The tests can be, e.g., see if the destination host can be reached directly, and if yes, bypass the jumphost. Using %h and %p ssh will pass the destination hostname and port to the test command.
- bodyfour 5y agoI've seen several systems that wrap the ssh binary to allow different agents to be forwarded to different hosts. Personally I think this is unwieldy -- it really should be something which is built into ssh directly. Running multiple agents is also a bit ugly, especially if you are trying to consolidate your keys with an agent integrated with your desktop environment, which I think is the most common use case. FWIW my proposal for fixing it is https://github.com/openssh/openssh-portable/pull/233 https://github.com/openssh/openssh-portable/pull/233 but it isn't the most elegant solution either I guess. It doesn't seem to have picked up much interest so I don't think it's likely to ever be merged (at least in its current form) which is fine. Hopefully some tamed version of agent forwarding appears directly in openssh someday, either as a simple key filter or something more complicated like guardian-agent
- metafunctor 5y agoNo need to wrap the binary for that, just something like this in ~/.ssh/config: Host *.foobar.com IdentityAgent ~/.ssh-agent-for-foobar.ssh Of course, you still need to run a separate agent for each security domain you wish to keep separate.
- inetknght 5y agoBetter: IdentitiesOnly yes # Only use the identity specified by IdentityFile instead of any presented by an agent ForwardAgent no # Don't forward to a remote server. IdentityAgent none # Don't use an agent. AddKeysToAgent no # Don't add any unlocked keys to an agent. Host *.foobar.com IdentityFile ~/.ssh/path/to/private/key
- bodyfour 5y ago> Of course, you still need to run a separate agent for each security domain you wish to keep separate. Yes, and that's the rub. It wouldn't be as bad if there was a way to make the ssh client manage the lifetime of the agent process itself (similar to ProxyCommand or something) And I definitely looked into building something like that. Ultimately I thought that something built into the client was better overall for a couple reasons: * Filtering rules can be easily managed as .ssh/config settings * As I mentioned in the PR, I was able to reuse a lot of the existing code for the agent protocol that already is compiled into the client. I also think the "filter" approach makes more sense than having truly separate ssh-agent binaries running. For one thing it's flexible to allow for multiple hops. Imagine if you are ssh'ing from A->B->C. On the first hop I want to give "B" access to keys "K1,K2" but then it wants to only give access to "K2" to C. With a protocol-filtering approach both hosts can prune back the amount of access being forwarded onwards.
- rfjakob 5y agoFrom man ssh-add: -c Indicates that added identities should be subject to confirmation be‐ fore being used for authentication. Confirmation is performed by ssh-askpass(1). Successful confirmation is signaled by a zero exit status from ssh-askpass(1), rather than text entered into the re‐ quester. I'm a bit surprised that this is not mention in the article, as this seems very useful to make exploits more difficult.
- metafunctor 5y agoYep, or put this in your ~/.ssh/config AddKeysToAgent confirm
- lathiat 5y agoWhile helpful it mostly just says “ok to sign” and it’s super easy to accidentally say yes by hitting enter at the wrong time. I need to look into the original post have wanted this for a while.
- encryptluks2 5y agoWhy not use your PGP key for SSH authentication? Seems like there should be a way to integrate with Git, so that rather than having to specify the SSH command or setting up a complicated global config you can just make sure that your right GPG key is added to the project? https://wiki.archlinux.org/title/GnuPG#Using_a_PGP_key_for_SSH_authentication https://wiki.archlinux.org/title/GnuPG#Using_a_PGP_key_for_S...
- throwdecro 5y agoIs ssh-agent even worth the trouble?
- johnklos 5y agoYes.
- inetknght 5y agoNo. I have not found a single use case where an ssh-agent is worth the security problems it adds.
- dataflow 5y agoHow do you push/pull a private GitHub repo on a remote machine you're SSHed into?
- janci 5y agoDeploy keys
- dataflow 5y agoSo you leave a copy of a key that can push to your repo on the machine? How in the world is that supposed to be more secure than forwarding an agent that only authenticates you when you're actually connected? At least you don't leave a copy of the key itself on another machine.
- johnklos 5y agoFirst, the author writes as if shell servers with multiple people don't exist. Please see, for example, https://sdf.org/ https://sdf.org/ Second, if you're going to exclude every server on which anyone else has root, you're essentially excluding all hosting (except colocation), since essentially that means all computers you don't physically manage. There are many scenarios where a physically local computer is only trustworthy for the moment, and where this could change at any time. Windows computers, for instance, aren't trustworthy in the long term. Work computers may have nefarious software on them. Computers which are shared with multiple people (think of a family) may have users who aren't as careful. A shell on a trustworthy provider such as SDF may be safer as a place to store keys and from which to run ssh-agent, so this scenario shouldn't be discounted. Of course, this means nothing if your access to your shell on a trustworthy server is compromised, but wholesale discounting this is not helping people.
- burnished 5y agoThe author makes it pretty plain they do everything from a laptop that is in their sole control. I don't think it is a reasonable critique that every article is pertinent to every kind of user.
- johnklos 5y agoIt's not written in the voice of, "this is good for most, but there are good reasons for other scenarios" as much as it's written in the voice of, "don't do this, don't do this".
- burnished 5y agoAnd they lay the reasons why out in a compelling and thoughtful manner. Your own comment is written with the voice you are decrying. Personally, I find opinionated articles like TFA to be very helpful. And trying to write something that works as a global solution or insight is.. difficult. It is a significantly different task trying to produce something helpful or interesting with a limited scope (my usecase, my opinion, etc) vs something that is broad enough to touch on everything else. Its just hard to feel like you know enough to speak from that position, you know?
- 0x000000001 5y agoMy Yubikey requires physical touch to authorize an SSH connection so it doesn't matter if I forward my agent to malicious servers as their attempts to hijack my socket will result in timeouts from my not authorizing their use with my physical key
- danieldk 5y agoIf you have a Mac with Touch ID, you can also use secretive, which requires fingerprint authentication: https://github.com/maxgoedjen/secretive https://github.com/maxgoedjen/secretive Extra nice with the new Apple Magic Keyboard with Touch ID.
- justincormack 5y agoYes, not using software keys is much the safest approach. They can't be stolen from your laptop oe remote forwarding.
- pmoriarty 5y agoBiometrics have their own set of problems.
- 0xCMP 5y agoNice, I'd been looking for an alternative to sekey unfortunately.
- Too 5y agoAnything similar for Linux and Windows? Modern SoCs do have secure enclaves, but how can one use it? I don't want a Yubikey dongle which i will forget at home when going to the office and vice versa. I'd be happy to get just the secure key storage without the fingerprint feature.
- ProZsolt 5y agoYubikey has the Nano series[1][2] which you can leave in your laptop [1]: https://www.yubico.com/gb/product/yubikey-5c-nano/ https://www.yubico.com/gb/product/yubikey-5c-nano/ [2]: https://www.yubico.com/gb/product/yubikey-5-nano/ https://www.yubico.com/gb/product/yubikey-5-nano/
- mtmulch5092 5y agoCovid Discrimination / Medical / Assistance anything helps. https://gofund.me/05183d43 https://gofund.me/05183d43
- bcl 5y agoI would also add 'Always set a timeout with -t' both to protect the keys from misuse, and so you don't forget your passphrase when you rarely type it in.
- throwaway984393 5y agoThere are a couple solutions to "too many keys". The simplest and best solution is don't use SSH. For Git remotes using HTTPS, use personal access tokens / API tokens. For each repository you check out, change the git remote URL to include the username, like git remote add origin https://username@github.com/user/repo.git https://username@github.com/user/repo.git. Then configure Git to use your system's credential keychain and store your token there with the hostname and username. Or use a .netrc file. The correct access token will be selected based on the hostname and username. If you do use SSH, you can configure a Git repo to use some specific SSH arguments to specify the key file, like git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_clientX". Or you can configure your SSH client to have a custom Host entry for a fake host that specifies the SSH key to use, and use that fake host for your Git ssh remote URL.
- maccolgan 5y agoUsing hostnames like a.github.com and b.github.com and in your ~/.ssh/config and adding Host entries with IdentityFiles pointing to the right private keys is the cleaner solution imo.
- koolba 5y agoHow is this better than using IdentiesOnly and explicitly listing the one and only key that should be used for a given destination?
- secabeen 5y agoA timeout of 4 or 8 hours works well for me. Enough that it's useful, and part of my routine when I start my workday and return from lunch.
- 3np 5y ago> Too many keys, github, and friends This right here is what has been bugging me recently and the what is really selling me on the author's approach. Given that exposing a series of public keys to an SSH server acknowledges their connection, pervasive use of git hosting like Github/Gitlab, separating private and professional personas... How else do you keep maintain that consistently? It's only mentioned in passing in the end but really, it's an underappreciated issue I haven't seen better solutions to.
- judge2020 5y agoNote that there is ssh-import-id[0] (and has a GitHub shortcut via ssh-import-id-gh) which can be useful when setting up new servers - it imports all your SSH keys stored in GitHub or another server. This is possible because your keys are public [1]. 0: http://manpages.ubuntu.com/manpages/bionic/man1/ssh-import-id.1.html http://manpages.ubuntu.com/manpages/bionic/man1/ssh-import-i... 1: https://github.com/torvalds.keys https://github.com/torvalds.keys
- maddyboo 5y agoI like to use GPG-agent’s SSH agent emulation [1]. I start the agent with a systemd user service and have the keys expire after something like 10 minutes. A benefit is that it uses a GUI pinentry dialog to ask for your password if the requesting program doesn’t have stdin from a terminal, e.g. if I try to git push from Fugitive inside vim. I find that GPG-agent is more intuitive and less finicky than SSH-agent. [1]: https://wiki.archlinux.org/title/GnuPG#SSH_agent https://wiki.archlinux.org/title/GnuPG#SSH_agent
- kragen 5y agoYou don't have to use agent forwarding to connect to servers behind a firewall! You can use SOCKS forwarding or static port forwarding in an ssh session to the bastion host, then a ProxyCommand option to tell the second ssh to tunnel over the first ssh. However, it can still be useful to use different keys for different purposes; as the article explains, by default, ssh presents all your public keys to the remote server so it can identify you, which can be a privacy concern.
- Jenda_ 5y agoThere is a -J option in recent ssh! `ssh -J machine1,machine2 machine3` It saves a lot of hassle with manually building the tunnels. The corresponding config option is ProxyJump. However, I thought people were using agent when they really needed the "one remote computer logs into another" feature - e.g. for direct file transfer. I have never used SSH agent in my life, though - when I need something like that, I just generate fresh SSH keys on the remote computer.
- kragen 5y agoGenerating fresh ssh keys on the remote computer is an alternative to ssh-agent forwarding, not to ssh-agent per se. The alternative to ssh-agent per se is I think to leave your keys with no passphrase.
- res0nat0r 5y agoI've been using keychain to manage my ssh-agent sessions forever and it works really well. https://www.funtoo.org/Keychain https://www.funtoo.org/Keychain
- dmuth 5y ago"Never ever copy your private keys on a computer somebody else owns." FTFY. In more detail: if your private keys ever leave your computer via the network, it's a good idea to consider your private keys compromised and to burn them and create new ones. If you're in an organization which uses SSH CAs and Principals (see https://dmuth.medium.com/ssh-at-scale-cas-and-principals-b27edca3a5d https://dmuth.medium.com/ssh-at-scale-cas-and-principals-b27... for details), you'll only need to create a single keypair, get it signed, and you're good to go again.
- AnonC 5y ago> In more detail: if your private keys ever leave your computer via the network, it's a good idea to consider your private keys compromised and to burn them and create new ones. Why such a rigid rule? What if I backup the private keys online, after encrypting them, using software that’s known to be secure? I guess my question is also about how to manage things when the private key stored locally is lost.
- aftbit 5y agoFirst, there's no need to run a script to add keys on demand. Just enable "AddKeysToAgent yes" in your .ssh/config and have openssh > 7.2. Second, you don't need a script to start the agent in your shell config, if you have systemd and logind. You can run one agent per session using systemd, with SSH_AUTH_SOCK set to a predictable path in /run/user/UID. Then you can include the predictable path as SSH_AUTH_SOCK in your .zshrc.
- mariusor 5y agoI thought the exact same thing, but by the dates on the comments, it looks like this article was written 7 years ago. I don't recall when I started using these features, but it might have been more recent than that, so I would say the omission is excusable.
- arpa 5y agoif [ "$?" == 2 ]; then why not $? -eq 2? why nested ifs?