Skip to content

Serial Console Server for the Poor II

This is the second installment of my article about the Serial Console Server for the Poor. First installment here.

The last part of the article having covered the hardware and the udev part creating the device nodes, this part addresses the part of the software that connects the user to the device node.

The idea of the software side is to allow users access only to certain serial ports without giving out a shell account on the server itself. Communication between user and the console server should be encrypted (which certainly means ssh), and users should be able to authenticate both with a key and with a password. Serial parameters (baud rate, parity, stop bits etc) should be configured on the console server to keep this possible error source away from the users.

For years, I have been thinking about using UUCP's cu to access the serial port. This time, it's not going to be used because it offers a shell escape which cannot be turned off. That would give a user shell to the users indirectly, which is not what I want.

Minicom seems still to be the most-used application to access a serial port. I have never understood the sense of using a terminal emulator inside a terminal emulator, especially if one has to break the terminal emulator's habit of trying to initialize a non-existent modem.

So I settled on the application that I usually use to access a serial port: ser2net. This is a Linux implementation of Cisco's "reverse telnet" feature which "connects" a TCP port to a serial port with a given set of parameters. For example,

4016:telnet:600:/dev/USBserial6:38400 8DATABITS NONE 1STOPBIT banner
connects TCP port 4016 with /dev/USBserial6 with an 38400 8n1 parameter set. If you telnet to localhost 4016, you'll find yourself talking to the device connected to the appropriate serial port.

This moves the security risk to the telnet client, which - unfortunately - offers a shell escape function from the telnet command line reachable with the escape character. The only way to remove this is to use the -E command line option, which turns off the escape function completely. This unfortunately excludes the user from cleanly quitting the telnet session, so the only way to get out of a telnet -E is to have the remote side close the serial port (which ain't happening on a serial console) or to kill the telnet process, for example by closing the carrying ssh session. That's a turn-off, but one that one can live with.

Now, the only challenge left is to have the appropriate telnet client started automatically for the user. I decided on connecting this to the account being connected to, so that ssh USBserial4@hostname will automatically do the right thing. Since password authentication needs to work (optionally), this precludes the use of the command modifier in an authorized_keys file.

Another possibility to force a command being executed on login is to set it as the users' login shell in /etc/passwd. One drawback: The command must not have any parameters, so one needs to pass needed parameters to the program some other way. Additionally, the program must be listed in /etc/shells or it will be silently ignored.

My /etc/passwd entries look like

with /usr/local/sbin/serialconnect-shell looking like

set -eu

case "$(id --user --name)" in
  USBserial1) PORT="2011";; 
  USBserial2) PORT="2012";;
  USBserial3) PORT="6013";;
  USBserial4) PORT="6014";;
  USBserial5) PORT="2015";;
  USBserial6) PORT="2016";;
  USBserial7) PORT="6017";;
  *) echo "called from unknown account, terminating."; exit 1;;

telnet -E localhost $PORT
Just for reference, here are the appropriate entries in /etc/ser2net.conf:
2011:telnet:600:/dev/USBserial1:9600 8DATABITS NONE 1STOPBIT banner
2012:telnet:600:/dev/USBserial2:9600 8DATABITS NONE 1STOPBIT banner
6013:telnet:600:/dev/USBserial3:115200 8DATABITS NONE 1STOPBIT banner
6014:telnet:600:/dev/USBserial4:115200 8DATABITS NONE 1STOPBIT banner
2015:telnet:600:/dev/USBserial5:9600 8DATABITS NONE 1STOPBIT banner
2016:telnet:600:/dev/USBserial6:9600 8DATABITS NONE 1STOPBIT banner
6017:telnet:600:/dev/USBserial7:115200 8DATABITS NONE 1STOPBIT banner

If one wants to authenticate for a given serial port with an ssh key, all you need to do is put the appropriate key into the authorized_keys file of the appropriate account, and you're all set.

I do sincerely hope that I didn't put any blatant security goofs into this setup, but if I did, you'll tell me in the comments, right?

Just one more challenge for my valued readers: The port numbers in my ser2net.conf have a system. Can you explain it to me?


No Trackbacks


Display comments as Linear | Threaded

Steve on :

Presumably, the ser2net.conf system is that 6xxx relates to 115200 BPS, whilst 2xxx relates to 9600 BPS?

Axel on :

Or, on second thought, make that 19200... 38400 would be 4xxx...

Marc 'Zugschlus' Haber on :

Using screen to access a serial port looks like abuse to me, also it seems clumsy to set the parameters for the serial port.

Kermit raises the same issue that minicom does: Why use a terminal emulator inside a terminal emulator?

tumbleweed on :

While screen is non-optimal, screen has the big advantage of allowing scroll-back. In diagnosing server problems, this is very useful.

Florian Laws on :

Totally not answering your question, but did you evaluate kermit (my favorite term emu, I hate minicom) and screen screen /dev/ttyX?

karthik on :

Hi Marc!

My goal was to connect to a site controller using remote login. So I used a LINUX server and since it does not have many USB ports used 2 HUB's and connected the AP's to the HUB. Since the USB names of the ports change each and everytime I used your UDEV configurations. I had to modify and it worked perfect. The software part I used is minicom, and it works perfectly fine to access and communicate with the AP.

But I am trying to use ser2net to access the AP. I added the following line to /etc/ser2net.conf. But when i tried to communicate with the AP configured to the server I am not able to get a command prompt or I am not able to give commands to the AP. Instead I get these messages going on and on. Following is the set of line i added to ser2net.conf, and the messages I get for the specific command are given below.


4000:telnet:600:/dev/USBserial0:115200 8DATABITS NONE 1STOPBIT banner

OUTPUT: ser2net port 4000 device /dev/USBserial0 [115200 N81] (Debian GNU/Linux) [4eb214c0] HAP: Assigning role of /apModemLink-2 to unassigned [4eb214c0] HAP: Assigned role of /apModemLink-2 to active [462514c0] HAP: Assigning role of /apModemLink-2 to unassigned


4001:telnet:600:/dev/USBserial0:115200 8DATABITS NONE 1STOPBIT

OUTPUT: [4eb214c0] HAP: Assigned role of /apModemLink-2 to active [4eb214c0] HAP: Assigning role of /apModemLink-2 to unassigned [4eb214c0] HAP: Assigned role of /apModemLink-2 to active [4eb214c0] HAP: Assigning role of /apModemLink-2 to unassigned [4eb214c0] HAP: Assigned role of /apModemLink-2 to active [361c34c0] HAP: Assigning role of /apModemLink-2 to unassigned [361c34c0] HAP: Assigned role of /apModemLink-2 to active


4001:raw:600:/dev/USBserial0:115200 8DATABITS NONE 1STOPBIT -XONXOFF LOCAL -RTSCTS

OUTPUT: [361c34c0] HAP: Assigning role of /apModemLink-2 to unassigned [361c34c0] HAP: Assigned role of /apModemLink-2 to active

Please do let me know how can i proceed with this configuration.

Thanks Karthik

Marc 'Zugschlus' Haber on :

I have never seen these HAP messages and do not know what they mean. I do it the exactly same way and everything is fine on my systems.

Add Comment

Markdown format allowed
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
Form options