Преамбула… Даная статья была написана ещё летом но, по независящим от автора причинам, немножко подзадержалась...
Однажды, жарким летним вечером, после очередной введённой в консоли браузера команды вида :set content.proxy socks://localhost:9050
, автор сего опуса понял, что дальше так жить нельзя и пора приводить выход во всякие скрытосети, а заодно и обход блокировок имени известной организации к какому-то единому, для любого софта вообще и браузера в частности, «общему знаменателю». А как приводить? Разумеется так, чтобы прокси сервер сам «понимал», через какой вышестоящий прокси отправлять и принимать трафик в зависимости от введённого адреса. Вторая цель, вытекающая из первой, вышестоящие прокси могут работать либо как http, либо как socks и оба протокола должны поддерживаться входным прокси. Ну и сам софт должен быть более менее актуальным, что б в случае ошибок или «хотения фич», не приходилось грустно смотреть на одинокую репу на гитхабе, а то и вообще на каком-нибудь сорсфорже.
Итак цели поставлены!
Муки выбора
На самом деле особых мук не было. Ибо, по большому счёту, из имеющихся известных прокси серверов поставленным требованиям удовлетворяли два. Это privoxy
и tinyproxy
. Но tinyproxy
оказался более живым, более легковесным и более простым, поэтому и был выбран и немедленно установлен (в качестве примера используется текущая версия Manjaro Linux).
sudo pacman -Syu tinyproxy
Само собой, до этого, уже были установлены настроены пакеты tor
и i2pd
. (sudo pacman -Syu tor i2pd
).
Базовая настройка tinyproxy
Итак, настроим базовые перенаправления, чтобы в обычный web ходило напрямую, а в *.i2p
и *.onion
через соответствующие вышестоящие (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 #####
Для начала практически все параметры в конфиге остаются по умолчанию.
- Сохраняем
- Запускаем:
sudo systemctl enable --now tinyproxy
- Проверяем:
journalctl -f -u tinyproxy
, параллельно пытаемся зайти на i2p и onion ресурсы (настроив браузер на использование http proxyhttp://localhost:8888
) и видим в лог файле сообщения о перенаправлениях на 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»
Ну что ж, связка прокси базово работает, теперь начинается самое интересное — обход блокировок роскомнадзора. К сожалению, tinyproxy
не поддерживает внешние файлы со списком parent proxy, но это не должно быть препятствием. Ведь мы можем сгенерировать монолитный конфиг «on the fly».
-
Копируем имеющийся конфиг tinyproxy под новым именем:
cp /etc/tinyproxy/tinyproxy.conf /etc/tinyproxy/tinyproxy.conf.static
-
Слегка правим новый
/etc/tinyproxy/tinyproxy.conf.static
:LogLevel Info
→LogLevel Error
-
Создаём юнит который будет клонировать репозиторий проекта zapret.info —
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
-
Создаём юнит который будет генерировать конфиг tinyproxy, в рантайме —
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
… и собственно скрипт
/usr/local/bin/tinyproxy-cfg-gen.sh
к нему:#!/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
-
Таймер и сервис, который раз в сутки будет выкачивать обновления списка и рестартовать основной сервис:
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
И сервис к нему
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
-
Наконец вишенка на торте, редактируем tinyproxy.service под наши нужды —
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
-
А теперь, со всем этим безобразием мы попытаемся взлететь ©
sudo systemctl enable --now tinyproxy sudo systemctl enable --now z-i-update-daily.timer
How it works?
Вдумчивый читатель безусловно поинтересуется, Для чего такие танцы с бубном? Что ж, в заключении не мешает прояснить некоторые моменты. Пойдём прямо по пунктам предыдущего раздела.
- Тут всё просто. Мы сохраняем в отдельный файл ту часть конфигурации, которая не должна меняться автоматически.
- Очень важный параметр, сокращающий время загрузки основного сервиса с часа(SIC!) до, примерно, полутора минут (нетбучный AMD проц года 2009-го и HDD на 5400 об./мин.). Разумеется это не единственный способ повышения производительности.
- «bootstrap» юнит, который запускается всегда, но отрабатывает только в том случае если отсутствует директория
/usr/local/lib/z-i/
либо пуст файл/usr/local/lib/z-i/dump.csv
(ДирективыCondition*
). Ключик--depth 1
позволяет склонировать только последний коммит, а не все 8 Гб. - Основная генерация конфига и ещё один лайвхак для повышения производительности. Из csv
awk
-ом вырезается поле с доменом, очищается от лишних символов. Удаляются строки с пустым доменом, далееcat
отправляет результат наstdout
. а уже юнит, благодаря директивеStandardOutput=
записывает весь вывод в конфиг файл в/run
наtmpfs
! По зависимостям запускается после того как отработает «bootstrap» юнит из предыдущего пункта. - Раз в сутки, начиная с нуля часов, с джиттером в час, обновляем репозиторий и перегенерим конфиг, с рестартом сервиса. Точнее рестартуем сервис с перегенерацией конфига.
- (и 7.) Ну тут всё понятно, запуск вспомогательных юнитов и основного.
Данная связка работает уже неделю 2,5 месяца. Глюкобагов, пока, вроде бы не замечено. готовые конфиги и скрипты живут на гитхабе, PR приветствуются!
Комментарии (63)
it1804
12.10.2021 09:41+4Я таким способом проверяю обновления z-i без выкачивания всего репозитория:
cd /usr/share/zapret/z-i if [ `git log --pretty=%H ...refs/heads/master^` == `git ls-remote origin -h refs/heads/master |cut -f1` ]; then exit 1; fi echo `date` - "New z-i updates" git pull
domix32
12.10.2021 13:25А опубликуйте репу со скриптами. И звезд отхватите и PR получите для поддержки других разновидностей линуксов.
Oxyd Автор
12.10.2021 14:02+2Так в самом конце статьи, там где...
Данная связка работает уже
неделю2,5 месяца. Глюкобагов, пока, вроде-бы не замечено. готовые конфиги и скрипты живут на гитхабе, PR приветствуются!И ссылка.
krylov_sn
13.10.2021 00:20На винде пользуюсь GoodbyeDPI. Насколько я понимаю пакеты определенным образом режутся, что позволяет обходить блокировки.
Oxyd Автор
13.10.2021 00:41Да. Там пакеты фрагментируются, от чего многм DPI системам слегка сносит крышу. Они не умеют собирать фрагментированные пакеты.
Qwentor
13.10.2021 11:19+1Ага, раньше пользовался - удобно было. Никаких прокси не надо. Сейчас не работает, просто нет коннекта вообще с ним. Провайдер МГТС
mayorovp
13.10.2021 06:39Я правильно понимаю, что эта штука не восстановит доступ к ресурсам, которые не являются заблокированными, но имеют общий IP-адрес с заблокированными?
Oxyd Автор
14.10.2021 00:34Да... Но в приходящем от zapret.info
csv
файле есть колонка и с ip адресом... но не во всех записях. Вобщем я думаю над этим вопросом. Как сделать так что-б и конфиг не раздулся до вообще неприличных размеров.mayorovp
14.10.2021 18:09Ну, можно dns-прокси сделать, который бы проверял все возвращаемые ip-адреса на предмет их заблокированности. Если в ответе есть хоть один незаблокированный адрес — то просто исключаем из ответа всё что заблокировано, если все адреса заблокированы — заменяем их на какой-нибудь 127.0.0.2. Ну а на 127.0.0.2 должен находиться прозрачный прокси.
Oxyd Автор
14.10.2021 18:13Вот интересно, какой из популярных DNS у нас умеет в такие финты? Что-т мне кажется что такого нет... Но это не точно.
yoz
13.10.2021 10:11У меня дома pfsense с туннелем до амстердамской vps. Просто все, что идет из домашней сети и попадает под список, уходит в туннель. Прозрачно для клиентов.
Oxyd Автор
14.10.2021 00:35Так может статью? Больше способов, хороших и разных!
yoz
14.10.2021 09:28Лениво таки. Да и схема не особо красивая и законченная. Сайты в список сам добавляю, которые нужно редиректить в туннель.
Может быть когда нибудь…MrRitm
19.10.2021 14:16-1Плагин для браузеров, чтобы в гитхаб коммитил домен заблокированный. Нажал кнопку, домен отправляется в список и тут же срабатывает вызов скрипта обновляющего список на прокси с гита.
Ещё как вариант PDNSD. Очень лёгкий в настройке кэширующий DNS-сервер. Может он DoH умеет? Тогда ответ от настроенного вышестоящего DNS уже так просто не подменят.
Oxyd Автор
19.10.2021 20:49Ну хотя-б основные принципы. А дальше глядишь и сообщество поможет. Что мы, не автоматизаторы что ли? ;-P
kt97679
14.10.2021 08:54Наивный вопрос: а нельзя настроить прокси так, чтобы любое соединение сперва устанавливалось напрямую, а в случае обнаружения блокировки использовались механизмы обхода? Когда-то подобным образом работало расширение frigate lite для хрома, но насколько я знаю оно больше не доступно.
Oxyd Автор
14.10.2021 09:30+1Хм... Ну это-ж будет медленнее чем посмотрел в список → направил куда надо. И потом, обнаружение блокировки не так просто гарантированно отловить. Особенно когда дело касается соединения по SSL/TLS.
kt97679
14.10.2021 12:16+1Насчет скорости согласен, но можно кешировать состояние, так что если обнаружена блокировка, то следующие сутки (к примеру) обращаемся к ресурсу через обходные пути. Насчет гарантированного определения блокировки — тут да, могут быть проблемы.
Но зато с таким подходом не надо постоянно обновлять конфиг.
bestann
14.10.2021 12:22У меня не так много сайтов блокируется (linkedin), некоторые сайты с торрентами. В таком случае просто включаю кнопкой в Firefox надстройку vpn hoxx, версия бесплатная. Никаких настроек, все максимально просто. А так мне нечего скрывать.
Oxyd Автор
14.10.2021 12:24Ну вот у меня не Firefox. Нет, конечно в qutebrowser можно расширять функционал скриптами на питоне, но из меня питонист ещё тот. Да и универсально. Работает даже с торрент и IRC клиентом.
randomizerko
14.10.2021 18:13Привет,
Не лучшим ли вариантом будет дополнительно сделать .path сервис, который будет рестартовать только в случае если файл хостов поменялся?Oxyd Автор
14.10.2021 18:16Мысль! Спасибо! Только тогда ещё надо будет проверять результат работы
git
, который списки вытягивает. И только в случае если новые данные пришли, перегенерить конфиг.it1804
15.10.2021 23:01А в моём варианте так ведь и есть, если не было изменений в репозитории, скрипт завершится с кодом ошибки 1. Если изменения были, изменения вытянутся через git pull и после этого можно перегенерировать список хостов. Можно сделать вокруг него скрипт-обвязку, проверять код возврата, и принимать решение. А можно сразу после git pull дописать свой код. Мне было удобнее сделать обвязку.
lyadnov
15.10.2021 10:30Лайтовый вариант решения проблемы - расширение FoxyProxy для Firefox. В нем достаточно гибко можно для разных сайтов прописать разные proxy. Работает в windows/linux/android.
Oxyd Автор
15.10.2021 23:58Я им раньше и пользовался, пока с FF / Chrome, не ушёл. Только одна беда. В него тоже надо как-то загружать список РКН и что-то мне подсказывает, что в автоматическом режиме это будет сделать малость проблематичнее.
mapcuk
16.10.2021 14:26Proxy autoconfiguratiion (PAC) позволяет написать JS скрипт и там уже всякую логику городить. И главное его браузеры уже поддерживают.
Я у себя локальльно поднял tor и подготовил proxy.pac если домен в списке блокировки, то используется tor, иначе подключение напрямую.
Proxy.pac может быть на другом хосте.
mayorovp
16.10.2021 15:09+1Тормозит такое решение. Не то из-за количества доменов, не то из-за объёма файла.
tmnidjan
30.10.2021 01:36Есть пара проблем - скрипт исполняемым сделать (раз), в скрипте добавить грепу параметр -s (два), раскомментировать PID-файл в конфиге tinyproxy(три). Ну да, пара это примерно три.
А, и ещё сервис тора стартовать пришлось.
И так работает, да.
SkryabinD
Вы действительно ходите на все эти запрещенные сайты? Если нет, то можно выбрать только нужные, и тогда прокси с 5-10 сайтами будет стартовать намного быстрее, да и настройка в целом будет проще.
Oxyd Автор
Проблема в том, что никогда не знаешь когда наткнёшься на заблокированный ресурс. Вон, недавно deviant-art блочили... Да и минута-полторы, раз в сутки, это ерунда. А на современной системе, это вообще секунды.
Dukat
С некоторых пор РКН начал практиковать блокировку неугодного трафика средствами так называемых ТСПУ, без добавления записей в списки, отправляемые провайдерам.
Таким образом, чтобы чуть менее, чем гарантированно не натыкаться на заблокированный ресурс, надо пользоваться "белыми" списками: на все ресурсы, кроме указанных, ходить в обход.
Oxyd Автор
Ну пока что таких случаев минимум. А там или ишак или падишах... ©
tty_port
шикарная статья, вот бы плюсик поставить!
Mayurifag
Если не секрет, поделитесь, пожалуйста, Вашим белым списком. Хочу перейти на своем прокси на указанную стратегию и знать заранее, где лучше белый список оставить. Кроме, может быть, музыки с синего сайта не приходит идей о содержимом.
И дабы одним комментарием обойтись — большое спасибо автору!
Надеюсь, на основе выложенной инструкции появится гайд/скрипт для роутеров, чтобы i2p/onion/прокси и всё такое было доступно со всех устройств беспроводной сети. Конечно, есть несколько похожих гайдов, но немного всё не то.
Dukat
Не секрет, но не думаю, что от моего списка будет много пользы. Вот он:
mail.ru
yandex.net
yandex.ru
Можно поискать что-то "официальное", но мне пока хватает ручного перечисления ресурсов, обращаться к которым через прокси некомфортно.
PS: тут-ту-ру)
yoz
А госуслуги как же!
Qwentor
Госуслуги, банки, налоговая, какой-нибудь Netflix или ivi, ВКонтакте
Elaugaste
Решение интересное, но если нет задачи залить совсем в даркнет, почему не обойтись vpn через забугорную vps ?
Oxyd Автор
Для случаев когда отсутствует возможность. Ну даже в случае VPS, если хочется гонять только трафик на заблокированные ресурсы — на VPS вместо TOR поднять тот-же tinyproxy и прописать его на этой стороне.
Elaugaste
да, но в случае vps можно сделать без прокси, только силами маршрутизации и туннелирования. Это позволяет поднять туннель на уровне домашнего роутера и все устройства подключающиеся к роутеру будут прозрачно ходить через забугорье. Плюс такого решения в отсутствии необходимости ставить что-то стороннее на клиенты, и нет необходимости настраивать прокси в приложениях. Если сделать vpn на ipsec то можно использовать ту же vps для шифрования трафика при использовании публичного wi-fi с любым утюгом.
Oxyd Автор
Любое туннелирование это, так или иначе, оверхед и потеря производительности. Вот например зачем мне обновления ОС, из реп манджаро, скачивать через VPS / VPN? И так приходится DNS трафик гонять окружными путями, потому что провадер подменяет ответы от «четырёх колов» и прочих паблик DNS, в случае попытки отрезолвить что-то из запрещёнки. Но, как мне кажется, всё-же большая часть трафика вполне может ходить нарямую.
Elaugaste
Справедливое замечание. Однако стоит заметить что используя mangle ветку можно разметить какой трафик отправлять в туннель, а какой нет. По поводу оверхеда спорить смысла конечно нету, он есть но насколько он ощутим большой вопрос. Несколько лет живу с ранее описанной схемой, смотрю какие еще есть варианты обхода блокировок... спасибо за статью.
Если пробовали V2ray через quic было бы весьма интересно почитать про ваш опыт :)
Oxyd Автор
Не пробовал. А можно ссылочку?
apapacy
Я не силен в этих технологиях. Но насколько я понимаю что тор это что-то похожее на торрент (не только тепрвыми тремя буквами) то есть чеез мой комп будет идти трафик который возможно не совсем хороший не только с точки зрения РКН но и с любой точки зрения. Или я ошибаюсь?
Oxyd Автор
TOR может работать просто как клиент (по умолчанию), как релей — передавать чужой зашифрованный трафик и отправлять его дальше. И как Exit Node — собственно нода выхода в интернет. В случае релея о содержимом трафика, начальном и конечном пунктах назначения, вы никогда не узнаете. Потому что только выходная нода видит расшифрованный трафик (но и она не знает кому он предназначен внутри TOR). Повторюсь, TOR, по умолчанию сконфигурирован как просто клиент. Но и релей никаких рисков не несёт. В условиях РФ страшна только выходная нода. Прецеденты были.
bgBrother
Был случай и с релеем — сделали «закупку», увидели адрес релея. Владельцу релея пришлось объяснять, что он содержит узел сети и какой проходит трафик — не знает. После этого никаких обвинений не было.
Oxyd Автор
Ну вобщем в РФ лучше не светить... Хотя не помню, вроде в настройках была возможность запрета быть входным релеем.
SerJ_82
А есть какие-то идеи что делать когда РКН начнет замедлять Ютуб? А он к сожалению имеет необходимые для этого технологии...
Oxyd Автор
VPN. А если будут блочить на DPI, то обфусцированный VPN.