From 3proxy to Nginx forward proxy through pain and suffering (Part One 3proxy)

Do not judge strictly, this is my first article, probably if I were the guru of Nginx and Linux, then most likely there would be no pain and suffering.

How did it all start?

One day I needed to implement a rather non-trivial task:

There are many services from which you need to collect data for processing and further analytics, the module that collects all this can be installed on many servers (so far 40, but in the horizon of the year it is 1000), but I want all requests from these servers to go to one ip , and from it were already distributed depending on the type of request or the end point of the call. Conventionally, we access the server 100.1.2.101 on port 8080 and ask it for data on all houses in a certain territory, it, in turn, connects to a certain proxy according to a given scenario (Let’s say squid, it is needed because some apis are locked by ip) and through it gets data from final api.

PS The data cannot be stored on an intermediate server, as it is updated too often 🙁

As a result, I decided to divide this task into several stages

  1. Create proxy server

  2. Create a load balancing capability (it seemed to me that if you manage to make a proxy that will accept a request and forward it, let’s say, to 300 other proxies, then half the work will be ready)

  3. Create logic for selecting a specific Proxy. (I thought it was simple, I was very wrong, but more on that later)

Stage 1: Create a proxy server (3proxy)

First you need to measure that I can’t use it as a Windows OS, and in Linux I’m like a monkey with a grenade. After a day of analysis, my choice fell on 3proxy as a test subject and beget as a VPS for a testing site (Vps there costs from 7r per day, which is very humane for tests) and a pack of 300 proxies on a third-party resource, they are all locked to one ip (on the Internet you can pick up a lot of them for your pocket, it cost me 30 $, I won’t tell you the address because I’m afraid it will fall from the habraeffect), the OS chose ubuntu 20.04 (it’s just that there are a lot of materials and articles for it) and MobaXterm for the convenience of connecting via SSH (you can download it from the official site or by the well-known method 🏴‍☠️ on the Internet).

3proxy is small and can do a lot, and most importantly, it has a parent that will allow me to contact others in the future. So installing 3proxy:

Let’s update the packages

sudo apt update
sudo apt upgrade

Install 3proxy

wget https://github.com/z3APA3A/3proxy/releases/download/0.9.4/3proxy-0.9.4.x86_64.deb; dpkg -i 3proxy-0.9.4.x86_64.deb

And everything, it was substituted.

now let’s go edit the configs: /usr/local/3proxy/conf/3proxy.cfg (I did it in MobaXterm, it’s more convenient for me)

nscache 65536
nserver 8.8.8.8
nserver 8.8.4.4

config /conf/3proxy.cfg
monitor /conf/3proxy.cfg

log /logs/3proxy-%y%m%d.log D
logformat "%d-%m-%Y %H:%M:%S %U %C:%c %R:%r %O %I %T"
rotate 60
counter /count/3proxy.3cf

users $/conf/passwd

include /conf/counters
include /conf/bandlimiters


nscache 65536
timeouts 1 5 30 60 180 1800 15 60

auth strong
allow *
proxy -n -p4888 -a

flush
allow *
proxy -n -p4890 -a

flush
allow proxyuser
admin -p8080

There are 3 open ports on 4888 and 4890 proxy, and on 8080 admin panel with access only for the proxyuser user

But now we need to create a proxyuser, for this we need to call /usr/local/3proxy/conf/add3proxyuser.sh , but if we try to do it right away, we get Permission denied, first we fix the rights

cd /usr/local/3proxy/conf/
chmod ug+rwx add3proxyuser.sh
/usr/local/3proxy/conf/add3proxyuser.sh proxyuser proxypass

We have created a proxyuser user with the password proxypass. Now start 3proxy

systemctl enable 3proxy && service 3proxy start && netstat -tlpn | grep prox

If one of the ports is not listening, then we write

ufw allow 4888
ufw allow 4890
ufw allow 8080

Now let’s check the Admin panel by going to ip_Server: 8080 and entering the login proxyuser and password proxypass (well, or what we indicated)

admin panel

admin panel

The admin panel works, it’s already good (I didn’t use it, but it seems that you can edit the configs from it). But we are not interested in this 🙂 Let’s try to make a curl request

curl -L -I -x http://proxyuser:proxypass@IP_Сервера:4888 https://habr.com

It works, So we got the result that we wanted and can we fold ?! But it doesn’t :<

We just installed 3proxy and configured it to work, now we need to teach it to work with other servers (in tests, these will be proxy, it is easiest to check it). We make a request and see what the server will return to us by determining the IP

curl -L -x http://proxyuser:proxypass@IP_Сервера:4888 https://myip.ru/index_small.php

And he returned IP_Server to us (Marked in green on the screen)

Stage 2 : Create a load balancing capability (3proxy)

3proxy has the ability to create redirects, it is described in documentation , but there are a number of nuances (well, or I’m just stupid and did not immediately understand them). For the test, we need some kind of proxy server (yeah, for the proxy test We need a proxy, you can set it up on another machine or just buy it on the Internet: I chose the second option).

So, we have IP_proxy_Server_2 (Red on the screenshots) that works on port 8085 (or another) and does not have authorization (login password) or has (it does not matter). First we need to change the config file /usr/local/3proxy/conf/3proxy.cfg and add

parent

  • weight – weight or probability of choosing this Ip, proxy weight,

  • type – proxy type (tcp – connection redirection, can only be the last one in the chain, http – tcp synonym, connect – HTTP CONNECT/HTTPS proxy, socks4 – SOCKSv4 proxy, socks5 – SOCKSv5 proxy),

  • ip – proxy IP address,

  • port – proxy port,

  • username – name for proxy authorization,

  • password – password for authorization on the proxy.

    Login and password can be omitted if the server does not require them. Add the line parent 1000 connect IP_proxy_Server_2 8085 for port 4890 (attention ip and port are separated by a space and not “:” as usual)

nscache 65536
nserver 8.8.8.8
nserver 8.8.4.4

config /conf/3proxy.cfg
monitor /conf/3proxy.cfg

log /logs/3proxy-%y%m%d.log D
logformat "%d-%m-%Y %H:%M:%S %U %C:%c %R:%r %O %I %T"
rotate 60
counter /count/3proxy.3cf

users $/conf/passwd

include /conf/counters
include /conf/bandlimiters


nscache 65536
timeouts 1 5 30 60 180 1800 15 60

auth strong
allow *
proxy -n -p4888 -a

allow *
parent 1000 connect IP_proxy_Сервера_2 8085
proxy -n -p4890 -a

flush
allow proxyuser
admin -p8080

Restart 3proxy

systemctl restart 3proxy

When restarting, the server thinks a little for 5 seconds (if this did not happen, then most likely there is an error in the config)

Now check with curl

curl -L -x http://proxyuser:proxypass@ip_Сервера:4888 https://myip.ru/index_small.php
curl -L -x http://proxyuser:proxypass@ip_Сервера:4890 https://myip.ru/index_small.php

Congratulations, when requesting the server on port 4888, it returns ip_Server (Green on the screen), and when querying on port 4890, it returns IP_proxy_Server_2 (Red on the screen).

Now we can manage the load by adding new proxy servers (IP_proxy_Server_3, IP_proxy_Server_4, IP_proxy_Server_5 …. IP_proxy_Server_251) via the parent construct

config example:

nscache 65536
nserver 8.8.8.8
nserver 8.8.4.4

config /conf/3proxy.cfg
monitor /conf/3proxy.cfg

log /logs/3proxy-%y%m%d.log D
logformat "%d-%m-%Y %H:%M:%S %U %C:%c %R:%r %O %I %T"
rotate 60
counter /count/3proxy.3cf

users $/conf/passwd

include /conf/counters
include /conf/bandlimiters


nscache 65536
timeouts 1 5 30 60 180 1800 15 60

auth strong
allow *
proxy -n -p4888 -a

flush
allow *
parent 4 connect IP_proxy_Сервера_2 8085
parent 4 connect IP_proxy_Сервера_3 8085
parent 4 connect IP_proxy_Сервера_4 8085
parent 4 connect IP_proxy_Сервера_5 8085
parent 4 connect IP_proxy_Сервера_6 8085
parent 4 connect IP_proxy_Сервера_7 8085
...
parent 4 connect IP_proxy_Сервера_251 8085

proxy -n -p4890 -a

flush
allow proxyuser
admin -p8080

Don’t forget to restart the server after every config change

systemctl restart 3proxy

Developer claims:

The weight (from 1 to 1000) is set for each proxy. The sum of weights for all redirects must be a multiple of 1000. Proxies with weights up to 1000 are grouped, and when building a chain, one of them is randomly selected according to the weight. The length of the chain is determined from the total weight. For example, if the total weight of the chain is 3000, there will be 3 links (hop) in the chain.

But there is a nuance, I tried to set the weight to 1000 for everyone, it doesn’t work like that! I did not just specify “parent 4 connect IP_proxy_Server_7 8085” where 4 is (weight), the sum of all (weights) should be 1000. Let’s say you have 300 servers and you want to use them with equal probability, forget this won’t work because if you divide 1000 by 300 you get a non-integer number, so you can use 250 (weight 4) or 500 (weight 2) or 1000 (weight 1).

PS It may be corrected or already corrected, but at the time of this writing, it worked like this)

Thank you all, I’ll be grateful for the criticism 🙂

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *