On Wed, Nov 23, 2005 at 05:23:46PM -0600, Jason.C.Burns at wellsfargo.com
wrote:> > I'll bet PAM calls "last" to generate its "last
logged in at"
> > messages.
> > Do you see "last" running if you run sshd with UsePAM set to
"no"?
>
> Yes. Running sshd without GSSAPI, PAM, or Login, last is still called.
>
> This is the debug output from sshd:
> debug3: send_rexec_state: entering fd = 7 config len 379
> debug3: ssh_msg_send: type 0
> debug3: send_rexec_state: done
> debug1: rexec start in 4 out 4 newsock 4 pipe -1 sock 7
> <This is where last is running, hanging the process for ~1-2
minutes.>
> debug1: inetd sockets after dupping: 3, 3
> Connection from xx.xx.xx.xx port 36540
Ah, ok. That makes sense now. It's the entropy gatherer
(ssh-random-helper) that's running "last", not sshd, and it's
being
run when sshd reexecs itself for each connection.
ssh-random-helper will attempt to kill off programs that run more than
a couple of seconds, though it uses SIGTERM so a process can ignore it.
I can see 4 options for resolving this.
1) remove the "last" calls from ssh_prngd_cmds.
2) install prngd, which will obviate the need for sshd to run
ssh-random-helper.
3) run sshd with the (undocumented) -r option to disable reexec.
4) apply the following patch, which will be in OpenSSH 4.3.
The latter 2 will still mean "last" will probably be run at startup of
both sshd and ssh but not when sshd accepts a new connection.
And now the patch, against 4.2p1:
- (dtucker) [entropy.c entropy.h sshd.c] Pass RNG seed to the reexec'ed
process when sshd relies on ssh-random-helper. Should result in faster
logins on systems without a real random device or prngd. ok djm@
Index: entropy.c
==================================================================RCS file:
/usr/local/src/security/openssh/cvs/openssh_cvs/entropy.c,v
retrieving revision 1.49
diff -u -p -r1.49 entropy.c
--- entropy.c 17 Jul 2005 07:26:44 -0000 1.49
+++ entropy.c 24 Nov 2005 02:15:59 -0000
@@ -26,6 +26,7 @@
#include <openssl/rand.h>
#include <openssl/crypto.h>
+#include <openssl/err.h>
#include "ssh.h"
#include "misc.h"
@@ -33,6 +34,8 @@
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
+#include "buffer.h"
+#include "bufaux.h"
/*
* Portable OpenSSH PRNG seeding:
@@ -152,3 +155,30 @@ init_rng(void)
#endif
}
+#ifndef OPENSSL_PRNG_ONLY
+void
+rexec_send_rng_seed(Buffer *m)
+{
+ u_char buf[RANDOM_SEED_SIZE];
+
+ if (RAND_bytes(buf, sizeof(buf)) <= 0) {
+ error("Couldn't obtain random bytes (error %ld)",
+ ERR_get_error());
+ buffer_put_string(m, "", 0);
+ } else
+ buffer_put_string(m, buf, sizeof(buf));
+}
+
+void
+rexec_recv_rng_seed(Buffer *m)
+{
+ char *buf;
+ u_int len;
+
+ buf = buffer_get_string_ret(m, &len);
+ if (buf != NULL) {
+ debug3("rexec_recv_rng_seed: seeding rng with %u bytes", len);
+ RAND_add(buf, len, len);
+ }
+}
+#endif
Index: entropy.h
==================================================================RCS file:
/usr/local/src/security/openssh/cvs/openssh_cvs/entropy.h,v
retrieving revision 1.4
diff -u -p -r1.4 entropy.h
--- entropy.h 9 Feb 2001 01:55:36 -0000 1.4
+++ entropy.h 24 Nov 2005 02:15:59 -0000
@@ -22,12 +22,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: entropy.h,v 1.4 2001/02/09 01:55:36 djm Exp $ */
+/* $Id: entropy.h,v 1.5 2005/09/27 12:46:32 dtucker Exp $ */
#ifndef _RANDOMS_H
#define _RANDOMS_H
+#include "buffer.h"
+
void seed_rng(void);
void init_rng(void);
+void rexec_send_rng_seed(Buffer *);
+void rexec_recv_rng_seed(Buffer *);
+
#endif /* _RANDOMS_H */
Index: sshd.c
==================================================================RCS file:
/usr/local/src/security/openssh/cvs/openssh_cvs/sshd.c,v
retrieving revision 1.313
diff -u -p -r1.313 sshd.c
--- sshd.c 26 Jul 2005 11:54:56 -0000 1.313
+++ sshd.c 24 Nov 2005 02:15:59 -0000
@@ -800,6 +800,7 @@ send_rexec_state(int fd, Buffer *conf)
* bignum iqmp "
* bignum p "
* bignum q "
+ * string rngseed (only if OpenSSL is not self-seeded)
*/
buffer_init(&m);
buffer_put_cstring(&m, buffer_ptr(conf));
@@ -816,6 +817,10 @@ send_rexec_state(int fd, Buffer *conf)
} else
buffer_put_int(&m, 0);
+#ifndef OPENSSL_PRNG_ONLY
+ rexec_send_rng_seed(&m);
+#endif
+
if (ssh_msg_send(fd, 0, &m) == -1)
fatal("%s: ssh_msg_send failed", __func__);
@@ -858,6 +863,11 @@ recv_rexec_state(int fd, Buffer *conf)
rsa_generate_additional_parameters(
sensitive_data.server_key->rsa);
}
+
+#ifndef OPENSSL_PRNG_ONLY
+ rexec_recv_rng_seed(&m);
+#endif
+
buffer_free(&m);
debug3("%s: done", __func__);
@@ -1051,8 +1061,6 @@ main(int ac, char **av)
drop_cray_privs();
#endif
- seed_rng();
-
sensitive_data.server_key = NULL;
sensitive_data.ssh1_host_key = NULL;
sensitive_data.have_ssh1_key = 0;
@@ -1071,6 +1079,8 @@ main(int ac, char **av)
if (!rexec_flag)
buffer_free(&cfg);
+ seed_rng();
+
/* Fill in default values for those options not explicitly set. */
fill_default_server_options(&options);
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.