0

I want to tunnel TLS traffic on Linux using bash. Can I do it without multithreading? Is there a predictable order of message exchanges so that I only need to listen to one of the parties at any one time?

I'm writing a proxy server for Linux and need to tunnel TLS. I'd prefer to do it in bash.

exec 3<>/dev/tcp/example.com/443
while 1
do
    cat <mypipe >&3
    cat <&3 >mypipe
done

Can I do it like this? Roughly? I mean, is this a viable architecture? Never mind that I should exit from the loop in the end. I intend to use a messenger to supply data in the named pipe mypipe, and to collect the response.

The messenger is meant to run the code:

cat <&0 >mypipe
cat <mypipe

where the data to be sent comes from stdin (the body of a http request).

Henrik4
  • 464
  • 3
  • 13

1 Answers1

1

No, it is not a viable architecture.

Even without understanding how you plan to feed data into the pipes, the endpoints communicating over TLS have no obligation to deliver message in order that you require with your blocking cat calls.

Additionally, bash doesn't do multi-threading. It allows you to start up multiple jobs/processes, but it is not multi-threaded itself.

Doug Richardson
  • 10,483
  • 6
  • 51
  • 77
  • I know the first cat blocks, but why is that a problem? – Henrik4 Aug 31 '19 at 17:22
  • Since it is a proxy, I assume you're pipe is meant to pass data back in both directions and it looks like the second `cat` is meant to pass the data in one of those directions. It will never execute so the data will only ever go in one direction. – Doug Richardson Aug 31 '19 at 17:24
  • Data will be supplied to the named pipe mypipe by a messenger. As soon as there is data the first cat executes and finishes. Then the second cat listens for a reply from the target server, reads it and forwards it to mypipe where it is collected by the messenger. That's the idea. – Henrik4 Aug 31 '19 at 17:29
  • It doesn't work like that. You're under the impression that your sends and receives will be framed and result in the pipe being closed in-between each "request/response". There is no "request/response" there is just a stream of data in both directions that doesn't stop until the connection is closed. – Doug Richardson Aug 31 '19 at 17:37
  • No, I don't assume that the pipe will be closed. I know that the receiving cat doesn't wait till the pipe is closed before it returns. I've tried it! I added the intended code of the messenger above. When it has done a cat the data immediately becomes available to the cat at the other end. Or am I somehow mistaken? – Henrik4 Aug 31 '19 at 17:46
  • But what happens if every set of messages doesn't begin on one end and finish on the other? You're assuming everything looks like A to B, then B to A. But what if the first thing TLS does depends on B to A. Then this will block forever. – Doug Richardson Aug 31 '19 at 17:55
  • Bingo! That's what I'm asking about. I don't know. I hope that the order of exchanges is client -> server -> client -> ... – Henrik4 Aug 31 '19 at 18:00
  • It's not. Consider a large file download. There is a bit of data sent up in the request, and then possibly gigabytes of response in the other direction. Whatever is sending data to these pipes is going to send the data as they get it, it isn't going to magically frame it to match your blocking read/write loop. – Doug Richardson Aug 31 '19 at 18:06
  • Are you saying that cat doesn't wait till it has read the whole file? Or that the server outputs it piecemeal? Sounds strange. Why would it do that? – Henrik4 Aug 31 '19 at 18:12
  • Piecemeal. If you want to know why I suggest you study networking and network programming. UNIX Network Programming is a well known and respected book on the subject. – Doug Richardson Aug 31 '19 at 18:16
  • Do you mean IP packets or something? I know about that, but cat operates on a higher level and collects all of them, as far as I know. It's tcp traffic. – Henrik4 Aug 31 '19 at 18:20
  • 1
    @Henrik4 There's back-and-forth happening at multiple protocol levels. See, for example, the "Obligatory SSL/TLS Handshake Graphic" [here](https://www.ssl.com/article/ssl-tls-handshake-overview/) showing messages being passed back and forth during TLS setup. And that's *just TLS* -- http, especially with keepalive (multiple back-and-forth over a single connection), etc. My answer to your question would be: this is *not* a viable architecture. – Gordon Davisson Aug 31 '19 at 18:45
  • @GordonDavisson Updated answer to be more explicit about that. – Doug Richardson Aug 31 '19 at 19:00
  • 1
    Another problem occurs to me: buffering. `cat` (and the various TCP stacks) like to buffer up large chunks of data before passing it on. But if the sender finishes and the buffer isn't full yet... the pipeline can stall (possibly forever) with everyone waiting for someone else. TCP has a way to deal with this: the [PSH flag](https://stackoverflow.com/questions/9153566/difference-between-push-and-urgent-flags-in-tcp) tells the receiving network stack to flush its buffer immediately. But `cat` won't recognize this, let alone pass it along to the next link. – Gordon Davisson Aug 31 '19 at 19:17
  • @GordonDavisson The scripts above are only meant to handle TLS, nothing else. Why do you think they can't handle the back and forth of TLS? cat works on top of tcp so if tcp can handle buffering so can cat. – Henrik4 Aug 31 '19 at 19:33
  • @DougRichardson Are you sure about the "no obligation" matter? The TLS protocol is very strict. At least the handshaking is strictly back and forth, starting with the client sending an hello message. – Henrik4 Aug 31 '19 at 19:37
  • After the handshake, the application using TLS can send whatever it likes in whatever order it likes. – Doug Richardson Aug 31 '19 at 19:49