By Nick Piazza –
Often, people will use an unencrypted protocol in favor of an encrypted one. This could be either be due to their lack of knowledge of encrypted protocols, the added difficulty that it takes to set up an encrypted communication, or that the machine that is using the unencrypted protocol cannot be upgraded or updated to use the better protocols. To overcome these reasons, or to develop a network-wide TLS encapsulation, an organization could deploy a TLS encryption gateway to handle the encrypted communications for them. This idea is not new, however. The theory was talked about in the paper “Verification of Secure Systems” by John Rushby in 1981. In his paper, he called this idea a Secure Network Front End. In this post, I will be explaining a proof of concept implementation of a simple TLS gateway to function as a Secure Network Front End.
When John Rushby talked about his idea for a Secure Network Front End (SNFE), he defined two areas; the Red and the Black. The Red communications are unencrypted communications, and the Black communications are encrypted. The idea is that two SNFEs will sit in front of two hosts that are using unencrypted communications, and encrypt the traffic between them.
In my implementation, both the server and the client are on the same machine, so all the traffic will be traveling over the loopback address. My proof of concept works as both a TCP and TLS server. The TCP listener is on localhost:5001 and will make a TLS connection to localhost:5002, which the program is also listening on. When a valid TLS connection is made to localhost:5002, it will make a plaintext connection to localhost:5003. The connection made to localhost:5002 is the only connection that is encrypted, and is meant to represent the untrusted network that the data is traveling across. In a real-world deployment, the server would not be connecting to localhost, but connecting to another machine and port combination.
You can see a demonstration of the code running at https://asciinema.org/a/el89qimchmgh9wiqdz194nniu. In the top pane, we run the TLS wrapper, which listens for TCP connections on port 5001 and TLS connections on 5002. The second pane runs the clear text netcat listener that we are running on port 5003. In the real world, this would be something like an HTTP server or an FTP server using clear text communications. In this example, it’s just a simple netcat listener. In the bottom pane, we see the netcat client. This client connects to port 5001, which causes the wrapper to make a TLS connection to itself, and then make a connection to the server, with the connection to port 5002 being the only encrypted channel. Both servers can communicate with each other in both directions, and if either of the connections is closed, the wrapper will close the other connection.
Now, to prove this, we can look at the Wireshark captures of the exchange. In this first capture, we see the initial communication from the netcat client to the TCP server of the wrapper. We can see that this capture consists of all the packets sent to or from port 5001. If we look at packet 89, we can see that the string “testing” was sent to the TCP server.
In this next capture, we can see the connection to the TLS server on port 5002. After TLS has been set up, we can see in packet 79 that a large amount of data has been sent, but it is unreadable. This trend continues for this entire communication. The reason that you cannot see what is in the data portion is that it is encrypted with the ciphers that TLS has approved.
In the next capture, we can see that the communications are going to and from port 5003, which is our plaintext netcat listener. We can see that in packet 93, we can once again see the plaintext traffic.
All of the code for this project can be found on GitHub at https://github.com/nmpiazza/TLS-Wrapper. This project was written in Go, and requires the Go compiler to be installed on your system if you want to run it. Currently, the routes are configured statically, since this is a proof of concept. A real-world implementation would have the program reading from a configuration file to define the static route that traffic would take. This server can be modified to run practically any number of TCP or TLS wrappers to implement port forwarding.