SSH Agent Explained
smallstep.com
smallstep.com
It works with SSH and Mosh. The basic idea is that before agreeing to a request, the principal or their agent should know (a) what machine is asking, (b) what remote machine they want to connect to, and (c) what command line they want to run on the principal's behalf. And the principal's authorization should then be limited to that context.
The ssh-agent protocol doesn't give the agent any of that information; it's really just intended for local SSH-like processes to ask "please sign this blob so I can connect somewhere" without them having to see the plaintext private key. Forwarding that to untrusted remote machines isn't ideal.
It turns out an agent can get access to this information and limit the scope of authorization in a mostly[1] backwards-compatible way, which is how guardian-agent works, but imo it would be preferable if a future version of the SSH protocol were designed more expressly for secure agent forwarding.
[1] For (c), the remote server has to be OpenSSH because guardian-agent relies on a nonstandard extension.
Once set, authentication will require confirmation via a GUI dialog provided by the ssh-askpass command. However, it does not mention the command or process requesting for authentication.
It works great on Linux, but I couldn't get it to work on macOS with the system keychain.
Aside from the missing context you mentioned, the other bigger problem with this approach is that agent confirmation is all-or-nothing: it turns on confirmation for local SSH connections in addition to forwarded connections. If you're using SSH a lot, having to confirm every connection is very annoying.
Holy snap this is exactly the reason that I've gone to great lengths to disable SSH Agents and askpass. Asking for a password without any context whatsoever of exactly which process is wanting it is a nightmare
As far as we know it lives up to that. Requests are locked to (a) [identity of requesting machine] because their origin is tagged by the local (trusted) code, which got to see the requesting machine's public key when it connected. They're locked to (b) [remote machine] by having the local code see the remote machine's public key. And they're locked to (c) [command] by having the local code be the one to send the command and then "no-more-sessions" and get confirmation before handing over control to the requesting machine.
This gives you, among other things, passwordless but authenticated "sudo" capability (which is actually required by the DOD, though nobody does it).
[0] http://cackey.rkeene.org/fossil/artifact/0d0e90bbfdee672c?ln...
[0] https://chiselapp.com/user/rkeene/repository/ssh-agent-pkcs1...
At one point I bought a few literal smart cards and a USB reader, but not being an enterprise customer of any of the vendors, couldn't find the necessary drivers / passwords to get them working with PKCS#11.
I've used it on macOS to use a PIV cert on a yubikey to ssh to remote linux servers. I have NOT used it to ssh-agent chain through, jump-box style though.
Theoretically it's an open standard, but there seems to be only one real vendor.
Browser TLS client authentication is also possible with some minimal initial setup of your browser of choice. You can use openssl with a pkcs11 engine for any X.509 operations you might think of (e.g. PKI, S/MIME email signing, etc.)—technically you could use the PIV applet to store web server TLS keys and have Nginx use those through OpenSSL via the pkcs11 engine, though it would probably slow down handshaking as the throughput and signing speed of a Yubikey is orders of magnitude slower than any modern general purpose CPU.
Many people don't know that Yubikeys also run a OpenPGP card applet for storing up to 3 key pairs. With the ssh option of gpg-agent it can also be used for SSH authentication just like ssh-agent.
I use this in combination with a Yubikey configuration setting requiring all GPG sign operations to be confirmed within 10 seconds by pressing the capacitive touch button on my YK4 nano (LED blinks during this time to prompt). This way I can safely enable agent forwarding globally as all SSH session authentication requires physical interaction to confirm (provided you don't have any file-based keys in the same agent which are still vulnerable to usage without your knowledge via this functionality).
There are many advantages of something like PKCS#11 over One-Time-Passwords (TOTP/HOTP):
1. Since you have an X.509v3 certificate, you have an identity not just an authenticator -- so when you are using this certificate to login to systems, you don't also have to supply an identification (though most systems let you optionally supply one, e.g., if you can login with multiple usernames and the same credential).
2. PKIX covers a lot more use cases than OTP, things like Kerberos (PKINIT), TLS (TLS Client Certificates), SSH (PKIXSSH et al), digital email signing (S/MIME), code signing, commit signing, and more
3. The device is basically a second computer, so it can run software policies on it to do various things like if you authenticate incorrectly a few times in a row it can zero itself out, with OTP systems that has to be coordinated by the various systems validating the OTP token.
I implemented a PKCS#11 module from the documentation for NIST SP 800-73 and RSA PKCS#11 in about a week.
What things do you think could be better documented ?
>Windows In-Box PIV Driver (Read Only) and PIVkey Windows Minidriver (Read/Write): Windows Vista, 7, 8, Server 2003, Server 2008, Server 2012.
>Mac OSX, Linux and Android (Read Only - Middleware Required)
The only open source middleware I know of for OSX is OpenSC, and it doesn't list C910 as a supported card.
https://github.com/OpenSC/OpenSC/wiki/Supported-hardware-(sm...
Does anyone know of a way to use scp without hassle, once ssh session is established?
Alternatively, ssh-add is your friend.
(But for security, make sure you do not forward ssh-agent unless you understand the risks)
Host *
ControlMaster auto
ControlPath ~/.ssh/ssh_mux_%h_%p_%r
Host host1
HostName 1.2.3.4
LocalForward 45432 db.internal.net:5432
User user1
Host host2
HostName host2.whatever.com
LocalForward 46432 db2.internal.net:5432
User user2
This way you can now scp/ssh to user1@1.2.3.4 with just this: scp file host1:
ssh host1
It also setups up port forwarding. In that case I can connect a postgresql client to localhost 45432 and it'll forward (assuming the ssh host has network access to it) the tcp connection to the host db.internal.net . I do this to use GUI SQL clients to our back-end DB.The Control options setup ssh multiplexing. If you ssh into a host, subsequent connections piggy-back off of the initial connection. This is useful if you have 2fa and don't want to do 2 factor for every connection.
There's much more you can do: https://linux.die.net/man/5/ssh_config
The answer is: using the server's public key which is transmitted to client when establishing the connection.
But then it's trivial to perform a person-in-the-middle attack and both observe and manipulate the plain text data by sending the client the attacker's public key.
That's why it's crucial to retrieve host keys via secure channels and explicitly whitelist them on clients.
The approach of SSH (like modern TLS) is to create a secure channel between two participants and only then authenticate one or both participants by binding credentials to this secure channel.
The article gets that upside down, which is understandable because most people seem to imagine that it'd be essential to figure out who you're talking to first and only then encrypt things, but actually the opposite is better.
If you do Trust On First Use as many SSH users do, then you're correct that bad guys can interpose on that first connection if they happen to get lucky - but that's because they can authenticate as the "correct" server by presenting their own public key since you have no idea what the correct one looks like.
This was true in SSH v1 which is ancient but in modern times v2 uses DH and the the server's pub key is only used to sign the DH parameters.
>"Later in the handshake process, a set of new, ephemeral and symmetric keys are generated and used to encrypt the SSH session traffic."
This isn't correct. After the TCP handshake, both systems agree on a session key by using the Diffie-Hellman key exchange. It's only after establishing a session key that user authentication takes place. There's a re-keying event but that's not part of the initial handshake and only happens later when some threshold(time or blocks) has been reached.
Thanks to this article I realize why I need to do that every time. :)
Years ago I wrote something to copy a file from a remote machine to my desktop over ssh-agent, worked well back then. https://matt.ucc.asn.au/ssh-xfer/
2. The issues and disadvantages claimed with Agent Forwarding don't actually exist anymore: https://news.ycombinator.com/item?id=22753590
Now I just need to set up my Somu, and I will be living in 2020.
TL;DR = extreme executive summary
Intro = introduction
Same number of letters, but different meanings
It's not a big deal, but the armchair lawyer in me cringes and throws an OCD tantrum when spelling, grammar, semantics, and linguistic conventions are abused. "Weight at the busstop" or "u know what i mean thatswut im saying haha he even said it tiwce" :sigh: :meta-sigh: