DEV Community

Cover image for Next generation dynamic tunnel proxy service
Megabit
Megabit

Posted on

Next generation dynamic tunnel proxy service

Overview

Speaking of tunnel proxy, familiar friends will definitely think of frp, which is a well-known open source tunnel proxy. And this product has also built its own ecosystem around the tunnel agency service.

This article is to throw out an idea and use an experimental open source project for demonstration.

As early as a few years ago, some people may have noticed that some software has begun to try to support dynamic updates, especially in cloud-native environments. For example: Nginx's dyups module, Nginx's Unit service, Kong's location hot update, etc.

Therefore, for tunnel proxy services such as frp, I also want to try the hot update mode. So there is this experimental project - Menet.

This is an experimental project, the experiment lies in two aspects:

  • Use Melang language development to verify the ability and stability of Melang language
  • Supports dynamic update of configuration to realize the dynamic establishment and disconnection of upstream, downstream and tunnels

This project is not recommended for production environments, this article is only used to demonstrate the dynamic update effect.

Usage

To use Menet, you only need to install the Melang script interpreter, and then execute Menet.

$ melang menet.m
Enter fullscreen mode Exit fullscreen mode

Here, there are two configurations that need to be given before startup:

  • Management port, used to deliver configuration to this proxy service
  • Tunnel port, the tunnel listening port of each service is determined at startup, and the remaining listening ports or remote connections are dynamically created at runtime

In the default example, the content of the configuration file is as follows:

//conf.m

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'
     ],
];
Enter fullscreen mode Exit fullscreen mode

You can edit the conf.m file if these two addresses should be modified.

After the service starts, you will see that two listening addresses are output to the terminal, which means that the service is ready.

Example

Below we give an example, assuming we have the following network structure:

                  |---------------|                      |------------------|
    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   |
                  |---------------|                      |------------------|
Enter fullscreen mode Exit fullscreen mode

Briefly describe:

We have a real 80 service running on 192.168.1.3, and we expect to use the tunnel proxy to access this service from port 8080 of 192.168.1.2.

We can use the curl command to issue 5 HTTP requests to complete this topology deployment, and we will explain them one by one:

1.

   $ curl -XPOST -d '{"name":"tunnel1", "dest":["192.168.1.3", "4321"]}' http://192.168.1.2:1234/tunnel
Enter fullscreen mode Exit fullscreen mode

This request is sent to Menet of 192.168.1.2, the purpose is to let 1.2 establish a TCP connection to port 4321 (tunnel port) of 1.3, so that a tunnel (tunnel1) is established. *Note: This is just an example. In practice, you can also send a request to 1.3 to establish a TCP to the tunnel port of 1.2. *

2.

   $ curl -XPOST -d '{"name":"service1", "key":"UHI@&s8sa*S", "type": "local", "addr":["0.0.0.0", "8080" ]}' http://192.168.1.2:1234/service
Enter fullscreen mode Exit fullscreen mode

This request is used to tell the 1.2 Menet service to establish a local port 8080 for listening (type is local), and name the listening service service1, and the tunnel uses RC4 encryption, so key is the encryption key.

3.

   $ curl -XPOST -d '{"name":"service1", "key":"UHI@&s8sa*S", "type": "remote", "addr":["192.168.1.3", "80" ]}' http://192.168.1.3:1234/service
Enter fullscreen mode Exit fullscreen mode

This request is used to tell the 1.3 Menet service to establish a connection to the 192.168.1.3:80 port and forward it when receiving service1 data from the tunnel.

4.

   $ curl -XPOST -d '{"tunnel": "tunnel1", "service": "service1", "type": "local"}' http://192.168.1.2:1234/bind
Enter fullscreen mode Exit fullscreen mode

This request is to inform the Menet service of 1.2 to establish a mapping relationship between tunnel1 and service1.

5.

   $ curl -XPOST -d '{"tunnel": "tunnel1", "service": "service1", "type": "remote"}' http://192.168.1.3:1234/bind
Enter fullscreen mode Exit fullscreen mode

This request is to inform the 1.3 Menet service to establish a mapping relationship between tunnel1 and service1.

After performing these 5 steps, we can use curl to access 192.168.1.2:8080 to indirectly access the 192.168.1.3:80 service.

Top comments (0)