https://habr.com/post/354708/- Системное администрирование
- Сетевые технологии
- *nix
Привет, хабровчане! Я думаю, многие в последнее время столкнулись с проблемами доступа к нужным ресурсам из-за попыток Роском
позоранадзора заблокировать Телеграм. И я думаю, комментарии тут излишни. Факт — эти ресурсы ни в чем не виноваты, но они заблокированы. Проблемы возникли с Viber, ReCaptcha, GoogleFonts, Youtube и др. (кроме самого телеграма). Это случилось и в моей организации, причем некоторые невинные сервисы нужны нам как воздух. В какое-то время решалось все использованием прокси серверов, но они были нестабильны или вовсе отключались (их также блокировал наш великий и могучий РКН).
После прочтения кучи статей, пришла идея научить Squid пускать отдельные URL через Tor. Какие здесь плюсы и минусы, решать вам. Но скажу, что после реализации пропали все проблемы, которые были до этого. Кому интересно, идем под кат.
Зачем это?Статья написана исключительно в целях помощи тем, кто неправомерно страдает от тотального бреда, который творится у нас в стране. Также она ориентирована на тех, кому нужен именно «прозрачный» Squid с HTTPS без подмены сертификатов и возможностью отслеживания посещений как по HTTP так и по HTTPS, поскольку статья по сути является продолжением
другой моей статьи, так как здесь я предлагаю исправление давнего бага, который не позволял видеть в логах доменные имена https ресурсов и не позволял использовать более новые версии Squid. Ну а также просто для тех, кому интересно использование Squid.
Какие преимущества?
- Неограниченные возможности масштабирования
- Относительная легкость в поддержке и администрировании
- Если это важно, то можно предоставлять анонимный доступ на указанные в списке ресурсы (хоть это и не тема статьи, но анонимность предоставляется «искаропки»
- Стабильность. При использовании нескольких сервисов Tor (разные конфиг файлы) их можно подключить к Squid, и получить round robin.
- Абсолютная бесплатность. Навсегда.
Я ничего не знаю, Squid медленный, пойду и подниму VPS с VPN за бугромПоздравляю! Вы действительно решили, что Роскомнадзор доставил вам неудобства, и вам же еще за это платить, чтобы выйти из положения? Ок. Можете смело пропускать статью, и поднимать VPN туннели. Кстати, VPN успешно блокируется. Легко. И в свете последних событий, я подскажу, что в скором времени никто не сможет использовать VPS для обхода блокировок на уровне закона. И плюс ко всему, ваш VPS может так же угодить в блокировку «просто потому что рядышком сидит телеграм». Tor не заблокируется, никак. Если его настроить с obfs, то никогда и нигде (тема, пожалуй, для отдельной статьи, так как в этой obfs не рассматривается). И сколько нужно будет поднимать таких VPS с VPN? Как это обслуживать? Здесь же решение легче в разы, надежное, и при желании, вполне скоростное, к тому же бесплатное. Так что прежде чем вводить в заблуждение других читателей, пожалуйста, еще раз обдумайте все + и — VPS с VPN, и только после этого утверждайте, что Squid+Tor — это тормознутое, ненадежное решение.
Итак, для начала немного теории. Как мы все знаем, Tor — это не HTTP-прокси, его нельзя сделать прямым peer для нижележащего Squid'а. Он предоставляет SOCKS-проксирование (конечно же, не только, но нам нужно именно это). Чтобы нам поженить Tor со Squid, нужно что-то, что могло бы играть роль проводника от Tor к Squid и обратно. И конечно же, дамы и господа, это Privoxy. Как раз таки он способен быть прямым peer, и отправлять все далее в Tor.
Было, как я уже говорил, прочтено куча статей, но ни одна не подходила мне. Попалась
вот эта статья, но и она мне не совсем подходила, так как мне не нужен bump. Вообще, все имеющиеся статьи, практически все, подразумевают либо бамп, либо только http, а в моем случае нужно и HTTPS, и splice, и прозрачность. Также видал
вот это и
это, но там совсем другие подходы. Свои плюсы и минусы. Я выбрал для себя именно связку Squid + Tor.
Я уже
ранее писал о том, как сделать прозрачный Squid с проксированием HTTPS без подмены сертификатов. И конечно же, я попробовал реализовать идею на нем. Но меня ждало разочарование. HTTP запросы прекрасно уходили в TOR, а вот HTTPS нет. Проблема не очень-то и известная, и я узнал у одного из разработчиков, что это недостаток старых версий Squid. Но в ходе экспериментов было найдено решение — Squid 3.5.27, в котором исправлен данный баг + красивые доменные имена в логах (https), вместо ip адресов. Но и тут меня ждали несколько разочарований, о которых речь пойдет ниже. Но всё, как говорится, допиливается напильником.
Итак, исходные данные:
- Debian Stretch (9) x86 (в х64 не пробовал)
- Сорцы Squid 3.5.23 из репозитория
- Свеженькие сорцы Squid с оф.сайта
- OpenSSL
- Libecap3
- Tor
- Privoxy
- Прямые руки и много кофе с печеньками
Собирать Squid ручками или ставить готовые пакеты (ссылки ниже), решать вам. Если вы думаете, что я впендюрил в них
блекджек и ш… вирусы, то компильте сами. Также компилировать нужно, если у вас дистрибутив другой (если Убунта, то поставите). Собирать мы будем версию Squid 3.5.23, которая на момент написания статьи валяется в репозитории
Stretch, повысив ее до свежих исходников 3.5.27 с оф.сайта. Также нам понадобится для этих дел libecap, его мы тоже соберем. В отличие от моей первой статьи про HTTPS+Squid, собирать будем без Libressl.
Итак, подготовимся к сборке:
apt-get install fakeroot build-essential devscripts
apt-get build-dep squid3
apt-get install libecap3
apt-get install libecap3-dev
apt-get install libssl1.0-dev
apt-get install libgnutls28-dev
ВАЖНО!Очень важно ставить именно libssl1.0-dev, а не другую версию, иначе Squid будет либо лагать, либо не соберется вовсе из-за непонятных ошибок
Далее получаем исходники Squid 3.5.23
apt-get source squid3
Качаем именно этот архив с исходниками Squid:
wget -O squid-3.5.27-2018.tar.gz http://www.squid-cache.org/Versions/v3/3.5/squid-3.5.27-20180318-r1330042.tar.gz
Переходим в каталог исходников Squid и обновляем исходники до новоскаченных сорцов:
cd squid3-3.5.23/
uupdate -v 3.5.27-2018 ../squid-3.5.27-2018.tar.gz
Переходим в новоиспеченный каталог с обновленными исходниками:
cd ../squid3-3.5.27-2018
Добавляем в debian/rules опции для компиляции:
--enable-ssl \
--enable-ssl-crtd \
--with-openssl
СоветМожете, кстати, вырубить ненужные вам опции, это ускорит компиляцию
Дальше нужно пропатчить исходники вот таким патчем:
<b>client_side_request.patch</b>
--- src/client_side_request.cc Thu Aug 18 00:36:42 2016
+++ src/client_side_request.cc Mon Sep 19 04:41:45 2016
@@ -519,20 +519,10 @@
// note the DNS details for the transaction stats.
http->request->recordLookup(dns);
- if (ia != NULL && ia->count > 0) {
- // Is the NAT destination IP in DNS?
- for (int i = 0; i < ia->count; ++i) {
- if (clientConn->local.matchIPAddr(ia->in_addrs[i]) == 0) {
- debugs(85, 3, HERE << "validate IP " << clientConn->local << " possible from Host:");
- http->request->flags.hostVerified = true;
- http->doCallouts();
- return;
- }
- debugs(85, 3, HERE << "validate IP " << clientConn->local << " non-match from Host: IP " << ia->in_addrs[i]);
- }
- }
- debugs(85, 3, HERE << "FAIL: validate IP " << clientConn->local << " possible from Host:");
- hostHeaderVerifyFailed("local IP", "any domain IP");
+ debugs(85, 3, HERE << "validate IP " << clientConn->local << " possible from Host:");
+ http->request->flags.hostVerified = true;
+ http->doCallouts();
+ return;
}
void
Для чего он нужен? Я объясню. Когда я писал первую статью про peek and splice, я говорил что более новые версии не работают, и это было так, и вот как раз таки этот патч исправляет ту самую проблему, которая заключалась в том, что Squid выборочно рвет HTTPS соединения, с интересным сообщением в cache.log:
SECURITY ALERT: Host header forgery detected on ... (local IP does not match any domain IP)
Дело в том, что на одном хосте что-то резолвится в один IP, на соседнем иногда в другой, на самом Squid в третий, т.к. существует кеш DNS и обновляется он не синхронно. Squid не находит соответствия ip-домен в своём кеше (потому что обновил свой кеш немного раньше или позже) и прерывает соединение. Вроде как, защита, но в наше время это считается нормальным (round-robin DNS). Разработчики перестраховались. И нам это не нужно совершенно! Тем, кто скажет, что данный патч, возможно, несет в себе угрозу безопасности, я отвечу, что по поводу этого патча я консультировался с Юрием Воиновым, который имеет непосредственное отношение к команде разработчиков Squid. Никакой угрозы здесь нет!
Итак, файлик для патча создали, код кинули, надо пропатчить:
patch -p0 -i client_side_request.patch
Далее необходимо отменить применение одного патча при компиляции (иначе получите ошибку, что этот патч применить невозможно, так как он уже применен). Идем в
debian/patches/series и закомментим там
0003-SQUID-2018_1.patch, поставив перед ним знак
#:
#0003-SQUID-2018_1.patch
Ну а дальше — компиляция и сборка пакетов!
dpkg-buildpackage -us -uc -nc
Установим squid-langpack
apt-get install squid-langpack
и установим свеженькие пакеты
dpkg -i squid-common_3.5.27-2018-1_all.deb
dpkg -i squid_3.5.27-2018-1_i386.deb
dpkg -i squid3_3.5.27-2018-1_all.deb
Если apt матерится на зависимости, сделайте
apt-get -f install
Далее нужно выключить Squid из автозагрузки (по умолчанию используется init файл, Squid жалуется на недоступность PID файла)
systemctl disable squid
и создать systemd сервис в директории
/etc/systemd/system (файл сервиса есть в исходниках, и полностью скопирован сюда)
cat /etc/systemd/system/squid3.service
## Copyright (C) 1996-2018 The Squid Software Foundation and contributors
##
## Squid software is distributed under GPLv2+ license and includes
## contributions from numerous individuals and organizations.
## Please see the COPYING and CONTRIBUTORS files for details.
##
[Unit]
Description=Squid Web Proxy Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/squid -sYC -N
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
[Install]
WantedBy=multi-user.target
Включим его
systemctl enable squid3.service
Установим
tor, privoxy
apt-get install tor privoxy
Конфиг Tor я лично вообще не трогал, а вот конфиг Privoxy можно привести к такому виду:
listen-address 127.0.0.1:8118
toggle 0
enable-remote-toggle 0
enable-remote-http-toggle 0
enable-edit-actions 0
forward-socks5t / 127.0.0.1:9050 .
max-client-connections 500
Почти готово. Перейдем в каталог
/etc/squid, кое-что там изменим. Создадим pem файлик, необходимый для splice:
openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 -keyout squidCA.pem -out squidCA.pem
И приведем squid.conf к следующему виду:
acl localnet src 192.168.0.0/24 # Ваша локалка
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
acl SSL method CONNECT
#Укажем DNS для Squid. Крайне рекомендую использовать одинаковые DNS тут и у клиентов
dns_nameservers 77.88.8.8
# Список доменов, которые нужно пустить через Tor
acl rkn url_regex "/etc/squid/tor_url"
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
icp_access deny all
htcp_access deny all
#прозрачный порт указывается опцией intercept
http_port 192.168.0.1:3128 intercept options=NO_SSLv3:NO_SSLv2
#также нужно указать непрозрачный порт, ибо если захотите вручную указать адрес
#прокси в браузере, указав прозрачный порт, вы получите ошибку доступа, поэтому нужно
#указывать непрозрачный порт в браузере, если конечно такое желание будет, к тому же в логах #сыпятся ошибки о том, что непрохрачный порт не указан=)
http_port 192.168.0.1:3130 options=NO_SSLv3:NO_SSLv2
#и наконец, указываем HTTPS порт с нужными опциями
https_port 192.168.0.1:3129 intercept ssl-bump options=ALL:NO_SSLv3:NO_SSLv2 connection-auth=off cert=/etc/squid/squidCA.pem
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
#укажем правило со списком блокируемых ресурсов (в файле домены вида .domain.com)
acl blocked ssl::server_name "/etc/squid/blocked_https.txt"
acl step1 at_step SslBump1
ssl_bump peek step1
#терминируем соединение, если клиент заходит на запрещенный ресурс
ssl_bump terminate blocked
ssl_bump splice all
# Никогда не пускать напрямую домены, указанные в списке РКН
never_direct allow rkn
# Указываем прокси, куда отправлять домены из списка, в нашем случае - Privoxy
cache_peer 127.0.0.1 parent 8118 0 no-query no-digest default
cache_peer_access 127.0.0.1 allow rkn
cache_peer_access 127.0.0.1 deny all
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB
coredump_dir /var/spool/squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
logfile_rotate 4
pid_filename /var/run/squid.pid
Список url_regex имеет примерно такой вид (список дан для примера!):
zenway\.ru
\.*google\.com
\.*viber\.*
\.amazon\.com
\.fbcdn\.net
\.slack\.*
media\.api\.viber\.com*
static\.viber\.com*
secure\.viber.*
\*.cloudfront\.net
fonts\.gstatic\.com
med-edu\.ru
ЗамечаниеВы можете использовать и не regex, можно использовать dstdomain, также можно «прикрутить» списки с неправомерно заблокированными подсетями (dst)
Более подробно про этот формат списка читайте в оф документации. Результат себя долго ждать не заставил — все заработало, как и было запланировано. И работает по сей день. Возможно, со статьей опоздал, но она, вероятно, пригодится в будущем).
Тему буду пополнять по возможности.
Готовые пакеты Squid и Libecap (.deb x86)
UPD 04.05.18: можно добавить в torcc строчку
HTTPTunnelPort 8118
и в принципе отказаться от Privoxy. Спасибо
dartraiden за
замечание
Также поправил статью по части libecap3. Не нужно компилировать ничего, а просто установить из репозитория Stretch. Спасибо
AlucoST за
замечание
UPD 05.05.18: товарищ
dartraiden подсказывает, что в конфиг Tor можно добавить
ExcludeExitNodes {ru}, {ua}, {by}
Это исключает использование выходных узлов в указанных странах
Огромное спасибо Юрию Воинову, который помогал в решении проблем с работой данной связки!