Menet icon indicating copy to clipboard operation
Menet copied to clipboard

This is NOT an Objective-C project. Menet is a TCP-based reverse proxy to help you expose a local server behind a NAT. It can be dynamically configured through HTTP requests. This is an experimental p...

Melon logo

Menet

Menet is a TCP network middleware that can be dynamically modified through HTTP requests.

This is an experimental project, do NOT use it in production.

Menet is like a combination of Nginx UNIT and FRP. On the one hand, users can use Menet to build their own tunnel or proxy services like FRP, and on the other hand, these services can dynamically configure routing like Nginx UNIT.

Installation

Menet is written by Melang which is a script language. So we just Install melang, please refer to the README of Melang repository.

Usage

Start the service

$ melang menet.m

Configuration

The configuration file is conf.m. The code in this file is a Melang array structure.

conf = [
    'admin': [ //HTTP API listen address
        'ip': '0.0.0.0', 
        'port': '1234'
    ],
    'tunnel': [ //tunnel server listen address
        'ip': '0.0.0.0',
        'port': '4321'
    ],
];

Menet is both a tunnel client and a tunnel server.

APIs

There are four APIs:

  • tunnel
  • service
  • bind
  • config

tunnel

Add or remove a tunnel, and complete the establishment of tunnel TCP and information synchronization.

http://ip:port/tunnel
  • HTTP Method: POST|DELETE

  • HTTP Body:

    {
        "name": "tunnel name",
        "dest": ["ip", "port"]
    }
    

    name will be synchronized to tunnel server automatically.

service

Add or remove a service. There are two kinds of services:

  • local
  • remote

local service represents the service that listens on the port locally, and the remote service represents which service to establish a TCP connection to.

http://ip:port/service
  • HTTP Method: POST|DELETE

  • HTTP Body:

    {
        "name": "service name",
        "key": "rc4 key",
        "timeout": 1000, //Connection timeout, in milliseconds. It's optional. If omitted, it means no timeout.
        "type": "local|remote",
        "addr": ["ip", "port"]"
    }
    

bind

Add or remove a tunnel-service mapping relationship. And of course, because there are two types of services, the mapping relationship is also divided into local and remote.

If you want to build a tunnel proxy service, you need to set the bind of the local service (assumed to be named service1) and the tunnel (assumed to be named tunnel1) on a Menet service, then you need to set up a remote service (also named service1) and tunnel (also named tunnel1) bind on the peer tunnel.

http://ip:port/bind
  • HTTP Method: POST|DELETE

  • HTTP Body:

    {
        "tunnel": "tunnel name",
        "service": "service name",
        "type": "local|remote"
    }
    

config

Display the configuration on Menet service.

http://ip:port/config
  • HTTP Method: GET
  • HTTP Body: None

Example

                  |---------------|                      |------------------|
    service1      |192.168.1.2    |        tunnel1       |192.168.1.3       |   service1
----------------> |8080    Menet  |--------------------->|4321      Menet   |-------------->192.168.1.3:80
                  |admin port:1234|                      |admin port:1234   |
                  |---------------|                      |------------------|

If we expect to get the 80 service content of 192.168.1.3 by accessing the 8080 port of 192.168.1.2, we need to make the following API calls:

$ curl -XPOST -d '{"name":"tunnel1", "dest":["192.168.1.3", "4321"]}' http://192.168.1.2:1234/tunnel
$ curl -XPOST -d '{"name":"service1", "key":"UHI@&s8sa*S", "type": "local", "addr":["0.0.0.0", "8080"]}' http://192.168.1.2:1234/service
$ curl -XPOST -d '{"name":"service1", "key":"UHI@&s8sa*S", "type": "remote", "addr":["192.168.1.3", "80"]}' http://192.168.1.3:1234/service
$ curl -XPOST -d '{"tunnel": "tunnel1", "service":"service1", "type": "local"}' http://192.168.1.2:1234/bind
$ curl -XPOST -d '{"tunnel": "tunnel1", "service":"service1", "type": "remote"}' http://192.168.1.3:1234/bind

We don't have to send tunnel request to 192.168.1.3, because the first command will help us to establish TCP and synchronize tunnel name to it.

You can now check the configuration of both Menet services using the config request.

License

GNU Affero General Public License v3.0

Copyright (c) 2022-present, Niklaus F. Schen