Serving SSH sessions

Ken Yap, ken_yap AT users PERIOD sourceforge PERIOD net

7 January 1999

This document shows how to provide a login session that directly connects to remote hosts with SSH.


I wanted a login program that would connect the user directly to a remote host with SSH. At first I thought of writing my own login program, then I remembered that mgetty could be configured to call any login program. So here's what I did:

In /etc/mgetty+sendfax/login.config I added the line:


*@*		sshguest	@	/usr/local/etc/mgetty-ssh @

In /etc/inittab I added the line:


8:35:respawn:/sbin/mgetty -r tty8

I picked a free virtual tty, you may want to expand this to other ttys later.

In etc/mgetty+sendfax/mgetty.config I added the lines:


port tty8
toggle-dtr n
ignore-carrier y
blocking y
direct y
login-time -1

Thanks to Gert Doering (mgetty author) for the advice on the above settings.

I added this user to /etc/passwd:


sshguest:*:199:199:SSH guest:/tmp:

If you are using shadow passwords you should also add an entry to /etc/shadow.

The mgetty-ssh Perl script mentioned above is:


#!/usr/bin/perl
die "No argument\n" if !defined($ARGV[0]);
($name, $host) = split /@/, $ARGV[0];
# remove leading non-alphanums from name and host to prevent
# masquerading as arguments
$name =~ s/^[^a-z0-9]*//;
$host =~ s/^[^a-z0-9]*//;
# remove whitespace as well
$name =~ s/[ \t\f]//g;
$host =~ s/[ \t\f]//g;
# limit length of strings
$name = substr($name, 0, 64);
$host = substr($host, 0, 256);
# do we have anything left?
die "Name or host null\n" if ($name eq '' or $host eq '');
exec '/usr/bin/ssh', '-e', 'none', '-o', 'FallBackToRsh=no',
	'-o', 'StrictHostKeyChecking=yes', '-l', $name, $host;

Make sure this script is executable. If you are concerned that Perl takes up too much resources for a transient script, feel free to write the C equivalent.

Make sure any remote hosts you want to connect to have their public keys in /etc/ssh/ssh_known_hosts

Now on tty8 enter user@remote as the login name. You will get the following:


Red Hat Linux release 5.2 (Apollo)
Kernel 2.0.36 on an i486

login: user@remote
user@remote's password:
Last login: Fri Dec 25 10:34:12 1998 from xterm.foo.com.au
No mail.
[user@remote user]$

After I did this for mgetty, Peter Samuel pointed me to rungetty which is essentially an enhanced mingetty but can invoke programs other than login. Unlike mgetty, rungetty does not have any pattern matching facilities on the login name or indeed any means of passing the login name to the script. We get around this by prompting for the name in the script itself.

In /etc/inittab, add the line:


8:35:respawn:/usr/local/sbin/rungetty -u sshguest tty8 -- /usr/local/etc/rungetty-ssh

The rungetty-ssh script is essentially the same as the mgetty-ssh script but with a section to prompt for the login name:


#!/usr/bin/perl
$| = 1;
do {
	print "SSH to user\@host: ";
} while (!defined(sysread(STDIN, $_, 100)));
chomp($_);
($name, $host) = split /@/, $_;
# remove leading non-alphanums from name and host to prevent
# masquerading as arguments
$name =~ s/^[^a-z0-9]*//;
$host =~ s/^[^a-z0-9]*//;
# remove whitespace as well
$name =~ s/[ \t\f]//g;
$host =~ s/[ \t\f]//g;
# limit length of strings
$name = substr($name, 0, 64);
$host = substr($host, 0, 256);
# do we have anything left?
die "Name or host null\n" if ($name eq '' or $host eq '');
exec '/usr/bin/ssh', '-e', 'none', '-o', 'FallBackToRsh=no',
	'-o', 'StrictHostKeyChecking=yes', '-l', $name, $host;

The disadvantage is that when the prompt is active, this Perl script is always running. This offsets the gains made by using the lighter rungetty in place of mgetty. You may prefer to rewrite this in C to keep it very light.

This technique could be used on diskless workstations to provide login sessions to remote hosts.