How time flies! It’s been two weeks since the last article in this series, “A Guide to Commercial-grade 4G Proxy Setup [Preparation],” was published. Due to a variety of chores, I couldn’t write the article since Tuesday, so I started cooing.

So in the preparation, we have learned about the software and hardware needed to build 4G agents, and also know the advantages and disadvantages of various choices. Now, we can start the actual construction, which I’m sure you’ve all been waiting for.


The basic idea

From the title of this article, we can see that Docker is mainly used in the construction scheme this time. You may be curious about whether Docker has anything to do with the construction of 4G agent.

Well, it matters a lot. Let’s sort out the whole thing and first take a look at the basic process of setting up 4G proxy:

  1. The nic dial-up is invoked. After the dial-up succeeds, a virtual NIC is created. (Under normal circumstances, you can use this virtual network card to access the Internet)

  2. In the case of multiple network cards, repeat the first step to get multiple virtual network cards.

  3. Start the proxy server to use the virtual network card as the outbound network card and the physical network card that accesses the Intranet as the inbound network card.

However, there is a problem. According to my previous test results, there is no HTTP proxy server in Linux that can specify the outbound network card and the inbound network card respectively. This is troublesome, because if we can’t do this, we have problems like the following:

  1. The proxy server must be used to access the network through the public network.
  2. The inbound network is a physical NIC, but the outbound network is locked by the proxy server. Therefore, multiple nics cannot be used.

B: well… Instead of using HTTP proxies, what about Socks5 proxies, which are often used to do some dirty work? If you can specify a network card, use a tool like Privoxy to turn the Socks5 proxy into an HTTP proxy. (The Windows version of a well-known wall buttress does this with HTTP proxies.)

After a few attempts, I found that although some Socks5 proxy servers document that you can specify a network card, following the instructions does not seem to directly achieve the effect I want (either still locked on one or not on the network), so there are still some problems. It may be that I need to cooperate with routing table Settings to operate it, but I don’t know much about network engineering, so I didn’t get it out for a few days, so I have to think of other ways.

At this point, I thought of something — Docker, which can be used to solve this problem!

After the Docker container is created, no matter how many external network cards there are, the network card inside the container will only have a Docker’s own virtual network card (communication between containers) and a local loopback interface (ignore it), and when we dial inside the container, The new virtual network card does not affect the outside world or other containers, so the proxy server does not need to specify the network card, just start up and run!

So now the whole process runs through, into the actual operation of the link to see!


systems

This Docker version has a lot of system choices. As the raspberry PI is my sample device, Raspbian (exclusive Debian version of Raspberry PI) is used here. If you’re using another device, just pick a system you use regularly.

So the first step after getting ready is of course to download and install Docker. Here I directly use the one-click installation script provided by Docker official to install:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# from the official documentation: https://docs.docker.com/install/linux/docker-ce/debian/#install-using-the-convenience-script
Copy the code

This one-click setup script should theoretically be available on all Linux distributions, since it’s been around for a long time, but if it’s not available use your own search engines.

Once Docker is installed, you have two options:

  1. Go into play mode and see what the details are like.
  2. Skip this paragraph and go straight to the bottom of this article and use the wheel I wrote.

Start the container

To do this, we’ll just start a Docker container like this and execute the following command:

Sudo docker runit --rm -- Privileged -p 3128:3128 Ubuntu :18.04 bashCopy the code

Start a container with Ubuntu18.04 internal system, go to the Shell inside the container and run bash. If you exit bash, the container will be destroyed automatically. Then map port 3128 inside the container to the external port, which is also mapped to the external port 3128. Finally, the privileged parameter enables the privileged mode, which is used to map the nic device into the container.

If downloading images is slow, search “Docker Accelerator” or hold onto the wall.

Test whether the network adapter works properly

Once inside the container, we can execute ls /dev/ttyUSB* to see if the network card is properly identified (and outside the container as privileged mode is on). If it is the same 4G card that I bought, you will see 4 ttyUSB devices with only one card inserted.

The COMBINATION of 4G nics and hardware may vary depending on the actual situation.

If you can see a 4 * 4G disk with a ttyUSB device, that means there is no problem and you are ready to go.

Dial-up Internet access

The next step is to dial. For dialing, you can choose to use a tool like Wvdial, or you can choose to use a dialing script provided by a vendor like Fanconn (which calls PPPD directly). If the vendor doesn’t provide a dialing script, use Wvdial, which automatically generates the configuration and is ready to use.

For my part, since Fanconn’s technical personnel directly provided a dialing script, I will use this script. There are many detailed documents on Wvdial online, so I will not mention them here, and you can search by yourself if you need them.

If you’re using Fanconn’s dial-up script (how to get into a container? /quectel-pppd.sh /dev/ttyUSB3 / chmod +x quectel-pppd.sh

/dev/ttyusb3 is the fourth communication port of the 4G network adapter. TtyUSB3 →For PPP connections or AT command communication

After dialing, use a tool like ifconfig to see something like the following:

As you can see, as mentioned above, there are now three network cards, one is Docker’s own, one is the local loopback interface (this is not concerned), and one is the virtual network card generated by dial-up.

There is also a wwan0 (or other name) if it is not used inside a Docker container, which is the 4G card ontology.

Test whether you can access the Internet normally

Curl –interface ppp0 https://ip.cn: curl –interface ppp0 https://ip.cn: curl –interface ppp0 https://ip.cn: curl –interface ppp0 https://ip.cn

Because Docker images are often extremely lean, Ubuntu images don’t come with packages like Net-tools, iputils-Ping, Vim, curl, etc., that need to be installed. If you don’t use ifconfig, ping, curl, or vim, don’t panic. This is normal.

Ping a public IP address (for example, ping 1.1.1.1) and a domain name (for example: If the IP address can be pinged but the DNS resolution fails, you can confirm that the DNS Settings are faulty.

If there is a DNS setting problem during 4G dialing, it is usually because the dialing tool does not write the DNS server Settings returned by the carrier into the configuration. We can manually configure it (you can also force to specify a DNS) :

# The following is the public DNS of Aliyun
echo 'the nameserver 223.5.5.5' >> /etc/resolv.conf
echo 'the nameserver 223.6.6.6' >> /etc/resolv.conf
Copy the code

In the Docker container, the /etc/resolv.conf file may also have two contents, which are required by the container itself. It is recommended not to delete/overwrite, otherwise containers cannot communicate with each other using container names.

Starting the proxy Server

Then, after the test, we can really access the Internet through the 4G network card, we can start the proxy server, here I use TinyProxy.

It is found that Squid consumes more resources, which is not conducive to the use of multiple network cards and will affect the maximum number of 4G network cards.

Apt first install tinyproxy a wave and then vim/etc/tinyproxy/tinyproxy conf modifying the configuration.

The following configurations need to be modified:

  • Change the Port configuration item to 3128 because the Port we mapped earlier was 3128.
  • The Listen configuration item was changed to 0.0.0.0 because we need to use the proxy server on other devices.
  • Allow indicates that the configuration item is commented out or changed to 0.0.0.0/0. The default value 127.0.0.1 will cause access failure on other devices.

After the change, save a wave, and then you can directly execute tinyProxy start… ?

Wait, there’s one more operation to do! To redirect the default route to the virtual network card, run the following command:

Route del-net 0.0.0.0 eth0 route add-net 0.0.0.0 ppP0Copy the code

Delete the default route to eth0, and then add the same route to PPP0.

Curl curl curl curl curl curl curl curl curl curl curl curl curl curl curl

If the default route is not changed, the 4G network card will not be used if no network card is specified, because the default route points to Docker’s own virtual network card, which leads to your original Intranet environment. In other words, the IP does not change!

Now you can execute TinyProxy to start the proxy server.

Testing the proxy server

Ok, the proxy server should have started up properly, now we can try to connect to the proxy server in that container on another device and see if it works using the 4G network card.

$curl = 192.168.137.66 $curl = 192.168.137.66

Curl:

curl "https://ip.cn"
curl -x "192.168.137.66:3128" "https://ip.cn"
Copy the code

Python:

import requests
resp = requests.get("https://ip.cn", proxies={"https": "http://192.168.137.66:3128"})
no_proxy_resp = requests.get("https://ip.cn")
print(resp.text)
print(no_proxy_resp.text)
Copy the code

The test results should be the same as the previous test inside the container, with the IP becoming the base station IP assigned by the carrier after using the proxy.

Change the IP

So the core problem comes, how to change the IP?

In fact, as with those dial-up VPS to set up proxy server, we just need to re-dial the number to change the IP, directly kill the PPPD process to disconnect it from dialing, and then execute the dial-up script again to re-dial.

The technical staff of Fanconn also provides a script to disconnect dial-up. After chmod +x quectel-ppp-kill grants the run permission, execute./quectel-ppp-kill.

However, it is important to note that the IP is retained for a period of time after the cellular dial-up is disconnected (it is not clear how long this may depend on the base station to which the connection is made), so we need to force the network card to be searched again.

Uncool fact: Turning airplane mode on and off on your phone is a research, usually just turning off mobile data, which is the same effect as disconnecting from dialing.

So how do we do that? It’s as simple as two lines:

AT+CFUN=0
AT+CFUN=1
Copy the code

Note, however, that this is the AT command, not the Linux Shell command. The AT command is a modem command language, and if we need to execute it, we need to do this:

echo "AT+CFUN=0" > /dev/ttyUSB2
The interval is about 1 second
echo "AT+CFUN=1" > /dev/ttyUSB2
Copy the code

/dev/ttyusb2 is the third communication port of the 4G network adapter. TtyUSB2 →For AT Command Communication, similar to the fourth communication port, except that it cannot be used For PPP connections, only For AT command communication.

The reason for not using the fourth communication port is that the port may be occupied, so it is safest to distinguish it directly. Originally, the network card provides two AT command communication channels.

In a few seconds to tens of seconds after the network card is searched again, you cannot dial normally. You need to wait for its initialization to complete before you can dial successfully. The specific waiting time depends on the signal strength.

So if you keep failing to dial after disconnecting, try again later.


conclusion

Now process also run through the operation, we also learned the whole internal details, the last thing to do is to make each card respectively assigned a container, so that we can realize the article mentioned in the beginning, “the use of virtual LAN as a network card, network entities, and use the network card as the net card” effects.

In practice, you can configure the part of the specified network card, and then pass it in when starting the container. Docker container environment variable Settings can easily achieve this function.

Finally, we can construct a Docker-compose template based on this idea. The core content of the template is to make a simple 4G network card container cluster and start a Squid to aggregate proxy servers. In this way, we only need to specify a proxy server to randomly replace the docker-compose template, which is more convenient to operate.


Well, the above is the idea of the Docker version of the building way and the whole building process, if you are too lazy to look at it, directly with the wheel I wrote is also ok, just need to send a message [Docker version of 4G proxy] to the public number [NightTeam].

evaluation

Finally, let me make a comment on this setup.

This setup isn’t perfect, because there are too many variables, and many places are definitely not as stable as system-level native support, which can cause all sorts of weird problems over the long term.

However, the resource usage of Docker is actually quite high, which will waste a considerable amount of memory in the startup container. If only two or three network cards are ok, but if the number is larger, devices with small memory like Raspberry PI 2B cannot carry it at all.

In addition, the resource consumption of the proxy server itself is also relatively high, and the pressure on the small CPU of Raspberry PI 2B is still quite large under the high-frequency call. Even if I overclocked its CPU, it would easily fill up the CPU in the concurrent test.

But! Up to now, I still have two kinds of building schemes based on router system to write out! So… Please look forward to the follow-up of other construction solutions (leant smile).


Article by “NightTeam NightTeam” – Loco

Founded in 2019, the nightnight team includes Cui Qingcai, Zhou Ziqi, Chen Xiangan, Tang Yifei, Feng Wei, CAI Jin, Dai Huangjin, Zhang Yeqing and Wei Shidong.

My programming languages include but are not limited to Python, Rust, C++, Go, and the fields include crawler, deep learning, service development, object storage, etc. The team is neither good nor evil. We only do what we think is right. Please be careful.