Building a Self-Hosted Port Forwarding Program with Docker, Brook, and Portainer for Web Management

Publish: 2021-01-09 | Modify: 2021-01-09

Previously, several commonly used port forwarding programs were introduced in the blog, such as rinetd and Nginx Stream. Today, another port forwarding program, brook relay, will be introduced.

Note: The following content requires a certain understanding of using Docker.

What can brook relay do?

Let's take a look at an official introduction:

brook relay can relay any TCP and UDP server. This is an independent feature that does not depend on brook server and brook wsserver.

Request <--> relay server <--> Server being relayed

However, Brook's capabilities go far beyond that. It can do much more, if you know what I mean. If you are interested, you can refer to the official documentation: https://txthinking.github.io/brook/#/zh-cn/. Today, the main focus is on using brook relay for port forwarding.

Why use Docker + Brook

Brook is developed in golang and the author has already packaged the binary files. The installation and usage are very simple, so simple that it only takes a few lines of commands to complete the port forwarding operation. Let's take a look at the official demo command, which only requires a simple line:

# Assuming your relay server IP is 5.6.7.8, then accessing 5.6.7.8:9999 is equivalent to accessing 1.2.3.4:9999
brook relay -f :9999 -t 1.2.3.4:9999

Since the official command is already simple enough, why run it on Docker? Isn't it redundant? Xiaoz summarizes several advantages of running Brook in Docker.

  1. When you need to forward multiple ports, it is not convenient to manage with brook relay alone.
  2. It is difficult to monitor the memory, CPU, and traffic usage of each port forwarding. Docker naturally supports monitoring of each container.
  3. It can be managed through a web interface with Portainer (to be introduced later).

Running brook relay in Docker

Now that we understand the advantages of running Brook in Docker, let's start deploying the container. Xiaoz has already created a Docker image for brook relay, so if you have Docker installed, you can directly use the following command:

docker run -itd \
    --restart=always
    -e DIP="192.168.1.222" \
    -e DPORT="22" \
    -p 2293:9999 \
    helloz/brook-relay

Let's explain the purpose of the above command:

  • --restart=always: Always automatically start the container when it encounters an exception.
  • DIP="192.168.1.222": Target IP.
  • -e DPORT="22": Target port.
  • -p 2293:9999: 2293 is the relay server port, you can define it yourself. 9999 is the internal port of the container, do not modify it, keep it as the default.

Assuming your relay server IP is 192.168.1.111, connecting to 192.168.1.111:2293 is equivalent to forwarding to 192.168.1.222:22. If you have used port forwarding before, I believe you can understand it easily.

If you need to forward multiple ports, continue copying the above command and modify the relay port, target IP, and target port.

Installing Portainer

Portainer is a visualization tool for container management, which allows you to manage Docker directly through a web interface. Installing Portainer is optional. In order to achieve web management of port forwarding, you can install Portainer if needed. Please continue reading below.

Continue on the relay server and copy the following command to install Portainer:

# Create a volume
docker volume create portainer_data
# Run Portainer
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

Then access IP:9000 to open the Portainer interface and follow the prompts to set the administrator account and password.

Select Docker and connect.

After entering the background, find the containers option, and you can see all the containers, including the brook relay port forwarding created just now.

Next, continue to use Portainer to demonstrate how to deploy a brook relay port forwarding container. Find containers on the left side of Portainer and click Add Container.

Fill in according to the figure below.

  • Name: Container name, fill in randomly.
  • Image: Fill in the name of the image packaged by Xiaoz: helloz/brook-relay:latest
  • Host port can be defined by yourself.
  • Container port should remain 9999 unchanged.

Not finished yet, scroll down and fill in the target IP and target port. In the Advanced container settings, click ENV and add 2 lines according to the figure below.

  • DIP: Target IP
  • DPORT: Target port

After setting according to the above, click the Deploy the container button on the interface to deploy it. After successful deployment, you can see the container we just created on the interface.

Click the Stats button, and you can also monitor the container status, such as CPU, memory, and traffic usage.

You can see that brook relay consumes about 5Mb of memory during idle time, and the memory usage is very small.

Summary

By using this approach, you can package any port forwarding program, such as rinetd, nginx, and socat, into a Docker image, and combine it with Portainer to achieve web management and status monitoring. It is difficult to achieve CPU, memory, and traffic monitoring with open source port forwarding panels on the Internet, while Docker natively supports it. Finally, thanks to the following open source projects:


Comments