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

Hornbeam
7 min

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 privoxyand tinyproxyBut tinyproxyit 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 torand i2pdsudo 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 *.i2pand *.onionthrough 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 proxy http://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 tinyproxyit 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.


  1. Copy the existing tinyproxy config under a new name:


    cp /etc/tinyproxy/tinyproxy.conf /etc/tinyproxy/tinyproxy.conf.static

  2. Slightly edit the new one /etc/tinyproxy/tinyproxy.conf.staticLogLevel InfoLogLevel Error


  3. 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

  4. 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.shfor 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

  5. 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

  6. 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

  7. 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.


  1. Everything is simple here. We save in a separate file that part of the configuration that should not change automatically.
  2. 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.
  3. "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(directives Condition*). The key --depth 1allows you to clone only the last commit, not all 8 GB.
  4. 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, then catsend the result to stdoutand already the unit, thanks to the directive, StandardOutput=writes all the output to the config file in /runon tmpfsAccording to dependencies, it starts after the “bootstrap” unit from the previous paragraph has completed.
  5. 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.
  6. (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!

Просмотры:

Коментарі

Популярні публікації