Category Archives: linux

Raspberry Pi 3 Terminal Server

Every now & then, I find myself working on my network gear at home.  And like many of you, I occasionally upgrade firmware or occasionally yes, even manage to make a mistake and lock myself out now and then..  Like that time I accidentally obliterated my EX2200’s configuration with PyEZ (note – don’t use overwrite config unless you really mean it!).  Hurray for Junos features like “rollback 1”. 🙂

Of course, fixing such things, or doing such upgrades is typically done via the console.  I could string a big long USB extension cable across my office that I’d have to limbo under to leave the room, or figure out something better.  Then, the Raspberry Pi 3 came out, and my lightbulb sparked.  I’d played with an old original Rpi Model B to do this a long time ago, but only wired (which makes it slightly useless when upgrading the switch it’s connected to!). Shouts out to Duane Grant for the tips on how to make it all happen back then.

The Rpi3, with its 4 USB ports, and built-in WLAN chip?  I was sold immediately, and ready to level this thing up so it would be way more useful.  Off to Amazon, where I grabbed the Canakit Rpi3 starter kit and the official Rpi3 case (neither of these are affiliate links). I had a 32GB MicroSD card laying around, so I used that.

What’s it doing now?  Well, it’s Ethernet connected, so I can reach it over the LAN in my house.  It’s also now got a WLAN it’s broadcasting, courtesy of hostapd.  It’s got 2 USB serial dongles, and can accommodate 2 more for console connections.  It’s bridging those serial connections to the network, courtesy of ser2net.  It’s also running Linux ipmasq (think SRC NAT using the outside interface to hide behind), so if you connect to the Pi’s WLAN, you can still talk to the outside world.  Then, I found tty.js, a node app.  This thing gives you a fully functional terminal on the host you’re running it from.  You see where this is heading, right?

We begin with a vanilla Raspbian install. I used the latest image, via NOOBS, based on Debian Jessie (i.e. Debian 8).  I undid all the “helpful” things that the NOOBS-Raspbian image does, like autologin to an X desktop (in the raspi-config utility), and dumped the “pi” user, adding one for me in its place.  Vanilla Linux bits so far though.

I started by setting up the WLAN AP side of things.  This was super simple.  Here’s the really nice guide I followed to get it done.  It’s also worth noting that if you use the ISC dhcp server instead of dnsmasq, you’ll want to configure the static IP for the WLAN in /etc/network/interfaces rather than the /etc/dhcpcd.conf file.  It’s all about what tools you want to employ here..

Got your WLAN on?  Great, next up – serial ports.  There’s a whole pile of USB to RS232 out there.  If you’ve got some laying around, they probably already work.  If you’re buying new ones like I did, go for something based on the Prolific PL2303 chipset.  It’s far and away the most common chipset used for this purpose.  I went with a couple of these, from Amazon (not an affiliate link). When you plug those in, they’ll self-register as /dev/ttyUSB0, /dev/ttyUSB1, and so on.  The remaining piece to bridge the serial ports to the network is ser2net, which is in the Raspbian apt repositories (apt-get install ser2net is all it takes).

Configuring ser2net is simple.  I added 2 lines to the bottom of its config and restarted the process.  Here’s the entire /etc/ser2net.conf:

BANNER:banner:\r\nser2net port \p device \d [\s] (Debian GNU/Linux)\r\n\r\n
7000:telnet:600:/dev/ttyUSB0:9600 8DATABITS NONE 1STOPBIT banner
7001:telnet:600:/dev/ttyUSB1:9600 8DATABITS NONE 1STOPBIT banner

So now, you can telnet to the Pi on port 7000 and get to /dev/ttyUSB0 or go to port 7001 to hit /dev/ttyUSB1.  If you’d like to further restrict this, you could change to localhost,7000 in the above to restrict connections to come from the Pi itself (i.e. so you’d have to ssh to the pi, then telnet localhost 7000).

Ok, it’s a terminal server now.  Let’s turn that up a notch and make it web accessible.  I installed the nodejs package from heroku (I was having trouble with the raspbian repo version), then did an “npm install –global tty.js”.  Configuring tty.js was a bit of a new experience for me, as I don’t really play with JSON files much.  Err.. ever.  I generated a key & cert, and here’s the config, which I stashed in /etc/default/webconsole/config.json, along with the cert and private key I’d generated:

 "https": {
 "key": "/etc/default/webconsole/key.pem",
 "cert": "/etc/default/webconsole/cert.pem"
 "port": 8000,
 "term": {
 "termName": "xterm",
 "geometry": [80, 40],
 "scrollback": 1000,
 "visualBell": false,
 "popOnBell": false,
 "cursorBlink": false,
 "screenKeys": false,
 "colors": [

I launch the app from /etc/rc.local as:

su -l jcostom -c '/usr/local/bin/tty.js -d --config /etc/default/webconsole/config.json'

Yes, I did some (very slight) customizations to the index.html and style.css in the static/ directory under the tty.js install.  Perfectly usable in its default state, but I just wanted some slight changes.

And now, what you’ve all been waiting for – what’s this thing look like?