A single point of exit to the web, I2P, TOR and blocking bypass
A single point of exit to the web, I2P, TOR and blocking bypass
Preamble ... This article was written back in the summer, but, for reasons beyond the author's control, it was a little delayed ...
One day, on a hot summer evening, after another command of the form:set content.proxy socks://localhost:9050
, the author of this opus realized that it was impossible to live like this any longer and it was time to bring an exit to all sorts of hidden networks, and at the same time bypass the blocking of the name of a well-known organization to some kind of common denominator for any software in general and a browser in particular. How to bring? Of course, so that the proxy server itself “understands” through which upstream proxy to send and receive traffic, depending on the entered address. The second goal, following on from the first, is that upstream proxies can work either as http or as socks and both protocols must be supported by the ingress proxy. Well, the software itself should be more or less relevant, so that in case of errors or “wanting features”, you don’t have to sadly look at a lonely turnip on a github, or even on some sourceforge.
So the goals are set!
The agony of choice
In fact, there was no particular pain. For, by and large, of the available known proxy servers, two met the requirements. This privoxy
and tinyproxy
. But tinyproxy
it turned out to be more lively, more lightweight and simpler, so it was chosen and immediately installed (using the current version of Manjaro Linux as an example).
sudo pacman -Syu tinyproxy
Of course, before that, packages tor
and i2pd
. ( sudo pacman -Syu tor i2pd
).
Basic tinyproxy setup
So, let's set up basic redirects so that it goes directly to the regular web, and to *.i2p
and *.onion
through the corresponding parent (parent) proxy.
/etc/tinyproxy/tinyproxy.conf:
User tinyproxy
Group tinyproxy
PidFile "/var/run/tinyproxy/tinyproxy.pid"
Port 8888
Listen 127.0.0.1
Timeout 600
DefaultErrorFile "/usr/share/tinyproxy/default.html"
StatFile "/usr/share/tinyproxy/stats.html"
Syslog On
# Set the logging level. Allowed settings are:
# Critical, Error, Warning, Notice, Connect, Info
LogLevel Info
MaxClients 100
MinSpareServers 5
MaxSpareServers 20
StartServers 10
MaxRequestsPerChild 0
Allow 127.0.0.1
ViaProxyName "tinyproxy"
## Parent proxy for TOR hosts
upstream socks5 127.0.0.1:9050 ".onion"
## Parent proxy for I2P hosts
upstream socks5 127.0.0.1:4447 ".i2p"
##### End of static configuration #####
To begin with, almost all parameters in the config remain by default.
- We save
- We launch:
sudo systemctl enable --now tinyproxy
- We check:
journalctl -f -u tinyproxy
, in parallel we try to access i2p and onion resources (by setting the browser to use http proxyhttp://localhost:8888
) and see in the log file messages about redirects to parent proxy's:июл 20 01:36:16 dell-lnx tinyproxy[198356]: Request (file descriptor 6): GET http://flibusta.i2p/ HTTP/1.1 июл 20 01:36:17 dell-lnx tinyproxy[198356]: Found upstream proxy socks5 127.0.0.1:4447 for flibusta.i2p июл 20 01:36:17 dell-lnx tinyproxy[198356]: opensock: opening connection to 127.0.0.1:4447 июл 20 01:36:17 dell-lnx tinyproxy[198356]: opensock: getaddrinfo returned for 127.0.0.1:4447 июл 20 01:36:17 dell-lnx tinyproxy[198356]: Established connection to socks5 proxy "127.0.0.1" using file descriptor 7. июл 20 01:36:40 dell-lnx tinyproxy[198356]: Closed connection between local client (fd:6) and remote client (fd:7) ... июл 20 01:39:36 dell-lnx tinyproxy[214495]: Found upstream proxy socks5 127.0.0.1:9050 for ilitafrzzgxymv6umx2ux7kbz3imyeko6cnqkvy4nisjjj4qpqkrptid.onion июл 20 01:39:36 dell-lnx tinyproxy[214495]: opensock: opening connection to 127.0.0.1:9050 июл 20 01:39:36 dell-lnx tinyproxy[214495]: opensock: getaddrinfo returned for 127.0.0.1:9050 июл 20 01:39:36 dell-lnx tinyproxy[214495]: Established connection to socks5 proxy "127.0.0.1" using file descriptor 7.
"zapret.info" list
Well, the proxy bundle basically works, now the fun begins - bypassing Roskomnadzor blocking. Unfortunately tinyproxy
it doesn't support external files with a parent proxy list, but that shouldn't be a problem. After all, we can generate a monolithic “on the fly” config.
Copy the existing tinyproxy config under a new name:
cp /etc/tinyproxy/tinyproxy.conf /etc/tinyproxy/tinyproxy.conf.static
Slightly edit the new one
/etc/tinyproxy/tinyproxy.conf.static
:LogLevel Info
→LogLevel Error
Create a unit that will clone the zapret.info project repository -
sudo systemctl edit --full --force z-i-prepare.service
:# /etc/systemd/system/z-i-prepare.service [Unit] Description=Zapret Info repository cloner ConditionPathExists=|!/usr/local/lib/z-i/ ConditionFileNotEmpty=|!/usr/local/lib/z-i/dump.csv Wants=local-fs.target After=local-fs.target Wants=network.target After=network.target # [Service] Type=oneshot User=tinyproxy Group=tinyproxy ExecStartPre=+/usr/bin/mkdir -p /usr/local/lib/z-i ExecStartPre=+/usr/bin/chown tinyproxy:tinyproxy /usr/local/lib/z-i ExecStartPre=+/usr/bin/chmod 0750 /usr/local/lib/z-i ExecStart=git clone --depth 1 https://github.com/zapret-info/z-i.git /usr/local/lib/z-i
We create a unit that will generate the tinyproxy config, in runtime -
sudo systemctl edit --full --force tinyproxy-cfg-generator.service
:# /etc/systemd/system/tinyproxy-cfg-generator.service [Unit] After=z-i-prepare.service Wants=z-i-prepare.service # [Service] Type=oneshot User=tinyproxy Group=tinyproxy Environment="PATH=/usr/local/bin:/usr/sbin:/usr/bin" ExecStart=tinyproxy-cfg-gen.sh StandardOutput=file:/run/tinyproxy/tinyproxy.conf
... and the actual script
/usr/local/bin/tinyproxy-cfg-gen.sh
for it:#!/usr/bin/env sh # tinyproxy-cfg-gen.sh -- tinyproxy dynamic config generator to stdout. awk -F';' '{print "upstream socks5 127.0.0.1:9050 \"" $2"\""}' /usr/local/lib/z-i/dump.csv|tr -d '*'|sort|uniq|grep -v '\s\"\"'>/tmp/tinyproxy.conf.dynamic cat /etc/tinyproxy/tinyproxy.conf.static /tmp/tinyproxy.conf.dynamic
A timer and a service that will download list updates once a day and restart the main service:
sudo systemctl edit --full --force z-i-update-daily.timer
:# /etc/systemd/system/z-i-update-daily.timer [Unit] Description=Zapret Info daily update After=network.target Wants=network.target # [Timer] OnCalendar=daily AccuracySec=1h Persistent=true # [Install] WantedBy=timers.target
And the service to it
sudo systemctl edit --full --force z-i-update-daily.service
:# /etc/systemd/system/z-i-update-daily.service [Unit] Description=Zapret Info daily update service After=network.target Wants=network.target # [Service] Type=oneshot User=tinyproxy Group=tinyproxy ExecStartPre=/usr/bin/git -C /usr/local/lib/z-i pull ExecStart=+/usr/bin/systemctl try-restart tinyproxy.service
Finally, the icing on the cake, we edit tinyproxy.service for our needs -
sudo systemctl edit tinyproxy.service
:# /etc/systemd/system/tinyproxy.service.d/override.conf [Unit] Wants=network.target Wants=z-i-prepare.service After=z-i-prepare.service Wants=tinyproxy-cfg-generator.service After=tinyproxy-cfg-generator.service # [Service] User=tinyproxy Group=tinyproxy ExecStart= ExecStart=/usr/bin/tinyproxy -c /run/tinyproxy/tinyproxy.conf ExecStopPost=+/usr/bin/rm -rf /run/tinyproxy/tinyproxy.conf
And now, with all this disgrace, we will try to take off ©
sudo systemctl enable --now tinyproxy sudo systemctl enable --now z-i-update-daily.timer
How it works?
A thoughtful reader will certainly ask, Why such dances with a tambourine? Well, in conclusion, it does not hurt to clarify some points. Let's go straight to the points of the previous section.
- Everything is simple here. We save in a separate file that part of the configuration that should not change automatically.
- A very important parameter that reduces the load time of the main service from an hour (SIC!) to about a minute and a half (netbook AMD 2009 processor and HDD at 5400 rpm). Of course, this is not the only way to improve performance.
- "bootstrap" unit that always runs, but only works if there is no directory
/usr/local/lib/z-i/
or empty file/usr/local/lib/z-i/dump.csv
(directivesCondition*
). The key--depth 1
allows you to clone only the last commit, not all 8 GB. - The main config generation and another live hack to improve performance. The field with the domain is cut out from csv
awk
, it is cleared of extra characters. Delete lines with an empty domain, thencat
send the result tostdout
. and already the unit, thanks to the directive,StandardOutput=
writes all the output to the config file in/run
ontmpfs
! According to dependencies, it starts after the “bootstrap” unit from the previous paragraph has completed. - Once a day, starting from zero hours, with jitter per hour, we update the repository and regenerate the config, restarting the service. More precisely, we restart the service with the regeneration of the config.
- (and 7.) Well, everything is clear here, the launch of auxiliary units and the main one.
This link is already working.week2.5 months. Glucobags, so far, it seems, have not been noticed. ready-made configs and scripts live on github , PRs are welcome!
Коментарі
Дописати коментар
Олег Мічман в X: «Donations and support for media resources, bloggers, projects, and individuals. https://t.co/HPKsNRd4Uo https://t.co/R6NXVPK62M» / X
https://twitter.com/olukawy/status/1703876551505309973