It's worth taking a moment to note that nearly everything I've discussed so far in this guide is probably really insecure.

Of course, this might not actually matter a whole lot.

For my purposes, it's not too important whether anyone else on my network can see the things I'm sending to my Raspberry Pi's display. On the other hand, there are a lot of situations in which it just might matter.

Consider the following:

  • The code in this guide is almost certainly vulnerable to attacks based on sending it weird input, and opening it up to arbitrary input from the network makes this much more likely to happen.
  • The raw network sockets we use in the netcat and node examples here are not only unencrypted, they're unauthenticated - you don't know who's sending you traffic, and they aren't limited to clients with a specific set of credentials.
  • The same is true of unencrypted HTTP requests.
  • Text sent in the clear can probably be intercepted by other users of the network, or by whoever controls the hardware that runs the network. On your home router, this might not matter very much. Everywhere else, you should be careful.

So what can you do about this? Well, if you're considering using any of the techniques here for a production project that handles sensitive data, think about the following:

  • Use HTTPS for web interfaces
  • Use a robust data-logging protocol with built-in authentication and encryption mechanisms
  • Tunnel traffic over SSH

Piping through SSH

The first two of these recommendations are out of scope for this guide, but the third is pretty straightforward for simple cases. Consider a version of which restricts netcat to listening on localhost:

      #!/usr/bin/env bash
echo "Listening on port 5280"
netcat -l 5280 -k | ./

If you drop this in a file called, you can run it on the Pi with:

chmod +x

Now from a terminal on another machine, we'll use a couple of really handy SSH features you may not have seen before:

echo 'a secret message' | ssh [email protected] 'netcat localhost 5280'

First, if you give ssh a command after the hostname, like 'netcat localhost 5280', it'll execute that command on the remote server.

Second, if you pipe the output of another command into ssh, it'll pass that output to the stdin of whatever command it runs. (Careful here - if you don't give it a command, it'll execute the input in Bash.)

Create an SSH Tunnel

As an alternative, you can use SSH to create an encrypted tunnel for traffic from utilities like netcat.

First, connect from your client machine via SSH, using the -L option to specify a port on the local host to be forwarded to a port on the remote host. (This can be a bit confusing: In 5280:localhost:5280 here, the localhost:5280 part is localhost from the context of the Raspberry Pi.)

ssh -L 5280:localhost:5280 [email protected]

Next, on the Pi, start netcat to listen for local connections:

netcat -l 5280 -k

Finally, back on your client machine, point netcat at port 5280 and try typing something:

netcat localhost 5280

If all has gone well, the traffic should be forwarded by SSH from port 5280 on the client machine to port 5280 on the Raspberry Pi. Here's an example in two terminals:

This technique is widely useful for all sorts of network services, especially if you're dealing with more restricted networks that you don't, yourself, control.

This guide was first published on Mar 26, 2015. It was last updated on Mar 26, 2015.

This page (On Security) was last updated on Oct 22, 2020.

Text editor powered by tinymce.