Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: OpenSSH: Dev

PATCH: Support for encrypted host keys

 

 

OpenSSH dev RSS feed   Index | Next | Previous | View Threaded


zevweiss at gmail

Jan 28, 2012, 1:25 AM

Post #1 of 9 (371 views)
Permalink
PATCH: Support for encrypted host keys

Hello all,

I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.

My initial implementation instead operated by passing the passphrase along to the rexec child, but I decided I thought it was slightly nicer to decrypt the key once and pass it along rather than redoing it every time. I can send the previous version if that would be preferred though -- this key-passing version does have some resulting ugliness in its handling of options.num_host_key_files, as described in a comment in the patch.


Thanks,
Zev Weiss
--

Makefile.in | 2 +-
buffer.h | 5 ++
bufkey.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
sshd.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
4 files changed, 253 insertions(+), 27 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 3be3aa6..3b47d18 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -61,7 +61,7 @@ MANFMT=@MANFMT@

TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)

-LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o bufkey.o buffer.o \
canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
diff --git a/buffer.h b/buffer.h
index e2a9dd1..a0c62c1 100644
--- a/buffer.h
+++ b/buffer.h
@@ -86,6 +86,11 @@ char *buffer_get_cstring_ret(Buffer *, u_int *);
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
int buffer_get_char_ret(char *, Buffer *);

+#include "key.h"
+
+void buffer_put_key(Buffer *buffer, const Key *key);
+Key *buffer_get_key(Buffer *buffer);
+
#ifdef OPENSSL_HAS_ECC
#include <openssl/ec.h>

diff --git a/bufkey.c b/bufkey.c
new file mode 100644
index 0000000..85a0c35
--- /dev/null
+++ b/bufkey.c
@@ -0,0 +1,132 @@
+/*
+ * Author: Zev Weiss <zevweiss [at] gmail>
+ *
+ * Functions for storing and retrieving Key structs into/from Buffers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include <openssl/bn.h>
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "log.h"
+#include "key.h"
+#include "rsa.h"
+
+static void
+buffer_put_key_rsa(Buffer *buffer, const RSA *key)
+{
+ buffer_put_bignum(buffer, key->e);
+ buffer_put_bignum(buffer, key->n);
+ buffer_put_bignum(buffer, key->d);
+ buffer_put_bignum(buffer, key->iqmp);
+ buffer_put_bignum(buffer, key->p);
+ buffer_put_bignum(buffer, key->q);
+}
+
+static void
+buffer_get_key_rsa(Buffer *buffer, RSA *key)
+{
+ buffer_get_bignum(buffer, key->e);
+ buffer_get_bignum(buffer, key->n);
+ buffer_get_bignum(buffer, key->d);
+ buffer_get_bignum(buffer, key->iqmp);
+ buffer_get_bignum(buffer, key->p);
+ buffer_get_bignum(buffer, key->q);
+ rsa_generate_additional_parameters(key);
+}
+
+static void
+buffer_put_key_dsa(Buffer *buffer, const DSA *key)
+{
+ buffer_put_bignum(buffer, key->p);
+ buffer_put_bignum(buffer, key->q);
+ buffer_put_bignum(buffer, key->g);
+ buffer_put_bignum(buffer, key->pub_key);
+ buffer_put_bignum(buffer, key->priv_key);
+}
+
+static void
+buffer_get_key_dsa(Buffer *buffer, DSA *key)
+{
+ buffer_get_bignum(buffer, key->p);
+ buffer_get_bignum(buffer, key->q);
+ buffer_get_bignum(buffer, key->g);
+ buffer_get_bignum(buffer, key->pub_key);
+ buffer_get_bignum(buffer, key->priv_key);
+}
+
+void
+buffer_put_key(Buffer *buffer, const Key *key)
+{
+ if (key->cert != NULL || key->ecdsa != NULL || key->ecdsa_nid != -1)
+ fatal("%s: unsupported key feature", __func__);
+
+ buffer_put_int(buffer, key->type);
+ buffer_put_int(buffer, key->flags);
+
+ switch (key->type) {
+ case KEY_RSA1:
+ case KEY_RSA:
+ buffer_put_key_rsa(buffer, key->rsa);
+ break;
+ case KEY_DSA:
+ buffer_put_key_dsa(buffer, key->dsa);
+ break;
+ default:
+ fatal("%s: unsupported key type (%s)", __func__,
+ key_type(key));
+ }
+}
+
+Key *
+buffer_get_key(Buffer *buffer)
+{
+ Key *key;
+ int type, flags;
+
+ type = buffer_get_int(buffer);
+ flags = buffer_get_int(buffer);
+
+ key = key_new_private(type);
+ key->flags = flags;
+
+ switch (type) {
+ case KEY_RSA1:
+ case KEY_RSA:
+ buffer_get_key_rsa(buffer, key->rsa);
+ break;
+ case KEY_DSA:
+ buffer_get_key_dsa(buffer, key->dsa);
+ break;
+ default:
+ fatal("%s: unsupported key type (%s)", __func__,
+ key_type(key));
+ }
+
+ return key;
+}
diff --git a/sshd.c b/sshd.c
index c8d71f8..f458860 100644
--- a/sshd.c
+++ b/sshd.c
@@ -175,6 +175,7 @@ int rexeced_flag = 0;
int rexec_flag = 1;
int rexec_argc = 0;
char **rexec_argv;
+int num_rexec_recvd_host_keys = 0;

/*
* The sockets that the server is listening; this is used in the SIGHUP
@@ -898,6 +899,7 @@ usage(void)
static void
send_rexec_state(int fd, Buffer *conf)
{
+ int i, num_host_keys;
Buffer m;

debug3("%s: entering fd = %d config len %d", __func__, fd,
@@ -914,6 +916,8 @@ send_rexec_state(int fd, Buffer *conf)
* bignum p "
* bignum q "
* string rngseed (only if OpenSSL is not self-seeded)
+ * u_int num_host_keys
+ * Key host_keys num_host_keys times
*/
buffer_init(&m);
buffer_put_cstring(&m, buffer_ptr(conf));
@@ -934,6 +938,18 @@ send_rexec_state(int fd, Buffer *conf)
rexec_send_rng_seed(&m);
#endif

+ num_host_keys = 0;
+ for (i = 0; i < options.num_host_key_files; i++) {
+ if (sensitive_data.host_keys[i] != NULL)
+ ++num_host_keys;
+ }
+
+ buffer_put_int(&m, num_host_keys);
+ for (i = 0; i < options.num_host_key_files; i++) {
+ if (sensitive_data.host_keys[i] != NULL)
+ buffer_put_key(&m, sensitive_data.host_keys[i]);
+ }
+
if (ssh_msg_send(fd, 0, &m) == -1)
fatal("%s: ssh_msg_send failed", __func__);

@@ -946,8 +962,10 @@ static void
recv_rexec_state(int fd, Buffer *conf)
{
Buffer m;
+ Key *hk;
char *cp;
u_int len;
+ int i, num_host_keys;

debug3("%s: entering fd = %d", __func__, fd);

@@ -981,6 +999,30 @@ recv_rexec_state(int fd, Buffer *conf)
rexec_recv_rng_seed(&m);
#endif

+ num_host_keys = buffer_get_int(&m);
+ debug("%s: receiving %d host keys", __func__, num_host_keys);
+ sensitive_data.host_keys = xcalloc(num_host_keys, sizeof(Key *));
+
+ num_rexec_recvd_host_keys = num_host_keys;
+
+ for (i = 0; i < num_host_keys; i++) {
+ hk = buffer_get_key(&m);
+ debug("%s: received %s host key", __func__, key_type(hk));
+ sensitive_data.host_keys[i] = hk;
+ switch (hk->type) {
+ case KEY_RSA1:
+ sensitive_data.ssh1_host_key = hk;
+ sensitive_data.have_ssh1_key = 1;
+ break;
+ case KEY_RSA:
+ case KEY_DSA:
+ sensitive_data.have_ssh2_key = 1;
+ break;
+ default:
+ fatal("%s: unsupported host key type", __func__);
+ }
+ }
+
buffer_free(&m);

debug3("%s: done", __func__);
@@ -1308,6 +1350,41 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
}
}

+static Key *
+sshd_key_load_private(const char *filename)
+{
+ Key *key;
+ char prompt[300], *passphrase = "";
+ int quit, i;
+
+ key = key_load_private(filename, passphrase, NULL);
+
+ if (key == NULL) {
+ snprintf(prompt, sizeof prompt,
+ "Enter passphrase for key '%.100s': ", filename);
+ /* options.number_of_password_prompts doesn't exist in sshd */
+ for (i = 0; i < 3; i++) {
+ passphrase = read_passphrase(prompt, 0);
+ if (strcmp(passphrase, "") != 0) {
+ key = key_load_private(filename, passphrase,
+ NULL);
+ quit = 0;
+ } else {
+ debug2("no passphrase given, try next key");
+ quit = 1;
+ }
+ if (key != NULL || quit) {
+ memset(passphrase, 0, strlen(passphrase));
+ xfree(passphrase);
+ break;
+ }
+ memset(passphrase, 0, strlen(passphrase));
+ xfree(passphrase);
+ debug2("bad passphrase given, try again...");
+ }
+ }
+ return key;
+}

/*
* Main program for the daemon.
@@ -1550,6 +1627,15 @@ main(int ac, char **av)
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
&cfg, NULL, NULL, NULL);

+ /*
+ * parse_server_config() changes options.num_host_key_files,
+ * but we need to change it back to what we received via
+ * recv_rexec_state to accurately reflect the number of keys
+ * in sensitive_data.host_keys. This is a bit ugly.
+ */
+ if (rexeced_flag)
+ options.num_host_key_files = num_rexec_recvd_host_keys;
+
seed_rng();

/* Fill in default values for those options not explicitly set. */
@@ -1583,35 +1669,38 @@ main(int ac, char **av)
}
endpwent();

- /* load private host keys */
- sensitive_data.host_keys = xcalloc(options.num_host_key_files,
- sizeof(Key *));
- for (i = 0; i < options.num_host_key_files; i++)
- sensitive_data.host_keys[i] = NULL;
-
- for (i = 0; i < options.num_host_key_files; i++) {
- key = key_load_private(options.host_key_files[i], "", NULL);
- sensitive_data.host_keys[i] = key;
- if (key == NULL) {
- error("Could not load host key: %s",
- options.host_key_files[i]);
+ if (!rexeced_flag) {
+ /* load private host keys */
+ sensitive_data.host_keys = xcalloc(options.num_host_key_files,
+ sizeof(Key *));
+ for (i = 0; i < options.num_host_key_files; i++)
sensitive_data.host_keys[i] = NULL;
- continue;
- }
- switch (key->type) {
- case KEY_RSA1:
- sensitive_data.ssh1_host_key = key;
- sensitive_data.have_ssh1_key = 1;
- break;
- case KEY_RSA:
- case KEY_DSA:
- case KEY_ECDSA:
- sensitive_data.have_ssh2_key = 1;
- break;
+
+ for (i = 0; i < options.num_host_key_files; i++) {
+ key = sshd_key_load_private(options.host_key_files[i]);
+ sensitive_data.host_keys[i] = key;
+ if (key == NULL) {
+ error("Could not load host key: %s",
+ options.host_key_files[i]);
+ sensitive_data.host_keys[i] = NULL;
+ continue;
+ }
+ switch (key->type) {
+ case KEY_RSA1:
+ sensitive_data.ssh1_host_key = key;
+ sensitive_data.have_ssh1_key = 1;
+ break;
+ case KEY_RSA:
+ case KEY_DSA:
+ case KEY_ECDSA:
+ sensitive_data.have_ssh2_key = 1;
+ break;
+ }
+ debug("private host key: #%d type %d %s", i, key->type,
+ key_type(key));
}
- debug("private host key: #%d type %d %s", i, key->type,
- key_type(key));
}
+
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
logit("Disabling protocol version 1. Could not load host key");
options.protocol &= ~SSH_PROTO_1;

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


dkg at fifthhorseman

Jan 31, 2012, 6:56 AM

Post #2 of 9 (352 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

Hi Zev--

On 01/28/2012 04:25 AM, Zev Weiss wrote:
> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.

Can i ask what threats you hope to mitigate with this approach? What
are your concerns about having a cleartext ~/.ssh/known_hosts?

Also, you might want to file this at https://bugzilla.mindrot.org/, so
that the suggestion and the patch don't get lost in the mailing list
archive if they're not immediately accepted or applied.

Regards,

--dkg
Attachments: signature.asc (1.01 KB)


keisial at gmail

Jan 31, 2012, 7:37 AM

Post #3 of 9 (354 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

Daniel Kahn Gillmor wrote:
> Hi Zev--
>
> On 01/28/2012 04:25 AM, Zev Weiss wrote:
>> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.
> Can i ask what threats you hope to mitigate with this approach? What
> are your concerns about having a cleartext ~/.ssh/known_hosts?

Daniel, I think he refers to /etc/ssh/ssh_host_*key, not ~/.ssh/known_hosts

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


zevweiss at gmail

Jan 31, 2012, 8:25 AM

Post #4 of 9 (358 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On Jan 31, 2012, at 8:56 AM, Daniel Kahn Gillmor wrote:

> Hi Zev--
>
> On 01/28/2012 04:25 AM, Zev Weiss wrote:
>> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.
>
> Can i ask what threats you hope to mitigate with this approach? What
> are your concerns about having a cleartext ~/.ssh/known_hosts?
>
> Also, you might want to file this at https://bugzilla.mindrot.org/, so
> that the suggestion and the patch don't get lost in the mailing list
> archive if they're not immediately accepted or applied.
>
> Regards,
>
> --dkg
>

As Ángel mentioned, this regards server-side /etc/ssh/ssh_host*key files, not ~/.ssh/known_hosts on the client.

As for threat mitigation -- an attacker who was able to read the file, e.g. via some sort of permissions bypass or perhaps a compromised system backup, would not be immediately able to impersonate the host.

Thanks for the bugzilla tip -- now posted at https://bugzilla.mindrot.org/show_bug.cgi?id=1974.


Zev

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


dkg at fifthhorseman

Jan 31, 2012, 8:58 AM

Post #5 of 9 (353 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On 01/31/2012 10:37 AM, Ángel Gonzålez wrote:

> Daniel, I think he refers to /etc/ssh/ssh_host_*key, not ~/.ssh/known_hosts

Ah, you're right. sorry, i misinterpreted (and clearly didn't read the
patch). Thanks for the correction.

Zev, am i right in thinking that your approach to this problem seems to
make it so that launching sshd might or might not prompt the user for a
passphrase when starting up? This might be tricky or cause trouble with
many common init systems.

What about an approach instead that allows sshd to talk to a running
ssh-agent for its keys? Then a system administrator could load the host
key to the system ssh-agent at any point, leaving them
passphrase-protected on disk.

This seems like it might be less code introduced, and it also introduces
a nice symmetry with the ssh client. Also, improvements with the agent
(e.g. connecting to smartcards) would flow naturally to sshd as well.

--dkg
Attachments: signature.asc (1.01 KB)


nkadel at gmail

Jan 31, 2012, 11:39 AM

Post #6 of 9 (353 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On Tue, Jan 31, 2012 at 9:56 AM, Daniel Kahn Gillmor
<dkg [at] fifthhorseman> wrote:
> Hi Zev--
>
> On 01/28/2012 04:25 AM, Zev Weiss wrote:
>> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this.  I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this.  It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.
>
> Can i ask what threats you hope to mitigate with this approach?  What
> are your concerns about having a cleartext ~/.ssh/known_hosts?

One concern is pretending to be the designated host with host keys
retrieved from backup or from sites that deploy identical hostkeys via
a base installation or replicated OS image in virtualization. Since
the sshd handles passwords in many environments, and there is no
mechanism for revocation or expiration of host keys in
$HOME/.ssh/known_hosts, the ability to pretend to be a previously
accepted host with stolen keys has presented a functional security
issue since SSH was first written.

Too many sites are far, far too careless with these keys since "if
they're inside our network, we have much bigger problems", both of
which I've heard on various occasions.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


imorgan at nas

Jan 31, 2012, 4:53 PM

Post #7 of 9 (355 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On Tue, Jan 31, 2012 at 13:39:09 -0600, Nico Kadel-Garcia wrote:
> On Tue, Jan 31, 2012 at 9:56 AM, Daniel Kahn Gillmor
> <dkg [at] fifthhorseman> wrote:
> > Hi Zev--
> >
> > On 01/28/2012 04:25 AM, Zev Weiss wrote:
> >> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. ?I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. ?It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.
> >
> > Can i ask what threats you hope to mitigate with this approach? ?What
> > are your concerns about having a cleartext ~/.ssh/known_hosts?
>
> One concern is pretending to be the designated host with host keys
> retrieved from backup or from sites that deploy identical hostkeys via
> a base installation or replicated OS image in virtualization. Since
> the sshd handles passwords in many environments, and there is no
> mechanism for revocation or expiration of host keys in
> $HOME/.ssh/known_hosts, the ability to pretend to be a previously
> accepted host with stolen keys has presented a functional security
> issue since SSH was first written.

With recent versions of OpenSSH, 5.4p1 and later, you can use host
certificates which can be expired or revoked. Also, regarding backups,
it is possible to exclude the private keys from being backed up. That is
only a partial solution and would mean that new keys would have to be
created if the old ones were lost.

>
> Too many sites are far, far too careless with these keys since "if
> they're inside our network, we have much bigger problems", both of
> which I've heard on various occasions.

Note that encrypting the private keys would break ssh-keysign (unless
some agent mechanism is used). Thus, this would break hostbased
authentication in cases where the client host used encrypted host keys.
--
Iain Morgan
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


nkadel at gmail

Jan 31, 2012, 5:50 PM

Post #8 of 9 (354 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On Tue, Jan 31, 2012 at 7:53 PM, Iain Morgan <imorgan [at] nas> wrote:
> On Tue, Jan 31, 2012 at 13:39:09 -0600, Nico Kadel-Garcia wrote:
>> On Tue, Jan 31, 2012 at 9:56 AM, Daniel Kahn Gillmor
>> <dkg [at] fifthhorseman> wrote:
>> > Hi Zev--
>> >
>> > On 01/28/2012 04:25 AM, Zev Weiss wrote:
>> >> I recently found myself wanting to run sshd with passphrase-protected host keys rather than the usual unencrypted format, and was somewhat surprised to discover that sshd did not support this. ?I'm not sure if there's any particular reason for that, but I've developed the below patch (relative to current CVS at time of writing) that implements this. ?It prompts for the passphrase when the daemon is started, similarly to Apache's behavior with encrypted SSL certificates.
>> >
>> > Can i ask what threats you hope to mitigate with this approach? ?What
>> > are your concerns about having a cleartext ~/.ssh/known_hosts?
>>
>> One concern is pretending to be the designated host with host keys
>> retrieved from backup or from sites that deploy identical hostkeys via
>> a base installation or replicated OS image in virtualization. Since
>> the sshd handles passwords in many environments, and there is no
>> mechanism for revocation or expiration of host keys in
>> $HOME/.ssh/known_hosts, the ability to pretend to be a previously
>> accepted host with stolen keys has presented a functional security
>> issue since SSH was first written.
>
> With recent versions of OpenSSH, 5.4p1 and later, you can use host
> certificates which can be expired or revoked. Also, regarding backups,
> it is possible to exclude the private keys from being backed up. That is
> only a partial solution and would mean that new keys would have to be
> created if the old ones were lost.

Good! I'm afraid I'm compelled by work to spend my time with older
releases in "production" environments. And until more deployed clients
support this as well, I'm afraid it will still be a risk. But it's a
good move.

And yes, backing up the private keys is important if you have to
restore the host. It's *precisely* the sort of data you want to be
able to build an authorized replacement host.

>> Too many sites are far, far too careless with these keys since "if
>> they're inside our network, we have much bigger problems", both of
>> which I've heard on various occasions.
>
> Note that encrypting the private keys would break ssh-keysign (unless
> some agent mechanism is used). Thus, this would break hostbased
> authentication in cases where the client host used encrypted host keys.

Excellent point!
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


djm at mindrot

Feb 5, 2012, 1:59 PM

Post #9 of 9 (353 views)
Permalink
Re: PATCH: Support for encrypted host keys [In reply to]

On Tue, 31 Jan 2012, Daniel Kahn Gillmor wrote:

> What about an approach instead that allows sshd to talk to a running
> ssh-agent for its keys? Then a system administrator could load the host
> key to the system ssh-agent at any point, leaving them
> passphrase-protected on disk.

I'm hoping to implement this anyway to support hostkeys in PKCS11 tokens.
It would be fantastic if someone did it first and saved me the work :)

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

OpenSSH dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.