Showing results for 
Search instead for 
Did you mean: 

Create a 'commserver' for USB Serial console ports with a Raspberry Pi



As a person working with Cisco's portfolio of IoT products you have probably realized that some new platforms are ditching away the old RJ45-based RS232 serial communication console in favour of the newer USB-based serial communication port. If this a good news for technicians as they are now able to connect a computer straight to the router console using just a mini-USB cable, this is not such a great news for those who need to operate serial connections remotely.


The purpose of a commserver is to map a serial console port to TCP port, so that using Telnet to the commserver one can actually talk directly to the equipment console port. This is very handy to have out-of-band management this way, as it works even when the main network is down, an access-list has been misconfigured, a router is stuck in ROMMON mode and plenty other hair pulling scenario.


With the classic RJ45 serial it was a simple task to use a router with a number of serial lines and connect them to console ports for out of band access. But you can't do that with USB... unless you want to use an active USB-to-RJ45 converter, which is messy and they are not that easy to find. 


Proposed Solution ETY_6448.jpg


I had an old Raspberry Pi 2B+ lying around that I wanted to leverage, but it only has USB ports. You have four USB ports as standard, but I wanted more therefore added an additional board called UUGear BIG7 USB HUB but I'm sure other alternatives will work equally well. The purpose is really to extend the number of USB ports available from 4 up to 11.


Making serial USB ports predictable and persistent


I have used Raspbian as a base operating system, and on my setup and by default the first USB-to-serial connection will be device /dev/ttyACM0. This is not desirable! What we want is to be able to predict which Cisco device console is connected to which USB port, to map a predictable serial device name and ultimately map it to a specific TCP port. For example, if we connect a gateway console to the first USB, we want to map it to /dev/csco1, and to TCP/2001. We will do this my modifying the udev rules, but first we need to uniquely identify the USB ports.


To identify how your ports are mapped: plug in a Serial USB console and watch using "dmesg" on which port this new serial connection has been mapped. For example in my case it shows ttyACM0:


[16201.694459] usb 1-1.3.1: new full-speed USB device number 17 using dwc_otg
[16201.851950] usb 1-1.3.1: New USB device found, idVendor=05a6, idProduct=0009, bcdDevice= 0.00
[16201.851975] usb 1-1.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[16201.851987] usb 1-1.3.1: Product: Cisco USB Console
[16201.851997] usb 1-1.3.1: Manufacturer: Cisco
[16201.883380] cdc_acm 1-1.3.1:1.0: ttyACM0: USB ACM device

Now that I know the device name is ttyACM0, let's check for some unique identifier using:


udevadm info --name=/dev/ttyACM0 --attribute-walk

You should see a long list of attributes but the beginning is what is interesting for us. It could be something like:


looking at device '/devices/platform/soc/20980000.usb/usb1/1-1/1-1.3/1-1.3.1/1-1.3.1:1.0/tty/ttyACM0':
looking at parent device '/devices/platform/soc/20980000.usb/usb1/1-1/1-1.3/1-1.3.1':

Since there can only be one USB driver in 1-1.3.1 this is enough for us to write the rules. Try other ports and see how the numbers are changing, for me this was the first USB port and then it goes 1-1.3.2, 1-1.3.3, ... 1-1.3.7. The udev mapping can be done by editing (or creating) the file in /etc/udev/rules.d/99-usb-serial.rules with the following content:



 Make sure that you restart udev with:


sudo /etc/init.d/udev restart

From this point on, when a serial-to-usb device is connected to USB port 1, it will be mapped to a serial device /dev/csco1, the USB port 2 will be mapped to /dev/csco2, and so on. This will make it very predictable for the next step. 


Using ser2net to map serial ports to Telnet TCP ports


Now in order to map specific USB / Serial ports to TCP / Telnet connections there is a very handy software called ser2net. We are very lucky as this is in the Raspbian repository and it can therefore be installed with:


sudo apt install ser2net


Ater the previous where we made the serial ports predictable this will be very simple. One can configure ser2net by editing the file /etc/ser2net.conf with the following:


2001:telnet:600:/dev/csco1:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2002:telnet:600:/dev/csco2:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2003:telnet:600:/dev/csco3:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2004:telnet:600:/dev/csco4:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2005:telnet:600:/dev/csco5:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2006:telnet:600:/dev/csco6:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser
2007:telnet:600:/dev/csco7:9600 8DATABITS NONE 1STOPBIT -XONXOFF -RTSCTS banner kickolduser


The "kickolduser" is optional but can be very handy: it will disconnect any existing session still active on that serial port and give precedence to the last arrived.


Make sure to restart ser2net for the configuration to take effect (sudo systemctl restart ser2net).




You can then telnet straight to a given console by using the corresponding TCP port number, for example for the console connected to my first USB port:


etychon@ETYCHON-M-D2ZR~ telnet 2001
Connected to
Escape character is '^]'.
ser2net port 2001 device /dev/csco1 [9600 N81] (Debian GNU/Linux)


That's it - now I'm on the IC3000 serial-USB console using Telnet on a Raspberry Pi!


Thank you for reading, and let us know in the comments should you have any other ways you are willing to share?


Cisco Employee
Neat and elegant. Thanks.
Content for Community-Ad