Skip to content
forked from koding/tunnel

About

Tunnel proxy package in Go

Resources

Stars

1 star

Watchers

1 watching

Forks

 
 

Repository files navigation

MyLittleProxy GoDoc

MyLittleProxy is a reverse proxy for cases where you cannot or do not want to expose entire development or testing environment to extranet, but also need to test an endpoint or single page.

For example, you need to test an Oauth flow or web callback from third-part service.

It is based on the modified koding/tunnel lib.

How it works

Server side receives incoming HTTP connections and tunnels them to clients based on assigned domain names.

Replies from clients are forwarded to requesting side via the same tunnel.

For example remote server sends HTTP POST to your feature.test.domain.com/callback, this request is routed to 1234.pr.domain.com/feature/cb guarded by firewall via tunnel. Reply from preproduction server is routed to caller.

sequenceDiagram
    3rd party->>MLP Server: POST feature.test.domain.com/callback
    MLP Server -->> MLP Proxy: tunnelled call
    activate MLP Proxy
    MLP Proxy ->> Preprod: POST 1234.pr.domain.com/feature/cb
    Preprod ->> MLP Proxy: HTTP 201
    MLP Proxy -->> MLP Server: tunneled response
    deactivate MLP Proxy
    MLP Server ->> 3rd party: HTTP 201
    box intranet
    participant MLP Proxy
    participant Preprod
    end
Loading

Building server and client

make build

This will generate two binaries and 2 default configs

Running the server

First you need a machine exposed to extranet.

It will receive HTTP commands from clients and incoming requests from web.

As of now server doesn't implement HTTPS connections, so you may want to set it up behind nginx or other proxy.

You may want to add a wildcard DNS record to automatically catch incoming connections.

Configure the server

{
  "debug": true,
  "listen": ":8080",
  "listenControl": "127.0.0.1:8081",
  "signatureKey": "secretkey",
  "allowedHosts": ["^.*\\.your-public-domain\\.com$"],
  "allowedClients": ["1234"],
  "controlPath" : "/customControlPath",
  "controlMethod": "POST"
}
  • debug Enable more human-readable log format
  • listen IP and port for requests from the Web. This one needs to be allowed by the firewall
  • listenControl IP and port for control connections from clients, served separately from web traffic. Recommended: point it at an address the public cannot reach, such as a private interface or a VPN, and clients connect there instead of to listen. Leave it out and both share listen, which exposes the control protocol to anyone who can reach the server
  • signatureKey A secret key you share between server and clients. Client will use it to sign identifier while communicating with server
  • allowedHosts List of regex rules to filter allowed domains names. If requested URL didn't match any it will fail with error 400
  • allowedClient List of client IDs allowed to use this server. If this list is empty then any client with valid signature will be allowed to connect
  • controlPath Use custom path for control protocol if default (/_controlPath) interferes with your needs. Leave empty or remove from config to use default value
  • controlMethod Custom HTTP method of control call. The default is POST.

Every setting can also come from the environment, which takes precedence over the file: MYLITTLEPROXY_DEBUG, MYLITTLEPROXY_LISTEN, MYLITTLEPROXY_LISTEN_CONTROL, MYLITTLEPROXY_SIGNATURE_KEY, MYLITTLEPROXY_ALLOWED_HOSTS, MYLITTLEPROXY_ALLOWED_CLIENTS, MYLITTLEPROXY_CONTROL_PATH, MYLITTLEPROXY_CONTROL_METHOD. The two list values are comma separated, or a JSON array when a pattern itself contains a comma: ["^a{1,3}\\.example\\.com$"].

The config file is optional when listen, signatureKey and allowedHosts all come from the environment.

Run server

server -c path/to/config.json or just server if the config.json is in the same directory

Run the server in Docker

docker build -t mylittleproxy-server .
docker run -p 8080:8080 -p 127.0.0.1:8081:8081 \
  -e MYLITTLEPROXY_LISTEN=:8080 \
  -e MYLITTLEPROXY_LISTEN_CONTROL=:8081 \
  -e 'MYLITTLEPROXY_ALLOWED_HOSTS=^.*\.example\.com$' \
  -e MYLITTLEPROXY_SIGNATURE_KEY=your-secret \
  mylittleproxy-server

Web traffic arrives on 8080 and clients connect on 8081, published to the host only.

To use a config file instead, mount one at /etc/mylittleproxy/config.json and keep MYLITTLEPROXY_SIGNATURE_KEY in the environment so the secret is not stored alongside the settings.

To start from the sample config in docker/config.json:

MYLITTLEPROXY_SIGNATURE_KEY=$(openssl rand -base64 32) docker compose up --build

Set allowedHosts there to the domains your clients will use.

Running the client

Configure client

{
  "debug": true,
  "identifier": "1234",
  "serverAddress": "localhost:8080",
  "signatureKey": "secretkey",
  "controlPath" : "/customControlPath",
  "controlMethod": "POST",
  "proxy": {
    "http": {
      "domain": "1234.domain.com",
      "target": "https://local.host",
      "customHeaders": {
        "X-Api-Key": "abc123"
      },
      "rewrite": [
        {
          "from": "/test",
          "to": "/api/test"
        }
      ]
    }
  }
}
  • debug Enable more human-readable log format
  • identifier Set custom identifier. Leave empty if you want to automatically use the host name. If you use multiple instances of the same container image or VM with the same host name you really should set custom identifier per instance.
  • serverAddress Address of proxy server
  • signatureKey Secret key shared between server and client to sign control calls from client
  • controlPath Use custom path for control protocol if default (/_controlPath) interferes with your needs. This field is optional but must match the same of server config
  • controlMethod Custom HTTP method of control call. The default is POST. This field is optional but must match the same of server config
  • proxy.http.domain Is the desired domain at the server side that will be routed to this client
  • proxy.http.target Is the target host protocol and port. Requests will be routed to this host
  • proxy.http.customHeaders Headers set on every request and websocket upgrade sent to the target, replacing any the caller sent under the same name. Optional. Values stay on the client and are never sent to the proxy server, so they may hold credentials the target needs.
  • proxy.http.rewrite list of Regex expressions to rewrite paths in URLs. This list must contain at least one entry and may be as simple as a pair / -> / but then you risk to expose entire local web server. Only requests with matched path will be routed to client. You may use RegEx capture groups and replacements (e.g. $1).

Run

client -c path/to/config.json or just client if the config.json is in the same directory

License

The BSD 3-Clause License - see LICENSE for more details

About

Tunnel proxy package in Go

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages