2010-08-13
PPP over ssh: solving problems with indirection
There is an old aphorism in Computer Science that any problem can be solved by another level of indirection (Wikipedia credits it to David Wheeler). Today I have an illustration of this.
I mentioned that I was having problems
with USB serial ports on my just upgraded to Fedora 13 machine.
Specifically, starting up PPP on such a port would hang the pppd
process (and then any other process that touched the serial port).
Since my DSL link is still down, this is a problem.
It turns out that the specific issue is that on my machine,
trying to switch to the PPP line discipline on a USB serial port
hangs the process; I suspect locking issues between the kernel's TTY
layer and USB layer. Reasonably, the PPP daemon switches its tty to the
PPP line discipline pretty much the moment it starts, and there goes my
connection attempt (and my dialup connection).
(I suspect that this happens on all SMP x86_64 Linux machines with a recent enough kernel, and possibly all SMP machines. It doesn't happen on a uniprocessor x86 machine. Interested parties can see the Fedora bug report.)
This is not a general bug with the TTY layer's handling of the PPP line discipline, or it would have been noticed well before now. In particular, you can switch to the PPP line discipline on a pseudo-tty without problems.
(I wound up testing this sort of by accident. My PPP account has a
somewhat weird setup, and the most convenient way to test that it had
survived the Fedora 13 upgrade was to just ssh
in to it in a terminal
window and see if it spewed a PPP connection initiation at me or printed
errors. After the upgrade I tried this and had it work, and I thought
nothing of it until later.)
So I solved my problem with indirection; I arranged to run pppd
on
a pty instead of on the serial port itself, transparently passing all
IO back and forth between the serial port and the pty. This needed
something to do this work, and the simple program for this is ssh
in
its transparent mode. So now my connect script doesn't directly log in to
my PPP account; instead it logs in to a regular account and immediately
does an 'ssh -e none pppme@localhost
'.
(I could have written a program to do this without the SSH overhead, but
ssh
has the great virtue of already existing and working and this is
an expedient hack that I sincerely hope is not living on for too long.)
Sidebar: the logical extension of this hack
Suppose that you have two machines; one machine with a dialin modem and
a regular account but no PPP setup, and another machine where you can
actually run PPP but you don't have a (working) dialin modem. We can
solve the problem of getting a PPP link up in this situation in exactly
the same way; since we're using ssh
, we can perfectly well ssh
off
to another machine entirely instead of localhost. It may not have great
latency and performance, but as the wise man once observed, working at
all is better performance than not working.
(Extensions to the situation where the first machine can't directly talk to the second machine are left as an exercise for the reader.)