While "internet" is not the first thing we think of when we hear about embedded, today, in the era of the Internet of Things, such an association is most appropriate. More and more devices are now connecting to the network, sending data to servers and exchanging it with other devices. Therefore, knowledge of how computer networks work is very useful in this industry.
Working with devices that connect to the network, often wirelessly via GSM, involves additional difficulties in testing such devices. In this article, we will focus on a specific problem we may encounter when working with such devices.
Problem
Suppose we are working on the software of device X. While working, our device connects to device Y over TCP/IP, for example, to send measurement data, or to receive remote commands.
The situation is shown in the figure below:
Server Y is publicly available at a.b.c.d:e, however, we would like to be able to test the communication on our computer. Under such conditions, we are able to easily preview the communication and fix any errors. If we have access to the Y server software we could start it locally on our computer, if not - write a simplified version of the Y server to test specific communication scenarios. In both cases, the same problem arises - how to connect our device X to our computer?
Proxy
Our X device can only connect to IP addresses available to the public. Our computer, however, (usually) does not have one - most likely it is behind one (or more) routers that change packet addresses (NAT - Network Address Translation). In such a situation, to be able to connect device X to our computer we have to use some server that has a public IP address. Perhaps we have such a server (we or our employer), if not then we can, for example, relatively cheaply buy a so-called Virtual Private Server (VPS).
In the rest of this article we assume that, we have SSH access to such a server running Linux.
Outline of the solution
Terminology:
- DEVICE - our device that wants to connect to the server application, we can not connect to it (we do not know the IP address);
- PC - our computer, we do not know its IP address, but we want DEVICE to connect to it;
- PROXY - a server with a public IP to which we have access;
To enable the connection, we need to use PROXY as an intermediary between DEVICE and PC, as shown in the following figure:
On the PROXY device, we will listen for connections from the DEVICE side. When DEVICE connects, we will redirect all communication to our PC. To enable such redirection we will have to prepare a so-called "reverse proxy" from our PC. We can do the whole thing with the help of several standard programs available on Linux.
Before we get to the final solution, we need to present the available tools and outline some problems.
Netcat
To see how this tool can be used we can do the following:
Assuming that the file README.md
exists in the current directory of Terminal 2, it will be uploaded to the server and displayed in Terminal 1.
Reverse proxy
Going back to our original problem, we still lack a way to connect from PROXY to our PC - we can only make connections from the PC to PROXY (since only PROXY has a publicly visible IP address). To enable connections from PROXY to the PC, we need to create a so-called "reverse proxy." This involves connecting from the PC to PROXY (that we know how to do), then redirecting connections from PROXY to the PC "inside" the previously created connection (known as tunneling).
Call example:
The syntax can be difficult to decipher at first, so let's examine the call arguments one by one:
This situation is illustrated in the figure below:
In our case, when our local server starts on our PC, we can perform tunneling to the localhost (127.0.0.1), that is, for example, when the local server starts on port 8300:
Local redirection to PROXY
Assuming that our reverse proxy is listening on PROXY for local connections on port 8200, we can create a local forwarding (already on the PROXY device) from port 8100 to port 8200, with port 8100 also listening for remote connections (from outside the PROXY device). To do this, we can use Netcat as follows:
Where:
Socat
Firewall
Before we present the final solution, it is worth mentioning the settings of our PROXY. It is possible that by default our server has a "firewall" configured to prevent connections on most ports. If this is the case, we need to add the appropriate exceptions to the firewall configuration.
Firewall configuration can vary depending on the configuration of our PROXY server, and it is difficult to provide a specific solution here.
Final command
We already have all the necessary pieces of the puzzle:
Now whenever DEVICE connects to PROXY on port 8100, the connection will be redirected to our local PC test server on port 8300, and we can test the communication. The following figure illustrates the final configuration:
We can include all of this in a single command to make it easier to start our DEVICE->PROXY->PC redirection:
Where:
We can test the redirection thus established on the PC, without DEVICE and without starting our local test server, using Netcat:
File data sent this way README.md
will go all the way from Netcat on the PC to PROXY:8100, via local redirection to PROXY:8200, and via SSH reverse proxy on PC:8300 to Netcat listening there with hexdump.
References: