Sign inSign up

wasperen/stream-conductor

By wasperen

•Updated over 9 years ago

A service to reverse-proxy streams from a port at the service host to a backend service.

Image
0

306

wasperen/stream-conductor repository overview

⁠stream-conductor

⁠synopsis

This service presents a flexible stream proxy solution. It enables the user to assign ports at the host where the service lives and have these being transparantly proxied to a backend service.

This repository provides the service code (Python 3) as well as a Dockerfile to create the service as docker container. A docker compose file is provided as a quick test and demo. It spins up the stream-conductor service and a backend ssh service (based on macropin/sshd) as a demo.

⁠use case

You have a service running at a backend server; for example a memcache service at port 2000 on address 10.1.0.1. You cannot expose this port to the outside world, but still want it to be reachable. If you do have an edge node that has an address that is accessible from the outside world, say at 85.12.23.34.

Running this stream-conductor at that edge node gives you the ability to quickly assign a port at this external address and have the stream-conductor reverse proxy all traffic to your backend service.

A simple GET /createstream/9000/mybackend:2000 request will create a stream reverse proxy at 85.12.23.34:9000 to the service at mybackend:2000. From that point onwards, any requests at 85.12.23.34:9000 will be proxied to mybackend:2000 and any application using 85.12.23.34:9000 would not know better.

⁠starting the serivce

The service uses the following environment variables:

variabledefaultdescription
STREAM_CONFIG_PATH/etc/nginx/stream.d/path to store the stream definition files
NGINX_BIN/usr/sbin/nginxpath to the nginx binary
STREAM_PREFIX_conductor_prefix to the per-stream configuration files
PORT_RANGE9000-9009port range1⁠ that is available through this service
BIND_ADDRESS0.0.0.0 (all)addresses that the API will bind to
BIND_PORT5000port that the API will bind to

⁠interface

The service uses a REST API that has the following options:

functionexample resultdescription
status{ 'version':'0.1', 'range':'range(9000-9999)' }returns the current API version and range of available ports
getstreams[ { 'listen': 9000, 'proxy_pass': 'mybackend:22' } ]get a list of current stream definitions
createstream/<port>/<backend>{ 'result':'ok', 'errors':'...'}create a stream connecting a port <port> to a backend service <backend>
removestream/<port>{ 'result':'ok' }remove the stream that listens at port <port>
hasstream/<port>{ 'result':'false' }returns true if there is a stream created that listens at port <port>
getfreeport{ 'result':'ok', 'port':9010 }returns the first available port
⁠examples
⁠getting the status
$ curl localhost:5000/status
{"version": "0.1", "available_ports": "range(9000, 9009)"}
⁠creating a stream
$ curl localhost:5000/createstream/9000/streamconductor_backendssh_1.streamconductor_default:22
{"errors": "[b'2017/06/05 09:27:22 [notice] 10#10: signal process started\\n']", "result": "ok"}
$ ssh localhost -p9000
The authenticity of host '[localhost]:9000 ([::1]:9000)' can't be established.
ECDSA key fingerprint is SHA256:am/KOV40B7/LUbBRb2V2DuwJYL9mPfqq2k2ClERFR6k.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:9000' (ECDSA) to the list of known hosts.
willem@localhost's password:

In this example, a stream is created, proxying port 9000 to the service at streamconductor_backendssh_1.streamconductor_default:22. An ssh to that port is demonstrated to be proxied.

⁠getting a list of streams
$ curl localhost:5000/getstreams
[{"proxy_pass": "localhost:4321", "listen": 1234}, 
{"proxy_pass": "streamconductor_backendssh_1.streamconductor_default:22", "listen": 9000}]

Here a list of all stream mappings is returned.

⁠removing a stream
$ curl localhost:5000/removestream/9000
{"result": "ok", "errors": "[b'2017/06/05 09:34:11 [notice] 12#12: signal process started\\n']"}

This example removes the stream that listens to port 9000 from the proxy.

⁠background

The proxy service is backed by nginx (http://nginx.org/⁠). A simple python program is created to manage the stream definitions and reconfigure nginx. The python program is exposed as REST API using Flask.

NB: There is absolutely no authorization or even authentication done!

⁠Footnotes

  1. The Dockerfile exposes only port 5000 and 9000-9009. If you need other ports, you will need to create your own image. ↩⁠

Tag summary

Content type

Image

Digest

Size

24.1 MB

Last updated

over 9 years ago

docker pull wasperen/stream-conductor