
The serial port is still
the way to access network components out of band. It is slow, but reliable, and
remarkably well standardized. It does not have technical whiz-bangs that can fail when one needs things to just work.
That makes it the natural way to access critical infrastructure and still being sure that this access vector still works
when most other things are down.
Every communication link has two sides, so there is a market for devices with a network link and a bigger number of
serial ports to connect the actual devices to. Commercial vendors have a broad choice of serial console servers. Most of
them, especially the small products with five to ten ports, are quite expensive, so I have been investigating how do
build a serial console server with el cheapo hardware.
USB comes to mind here, of course.
The hardware side is actually
quite easy: A seven-port USB hub, and seven USB-to-serial adaptors (using the widely-deployed Prolific PL2303) are
easily purchased for well below a hundred Euros, and naively connected. In my test setup, connected to the hp compaq
nc8000 that my blog readers should know only too well by now, the hub does not even need to have its power supply
connected. The notebook can power the hub and the seven adaptors just fine.
When the
UMTS card is plugged in, the ttyUSBx device nodes appear in the
order of plugging in the devices. When the system is booted, the order is not very predictable, so one needs - again -
udev to give predictable device node names.
udevinfo is an important tool to obtain the data set of an USB device which is available to match a device and to act
appropriately when it is connected. udevinfo sorts the devices into a tree and shows the relationship of the devices,
which device is “behind” which other device from the system’s point of view. udevinfo’s output
starts at the leaf of the device tree and shows the information for each node up the tree until its root is reached.
One pitfall is that one can only match against the leaf and
_one_ other node more up the tree. So you cannot do
matches like “the pl2303-based device connected to port 3 on hub 2-3 will be designated USBserial3”. If you
try this, your rule will silently be ignored. This is a major turn-off in udev’s implementation. I didn’t
try it on sid, but etch definetely shows this behavior. So one can only match like “the tty on the USB subsystem
connected to port 3 on hub 2-3 will be designated USBserial3”, but that’s probably as good as it’ll
get.
The cause for my hub having only seven ports clearly shows itself when one looks at the udevinfo outputs of the fully
equipped USB hub: The adapters are connected to ports 1, 2, 3, 4.1, 4.2, 4.3 and 4.4. The seven-port hub is actually two
four-port hubs in a single case, with the second one connected to the first one’s port 4. This reflects itself, of
course, in the udev rules necessary to address the adapters by the hub port they’re plugged in:
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.1”, \
SYMLINK=“USBserial1”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.2”, \
SYMLINK=“USBserial2”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.3”, \
SYMLINK=“USBserial3”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.4.1”, \
SYMLINK=“USBserial4”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.4.2”, \
SYMLINK=“USBserial5”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.4.3”, \
SYMLINK=“USBserial6”
SUBSYSTEM==“tty”, SUBSYSTEMS==“usb”, DRIVERS==“usb”, \
KERNELS==“*-*.4.4”, \
SYMLINK=“USBserial7”
These rules will only work for a similary structured hub that is
directly connected to the notebook. If there
are more hubs in between the “final” hub and the host, the address matched against in the KERNELS matches
are going to have a different structure. In the test setup, the first two parts of the address needed to be wildcarded
since these addresses keep changing when the host is booted or the hub plugged out and in. So I guess that these udev
rules are probably going to fail miserably when more hubs and/or USB-to-serial adaptors are connected.
But if one does not do too many changes, things are just fine, and it is possible to put numbers on the USB hub ports
and be sure that the USB-to-serial adaptor connected to port 4 is going to be /dev/USBserial4 in the host system. I
tried plugging in and out the adaptors in random order, unplugged and plugged the hub itself, booted the host, and the
relationship between the port and the device node was stable.
In the test environment, I only tested one adapter at a time, but all these tests were successful as well. I guess that
many more of these adaptors will eventually need a powered USB hub, but with seven adaptors on a single hub, the power
from the USB host is sufficient to live without extra power on the hub. And, I guess, there is some hard limit for the
number of USB adapters being used, and some soft limit when managing the ports and adapters is going to get harder. But,
I think that a site in need of more than, say, sixteen serial ports on the console server can afford a
“real” console server from one of the major vendors, which can be accessed via ethernet, UMTS, ISDN and
whatever you can think of.
This concludes the hardware part of my serial console server for the poor. Tomorrow, I’ll blog about the software
side needed on the host to allow the serial ports to be accessed from the network while still being reasonably secure.
The next article will involve ssh, /etc/passwd shells, /etc/shells, a small perl script, ser2net and telnet. And, shell
escape is the cue word for grey hairs sprouting on my head.