Search code examples
encryptionports

bidirectional encrypted communication using spiped for port forwarding


I would like to establish bidirectional encrypted communication between two machines using spiped (http://www.tarsnap.com/spiped.html) but I suspect that this is really a question about port forwarding... here's what I have working thus far (where my local machine is OS X Mavericks, and the remote is a Ubuntu 12.04 Virtualbox VM):

Remotely (listen on 8025 for external requests and redirect to 8000, where nc displays on stdout):

remote % killall spiped
remote % spiped -d -s '[0.0.0.0]:8025' -t '[127.0.0.1]:8000' -k keyfile
remote % while true; do nc -l 8000; done

Then, locally (listen on 8001 locally and redirect to 8025, where it is sent to the remote machine):

local % killall spiped
local % spiped -e -s '[127.0.0.1]:8001' -t '[192.168.56.10]:8025' -k keyfile

Now when I do the following, "hello" is printed to stdout remotely:

local % echo hello | nc 127.0.0.1 8001

All of this is great. But what about sending data from the remote machine and receiving it locally? I naively assume I can do this remotely:

remote % echo hello | nc 127.0.0.1 8000

And read the data locally with

local % nc -l 8001

But nc does not receive any data locally. I assume I am fundamentally misunderstanding something. In the absence of specific answers, can anyone suggest resources to read up on relevant topics? I'm not looking for a solution using an ssh tunnel - I know how to do that.


Solution

  • In order to provide bi-directional communications with spiped you will need to setup the following on both machines:

    1. A server daemon using the pre-shared key which forwards to the requested local service
    2. A client which sends traffic using the same pre-shared key to the desired spiped port

    One listens & one receives on both systems. For more information take a look a the source code for the client & for the server.

    You can run the spiped service on both systems but each will require manual (or scripted) connections using the spipe client.

    For example using the server (on both machines you would run the following):

    spiped {-e | -d} -s <source socket> -t <target socket> -k <key file>
        [-DfFj] [-n <max # connections>] [-o <connection timeout>] [-p <pidfile>]
        [{-r <rtime> | -R}]
    

    And on the clients wishing to communicate (bi-directionally) with each other you would have to manually invoke the client:

    spipe -t <target socket> -k <key file> [-fj] [-o <connection timeout>]
    

    Or as a real world example using your setup (two services bound to 8025 forwarding to nc on 8000).

    remote % spiped -d -s '[0.0.0.0]:8025' -t '[127.0.0.1]:8000' -k keyfile
    remote % while true; do nc -l 8000; done
    
    local % spiped -d -s '[0.0.0.0]:8025' -t '[127.0.0.1]:8000' -k keyfile
    local % while true; do nc -l 8000; done
    

    Each (remote & local) run the following (nc bound locally to 8001 and sending to the server at 8025):

    remote % spiped -e -s '[127.0.0.1]:8001' -t '[192.168.56.10]:8025' -k keyfile
    
    local % spiped -e -s '[127.0.0.1]:8001' -t '[192.168.56.11]:8025' -k keyfile
    

    Sending data to 8001 on both remote & local forwarding to local & remote

    remote % echo "hello client" | nc 127.0.0.1 8001
    
    local % echo "hello server" | nc 127.0.0.1 8001
    

    Listening to each

    remote % nc -l 8001
    
    local % nc -l 8001
    

    Seeing as how the software was designed to protect the transport layer of the tarsnap backup software which only requires the payloads to be encrypted TO the service.

    Their example within the documentation for protecting the SSH daemon further illustrates this by making use of the 'ProxyCommand' option for SSH. Eg:

    You can also use spiped to protect SSH servers from attackers: Since data is authenticated before being forwarded to the target, this can allow you to SSH to a host while protecting you in the event that someone finds an exploitable bug in the SSH daemon -- this serves the same purpose as port knocking or a firewall which restricts source IP addresses which can connect to SSH. On the SSH server, run

    dd if=/dev/urandom bs=32 count=1 of=/etc/ssh/spiped.key spiped -d -s '[0.0.0.0]:8022' -t '[127.0.0.1]:22' -k /etc/ssh/spiped.key

    then copy the server's /etc/ssh/spiped.key to ~/.ssh/spiped_HOSTNAME_key on your local system and add the lines

    Host HOSTNAME ProxyCommand spipe -t %h:8022 -k ~/.ssh/spiped_%h_key

    to the ~/.ssh/config file. This will cause "ssh HOSTNAME" to automatically connect using the spipe client via the spiped daemon; you can then firewall off all incoming traffic on port tcp/22.

    For a detailed list of the command-line options to spiped and spipe, see the README files in the respective subdirectories.