#tunnel #tcp #client-server #protocols #client-connect #proxy #networking

tcp-warp

A userspace tunnel between two hosts mapping ports on client machine to addresses reachable from server machine

2 unstable releases

0.2.0 Dec 24, 2019
0.1.0 Dec 21, 2019

#24 in #client-connect


Used in tcp-warp-cli

Unlicense OR MIT

50KB
976 lines

A userspace tunnel between two hosts mapping ports on client machine to addresses reachable from server machine

Linux build status Windows build status Crates.io Packaging status

Dual-licensed under MIT or the UNLICENSE.

Features

  1. A userspace tunnel to connect ports on client network with connections available on server side.
  2. Uses only single port.
  3. Client push of addresses to connect from server.

Installation

With cargo:

cargo install tcp-warp-cli

Usage

To create a tunnel we need to start a server listening on some port and then connect to it with a client.

Docker usage for server part

docker run --rm -d -p 18000:18000 tcpwarp/tcpwarp

or with custom listen port (ex: 18234):

docker run --rm -d -p 18234:18234 tcpwarp/tcpwarp tcp-warp server --listen=0.0.0.0:18234

Simple local running port remapper

  1. Start server:

    tcp-warp server
    
  2. Start client:

    tcp-warp client -c 8080:towel.blinkenlights.nl:23
    
  3. Enjoy the show:

    nc 127.0.0.1 8080
    
  4. This example uses default listen and connect interfaces. In a real life scenario you need at least provide -t / --tunnel parameter to client:

    tcp-warp client -t host:port ...
    

Both client and server have address on which they listen for incoming connections and client additionally have parameter to specify connection address.

Next we look at more specific example.

Use case: running Docker on machine without Docker daemon installed with Docker daemon behind SSH

Background:

  • client: client machine runs on Windows, has Windows version of tcp-warp and Docker CLI installed. Client cannot run Docker daemon.
  • public: master node accessible with SSH from which Docker daemon node can be accessed.
  • docker: docker daemon node accessible with SSH.

Target:

Run Docker over tcp transport, allowing client to build and run containers. Environment should be available for each developer independent of other.

Solution:

Run on docker machine Docker-in-Docker container (dind) using tcp host protocol. Use DOCKER_HOST environment variable on client to connect to dind. dind is bindet to host port on docker host and forwarded via public with SSH port-forwarding.

The sequence of commands can be following:

Initial sequence (installation)

  1. Go to docker node and start required containers:

    user@client $ ssh user1@public
    user1@public $ ssh user2@docker
    user2@docker $ docker run --rm --privileged -p 2375:2375 -p 18000:18000 -d --name some-docker docker:dind dockerd --host=tcp://0.0.0.0:2375
    user2@docker $ DOCKER_HOST=tcp://127.0.0.1:2375 docker run --rm -p 18000:18000 -d --name some-docker-tcp-warp tcpwarp/tcpwarp
    
  2. Disconnect from docker and public nodes.

Normal sequence (usage)

  1. Connect to public node with ssh and forward port for tcp-warp:

    ssh -L 18000:docker:18000 user1@public
    
  2. Connect to Docker daemon with tcp-warp client on client machine:

    tcp-warp client -c 10001:172.18.0.1:2375
    

    172.18.0.1 here is the address of host node in dind.

  3. Export DOCKER_HOST environment variable on client machine:

    export DOCKER_HOST=tcp://127.0.0.1:10001
    
  4. Run docker commands from client:

    docker ps
    docker run hello-world
    docker run -it alpine ash
    

Additional services

We can start additional services and relaunch tcp-warp client with additional -c for these services.

Simple example with whoami service:

  1. Create network to use for hostname resolution. Start whoami service with all above steps done. Connect tcp-warp container to new network:

    docker network create our-network
    docker run --rm -d --net our-network --name whoami containous/whoami
    docker network connect our-network some-docker-tcp-warp
    
  2. Stop tcp-warp client. Start it with additional port mapping for whoami service:

    tcp-warp client -c 10001:172.18.0.1:2375 -c 8080:whoami:80
    
  3. Test whoami service:

    $ curl http://localhost:8080/
    Hostname: 9fe704cf0e87
    IP: 127.0.0.1
    IP: 172.18.0.3
    IP: 172.19.0.3
    RemoteAddr: 172.19.0.2:44612
    GET / HTTP/1.1
    Host: localhost:8080
    User-Agent: curl/7.64.1
    Accept: */*
    

Dependencies

~5.5MB
~85K SLoC