tag:blogger.com,1999:blog-18325371277226435092024-01-17T19:35:07.231+11:00djm's personal weblogDamien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-1832537127722643509.post-4548561489370366322015-02-17T14:01:00.000+11:002015-02-17T14:14:45.962+11:00Hostkey rotation, redux<p>
A couple of weeks ago I described the <a href="http://blog.djm.net.au/2015/02/key-rotation-in-openssh-68.html">host key rotation</a> support forthcoming in OpenSSH 6.8. Almost immediately after smugly declaring "mission accomplished", the bug reports started rolling in. First Mike Larkin noticed an interaction with ssh's <tt>CheckHostIP</tt> option that would cause host key warnings, then Theo de Raadt complained about the new code unnecessarily rewriting <tt>known_hosts</tt> when no changes needed to be made, finally Philipp Kern and Jann Horn pointed out a way for a hostile server to abuse the extension.
</p>
<p>
Given all this, I disabled the feature and went back to the drawing board. Host keys handling has long been one of my least favourite parts of OpenSSH - the code is poorly tested, mistakes might catastrophically break host authentication and there are lots of overlapping and interacting features (e.g. host key hashing, the aforementioned <tt>CheckHostIP</tt>, host with port specifiers, CA / revocation markers). So my first task was to <a href="https://anongit.mindrot.org/openssh.git/commit/?id=6c5c949782d86a6e7d58006599c7685bfcd01685">improve the API</a> to make it possible to solve the <tt>CheckHostIP</tt> interactions and <a href="https://anongit.mindrot.org/openssh.git/commit/?id=ef575ef20d09f20722e26b45dab80b3620469687">add some sorely-needed unit tests</a> for it (well, at least of the code that I was going to be fiddling with).
</p>
<p>
The abuse problem was more tricky - the attack was:
<blockquote>
a malicious server (say, "host-a") could advertise the public key of another server (say, "host-b"). Then, when the client subsequently connects back to host-a, instead of answering the connection as usual itself, host-a could proxy the connection to host-b. This would cause the user to connect to host-b when they think they are connecting to host-a, which is a violation of the authentication the host key is supposed to provide.
</blockquote>
The fix for this is to have the server prove to the client that it has the private keys that correspond to the public keys that it offers. Unfortunately, this is a little fiddly since we don't want to have to calculate and send signatures for each of a server's host keys on every connection (it's slow and expensive) and we can't precompute the signatures (otherwise a hostile server could just replay them and the above attack is back on). So I settled on a way for a client to ask the server to prove ownership of particular keys, allowing a flow like this:
</p>
<blockquote>
<b>S->C:</b> <em>hostkeys@openssh.com</em>; list of public hostkeys<br>
<b>Client:</b> Check known_hosts, see which keys are new<br>
<b>C->S:</b> <em>hostkeys-prove@openssh.com</em>; new keys server must prove ownership of<br>
<b>S->C:</b> <em>(reply)</em>; private key signature for each key<br>
</blockquote>
<p>
The signatures proving ownership of the private keys are bound to the specific connection instance, so they cannot be replayed. Unfortunately, this means that the hostkeys rotation support is a little less useful: it is not longer possible to offer public keys without having their private halves online to complete the proofs. I hope to bring this capability back in a future release, perhaps by (ab)using the certificate format to allow pre-computed proofs that are tied to specific hostnames.
</p>
<p>
The <a href="https://anongit.mindrot.org/openssh.git/commit/?id=523463a3a2a9bfc6cfc5afa01bae9147f76a37cc">host key proof extensions</a> are now committed to HEAD. I also added a <tt>UpdateHostKeys=<b>ask</b></tt> mode that prompts the user for confirmation before modifying <tt>known_hosts</tt>, since that seemed reasonable and symmetric with <tt>StrictHostkeyChecking=yes</tt>. Anyway, if you are interested in this then <a href="http://www.openssh.com/portable.html#git">please try out HEAD</a> and/or review the code or <a href="https://anongit.mindrot.org/openssh.git/tree/PROTOCOL?id=523463a3a2a9bfc6cfc5afa01bae9147f76a37cc#n285">protocol specification</a>.
</p>Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com8tag:blogger.com,1999:blog-1832537127722643509.post-43146244182592962172015-02-01T10:00:00.000+11:002015-02-17T14:24:45.458+11:00Key rotation in OpenSSH 6.8+<p>
<b>Update:</b> Two things that I neglected to mention in the above: 1) host keys that are not offered as part of the server->client notification are automatically removed from <tt>known_hosts</tt>, and 2) the updating of <tt>known_hosts</tt> can be disabled using a new <tt>UpdateHostkeys</tt> option in <tt>ssh_config</tt> and <tt>~/.ssh/config</tt>.
</p>
<p>
<b>Update 2:</b> Jann Horn (after Philipp Kern) points out that a malicious server (say, <em>"host-a"</em>) could advertise the public key of another server (say, <em>"host-b"</em>). Then, when the client subsequently connects back to <em>host-a</em>, instead of answering the connection as usual itself, <em>host-a</em> could proxy the connection to <em>host-b</em>. This would cause the user to connect to <em>host-b</em> when they think they are connecting to <em>host-a</em>, which is a violation of the authentication the host key is supposed to provide. The solution for this is for the server to prove to the client that server is in possession of the private key as well as the public. I'll add this before release (or delay the feature), but it's going to make the key rotation more onerous.
</p>
<p>
<b>Update 3:</b> (last one, promise). See the <a href="http://blog.djm.net.au/2015/02/hostkey-rotation-redux.html">follow-up post</a>.
</p>
<p>
Something that's bugged me about the SSH protocol is its lack of key continuity - key algorithm changes and key rotations are basically unsupported, as there is no in-protocol way for a client to learn updated host keys for hosts that the user already trusts. About the best one can do is <tt>cat /etc/ssh/*.pub</tt> once logged in to manually learn the host's other keys, but this only works if you have shell access and is a kludge anyway...
</p>
<p>
This makes it difficult for users to switch away from weak public key algorithms like <tt>ssh-dss</tt> to stronger ones and makes it practically impossible for a host to gracefully rotate its hostkeys. (I'm ignoring host certificates here, which do solve the problem but are mostly useful within an organisation).
</p>
<p>
These problems have become more urgent as the DSA supported in the SSH protocol has not aged gracefully, being within the range of a motivated attacker now. OpenSSH has preferred other host key algorithms for over 14 years, but it is the only "REQUIRED" public key algorithm in the <a href="https://tools.ietf.org/html/rfc4253#section-6.6">SSH transport protocol</a> (RSA was only "RECOMMENDED" because its patent hadn't expired back when they were written, and ECDSA was still future-tech), so people who have maintained systems for long periods of time could still be using this crappy algorithm today.
</p>
<p>
I've wanted the SSH protocol to provide a way to get users onto better host key algorithms for a while and finally got around to implementing it a couple of weeks ago: OpenSSH 6.8 will ship with a protocol extension that allows a server to inform a client of all of its host keys, and support in the client to update <tt>known_hosts</tt> when such a message is received. So, when an OpenSSH ≥6.8 client connects to a OpenSSH ≥6.8 server (or any other client/server that adopts the extension) where the user already trusts or explicitly accepts the host key, the user's <tt>known_hosts</tt> file will be updated with <b>all</b> the server's host keys, not just the one that authenticated the host during key exchange.
</p>
<p>
This fixes both the shortcomings I mentioned above: first, the client learns all the server's host key types, and can select the best possible host key algorithm (ed25519 is our current favourite) on subsequent connections. Secondly, it allows a server to gracefully rotate keys by publishing additional keys for a period to allow clients to learn them, before removing the deprecated key(s) and letting the new ones become the primary ones.
</p>
<p>
To practically rotate host keys, the operator of a sshd server should add additional <tt>HostKey</tt> statements to their <tt>sshd_config</tt> for the new keys, while keeping the existing keys in place. I.e.
<pre>
# Old keys
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_dsa_key
# New keys
HostKey /etc/ssh/ssh_host_ed25519_key_new
HostKey /etc/ssh/ssh_host_rsa_key_new
HostKey /etc/ssh/ssh_host_ecdsa_key_new
</pre>
Once these lines are added, sshd can be restarted to begin offering the new keys to clients who connect. The old keys, appearing first in the configuration, will be the ones actually used to authenticate the host to the client. Once the operator is satisfied that enough users have had a chance to pick up the new keys, they can rename replace the original keys with the new keys and remove the extra <tt>HostKey</tt> lines from <tt>sshd_config</tt>.
</p>
<p>
This mechanism isn't perfect: first, it only works for users who actually connect to the server - if they don't happen to connect during the grace period when both old and new keys are offered then they will have to learn the new key manually afterwards. As such, it doesn't cope well with sudden key rotations (e.g. when the operator has reason to believe a key has been compromised).
</p>
<p>
Fortunately both these cases can be addressed with a bit of forethought: when setting up a server, generate some
<em>reserve</em> keys. Keep their private halves offline (e.g in a safe), but list them in <tt>sshd_config</tt> as described above. OpenSSH ≥6.8 will notify clients of the reserve public keys on every connection, so if you ever need to rotate keys in a hurry then they are already ready to go. You could generate multiple sets of reserve keys if you like - you aren't limited to a single set.
</p>
<p>
The host key rotation support is in OpenBSD -current and the <a href="http://www.openssh.com/portable.html#git">git HEAD</a> version of portable OpenSSH. Please try it out!
</p>
<p>
If you implement SSH yourself and want to add the extension to your own software, then setails of the protocol extension are in the <a href="https://anongit.mindrot.org/openssh.git/plain/PROTOCOL">PROTOCOL</a> file in the source distribution. It's trivial though: a global request <tt>hostkeys@openssh.com</tt>, sent once after authentication completes containing one or more public key blobs encoded as strings. In my biased opinion, its a small, easy to implement tweak to the SSH protocol that provides a significant improvement to the protocol.
</p>
Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com27tag:blogger.com,1999:blog-1832537127722643509.post-12502974235557337832014-10-06T20:03:00.000+11:002014-10-06T20:03:46.804+11:00Mandatory data retention in Australia<p>
Once again their are proposals for mandatory retention of Australian Internet data to improve domestic surveillance.
I think these are a terrible idea, both personally and professionally. Here is a letter I just sent to my local parlimentarian and senator that explains my reasoning.
</p>
<blockquote>
Dear Mr Thomson,<br>
<br>
I'm a resident in your electorate and am writing in regards to the proposed changes to the Telecommunications (Interception and Access) act to support mandatory data retention.<br>
<br>
As an an information security professional with >15 years experience, the proposed legislation is highly concerning. The proposals would create a huge trove of information that service providers would need to keep absolutely secure.<br>
<br>
Evidence suggests that this will not be possible. Consider the numerous security breaches of large financial institutions, the latest just last week at JP Morgan exposed the information of 76 million customers. Financial organisations are subject to strong regulation, have a direct incentive to maintain the security of their customer data, maintain generally good internal controls, undergo frequent external audits and hold decades' of experience dealing with rogue insiders. Despite all of this, they are frequently broken in to.<br>
<br>
Internet service providers have little to none of these factors in their favour. They generally maintain good security of their networks, but they do not have the skills, incentives or mindset needed to maintain the security of the highly-private data that is proposed to be collected. I would consider a breach to be inevitable - it might be an ISP employee checking on their spouse's browsing habits, an unethical provider selling the information or perhaps a foreign intelligence agency chuckling as they download the browsing habits of Australia...<br>
<br>
As a citizen, I am appalled by these proposals. They treat all citizens as suspects, and have the temerity to bill us for the privilege. They create a system of domestic surveillance more complete than any that enabled the horrors of last century and, in doing so, allow countries that lack our commitment to human rights to point and say "hey, but Australia's already doing it". They create moral hazard for more surveillance, more collection and greater access to the collected data that will be difficult to wind back. There has been no explanation of what threat could justify this immense undertaking.<br>
<br>
I ask you to oppose these amendments and exhort your colleagues to do the same. If you would like to discuss the above further I would be happy to oblige.<br>
<br>
Thanks,<br>
Damien Miller
</blockquote>
<p>
If you agree, I encourage you to compose an email of your own or join one of the online campaigns like <a href="http://stopthespies.org">stopthespies.org</a>.
</p>Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com0tag:blogger.com,1999:blog-1832537127722643509.post-80641271184138244332014-01-14T17:20:00.000+11:002014-03-13T11:55:12.501+11:00Hostname canonicalisation in OpenSSH<p>
OpenSSH 6.5 will introduce some new options to allow the client to canonicalise unqualified domain names, allowing it (for example) to understand that I actually meant "<em>bigserver.mydomain.com</em>" when I typed "<tt>ssh bigserver</tt>". This turns out to be important because, even though your host's DNS resolver will connect you to the host that you intended, ssh doesn't know the full name for it.
</p>
<p>
If ssh doesn't know the full name for a host then it can't reliably match it with a host key. The problem is even worse when the server is offering a certificate host key - these (should) contain the fully-qualified domain name (FQDN) of the server, but this break when users type "<tt>ssh bigserver</tt>" without the remainder of the domain name. A common workaround is to add "<tt>Hostname</tt>" or "<tt>HostkeyAlias</tt>" directives to ssh_config, but that is messy and doesn't scale well to lots of hosts. The other workaround for certificates of adding the unqualified names to the list of certificate principals is also terrible.
</p>
<p>
One might be forgiven for thinking that the system resolver should be able to help us here; after all - it knows the FQDN for the destination host because it knows all the domain search paths the user configured and which one was actually taken. Unfortunately, it turns out not to be useful for two reasons:
</p>
<ol>
<li>
The resolver doesn't actually offer a way to figure out what the fully-qualified name is. Some platforms do, via the AI_FQDN option - but it isn't widely available (Windows and OpenBSD only AFAIK)
</li>
<li>
Even if we could get the name, then we couldn't trust it for anything configured via DHCP anyway. On most systems, the set of domain search paths is configured by DHCP and a rogue DHCP server could supply a malicious set.
</li>
</ol>
<p>
My solution has been to add explicit hostname canonicalisation options that allow the user to define their own optional DNS search paths in OpenSSH itself. These options are:
<tt>CanonicalDomains</tt>,
<tt>CanonicalizeFallbackLocal</tt>,
<tt>CanonicalizeHostname</tt>,
<tt>CanonicalizeMaxDots</tt> and
<tt>CanonicalizePermittedCNAMEs</tt>. You may notice that they substantially duplicate the search path functionality you'd expect to find in <tt>resolv.conf</tt>.
</p>
<p>
<tt>CanonicalizeHostname</tt> turns canonicalisation off and on (it's off by default). <tt>CanonicalDomains</tt> specifies the list of domains to search for an unqualified hostname in. <tt>CanonicalizeMaxDots</tt> sets how many '.' characters must appear in a domain name before it is considered unqualified (e.g. if you want names like "ftp.dmz" to be subject to canonicalisation then you would set this to one or more). <tt>CanonicalizeFallbackLocal</tt> specifies whether the original, unqualified name should be passed to the system resolver if it wasn't found in any of the suffixes in <tt>CanonicalDomains</tt>. Finally <tt>CanonicalizePermittedCNAMEs</tt> specifies some rules for selectively following CNAMEs (DNS aliases) when canonicalising a name.
</p>
<p>
This should all be more clear with an example. This is what is at the top of my <tt>~/.ssh/config</tt>:
</p>
<pre>
CanonicalizeHostname yes
CanonicalDomains mindrot.org
CanonicalizeMaxDots 0
CanonicalizeFallbackLocal no
</pre>
<p>
This enables canonicalisation with a single search path of <em>mindrot.org</em>. When I type "<tt>ssh mail</tt>", the hostname <em>mail</em> will be judged unqualified since it contains the no period characters (specifically, less than or equal to <tt>CanonicalizeMaxDots</tt>), so ssh will try to resolve it in one of the <tt>CanonicalDomains</tt>. If <em>mail.mindrot.org</em> did not exist, then ssh won't bother attempting to continue with the original hostname <em>mail</em>.
</p>
<p>
I haven't mentioned <tt>CanonicalizePermittedCNAMEs</tt> yet, since it is the most complex and most users won't need it. It's useful in cases where your organisation's DNS has a number of CNAME aliases that point to the same host(s). It allows the user to specify rules for when the alias should be allowed to replace the original host name.
This option accepts multiple arguments, each of the form <em>source_pattern:target_pattern</em>. If the name (after canonicalisation and resolution) matches <em>source_pattern</em> <b>and</b> the destination of the CNAME matches <em>target_pattern</em> then the target of the CNAME will replace the original name
The rules are pretty flexible; they accept the pattern syntax used widely in OpenSSH (with negation, '*' and '?' wildcards). Hopefully an example will make this clear too:
</p>
<pre>
CanonicalizeHostname yes
CanonicalDomains example.com int.example.com
CanonicalizeMaxDots 1
CanonicalizeFallbackLocal yes
CanonicalizePermittedCNAMEs mail.*.example.com:anycast-mail.int.example.com dns*.example.com:dns*.dmz.example.com
</pre>
<p>
This example enables canonicalisation with a couple of suffixes in the search path. It also turns <tt>CanonicalizeMaxDots</tt> up to 1, so a name like <em>mail.dmz</em> will be searched in each suffix. If a name does not resolve in any suffix then it will be passed to the system resolver as a fallback. Finally, some rules for following CNAMEs are specified: any CNAME matching <em>mail.*.example.com</em> will be followed so long as the ultimate destination is <em>anycast-mail.int.example.com</em> and any host name matching <em>dns*.example.com</em> will be followed so long as the destination matches <em>dns*.dmz.example.com</em>.
</p>
<p>
These options will be available in OpenSSH 6.5, which is due really soon (hopefully by the end of the month).
I'd love to hear any feedback about them.
</p>Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com0tag:blogger.com,1999:blog-1832537127722643509.post-899517821358323042013-12-10T15:31:00.000+11:002013-12-10T15:31:41.030+11:00PGP keys rotated<p>
I just (belatedly) rotated my PGP keys. The old ID was 86FF9C48 and the new 6D920D30 with a fingerprint of <tt>59C2 118E D206 D927 E667 EBE3 D3E5 F56B 6D92 0D30</tt>. The new key should be available from the keyserver network and is signed by my old key.
As a very infrequent user of gnupg for anything but generating signatures, I found <a href="http://www.apache.org/dev/key-transition.html">apache.org's key transition guidelines</a> to be very useful in doing this.
</p>
<p>
One thing that I noticed along the way that doesn't seem to be in the documentation. Where gnupg asks you for an expiry duration, it will actually accept an exact timestamp too. So you can answer something like <tt>20201231T235959</tt> and it will do the right thing.
</p>
<p>
My whole key blob is now:<br>
<textarea readonly rows=10 cols=70>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (OpenBSD)
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
=s7sa
-----END PGP PUBLIC KEY BLOCK-----
</textarea>
</p>Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com6tag:blogger.com,1999:blog-1832537127722643509.post-33087806807726830182013-11-29T22:38:00.000+11:002014-06-11T08:35:38.312+10:00ChaCha20 and Poly1305 in OpenSSH<p>
Recently, I committed support for a new authenticated encryption cipher for OpenSSH, <em>chacha20-poly1305@openssh.com</em>. This cipher combines two primitives from Daniel J. Bernstein: the <a href="http://cr.yp.to/chacha.html">ChaCha20 cipher</a> and the <a href="http://cr.yp.to/mac.html">Poly1305 MAC</a> (Message Authentication Code) and was inspired by Adam Langley's <a href="http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03">similar proposal</a> for TLS.
</p>
<p>
Why another cipher and MAC? A few reasons... First, we would like a high-performance cipher to replace RC4 since it is pretty close to broken now, we'd also like an authenticated encryption mode to complement AES-GCM - which is great if your hardware supports it, but takes significant voodoo to make run in constant time and, finally, having an authenticated encryption mode that is based on a stream cipher allows us to encrypt the packet lengths again.
</p>
<p>
Wait, what do you mean by "encrypt the packet lengths <em>again</em>"? (last rhetorical question, I promise) Well, it's a long story that requires a little background:
</p>
<p>
Back in the dark ages of the SSH2 protocol's design, there wasn't consensus among cryptographers on the best order to apply encryption and authentication in protocols - in fact, the three main cryptographic protocols to emerge from the 1990s - SSL, SSH and IPsec - all use different choices: SSL calculated a MAC over the packet's plaintext, appended it to the plaintext packet and encrypted and sent the lot - a construction now called "MAC then Encrypt" or "MtE". IPsec encrypted the plaintext, calculated the MAC over the ciphertext and appended it - this is now called "Encrypt then MAC" (EtM). SSH calculated the MAC over the plaintext, encrypted it and then appended the MAC - this is called "Encrypt and MAC" (EaM).
</p>
<p>
Of these, only "Encrypt then MAC" is now considered safe and in retrospect it's pretty easy to see why: for MtE and EaM, it's necessary to decrypt and process the packet before checking the MAC. Doing this allows an active attacker (i.e. one who is happy to forge or modify messages) the chance to peek behind the veil of the encryption before the MAC check detects their mischief. This has resulted in attacks on both SSL/TLS and SSH that wouldn't otherwise have been possible.
</p>
<p>
Recent versions of OpenSSH have offered some solutions to the problems caused by the original Encrypt-and-MAC design: AES-GCM cipher modes and Encrypt-then-MAC MAC modes. The AES-GCM ciphers <em>aes128-gcm@openssh.com</em> and <em>aes256-gcm@openssh.com</em> replace the usual cipher+MAC combination with a combined <a href="https://en.wikipedia.org/wiki/Authenticated_encryption">authenticated encryption</a> mode the provides confidentiality and integrity in a single cryptographic algorithm. The Encrypt-then-MAC MAC modes alter the SSH packet format to be more IPsec-like: performing encryption first and then authenticating the ciphertext.
</p>
<p>
Both AES-GCM and the EtM MAC modes have a small downside though: because we no longer desire to decrypt the packet as we go, the packet length must be transmitted in plaintext. This unfortunately makes some forms of traffic analysis easier as the attacker can just read the packet lengths directly. OpenSSH takes some countermeasures to obscure the lengths of obvious secrets like passwords used for login or typed into an active session, but I haven't felt entirely comfortable with the protocol revealing the length of every packet sent on the wire.
</p>
<p>
The new <em>chacha20-poly1305@openssh.com</em> avoids this though. In addition to providing authenticated encryption with integrity-checking performed before unwrapping encrypted data, this mode uses a second stream cipher instance to separately encrypt the packet lengths to obscure them from eavesdroppers. An active attacker can still play games by fiddling with the packet lengths, but doing so will reveal nothing about the packet payloads themselves - they can make the receiving end read a smaller or larger packet than intended, but the MAC will be checked (and the check will fail) before anything is decrypted or used. Fortunately ChaCha20 is very fast and has quite small keys, so maintaining a separate instance is very cheap.
</p>
<p>
We're not done yet though - an attacker may still observe the encrypted packets on the network to try to ascertain their length, and right now they are likely to be successful. I hope to add some features to frustrate this sort of traffic analysis some time next year.
</p>
<p>
Full details on the new mode are in the <a href="http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?rev=HEAD;content-type=text%2Fplain">PROTOCOL.chacha20poly1305</a> file in OpenSSH and the <a href="http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/cipher-chachapoly.c?rev=HEAD;content-type=text%2Fplain">source code</a> for the cipher itself. If there is anything that these don't explain, then feel free to contact me.Damien Millerhttp://www.blogger.com/profile/14257661959110958567noreply@blogger.com8