Эту заметку я по большей части для себя пишу, т.к. сейчас всё делается костылями, чтобы собрать все растяжки. Именно описание всех этих растяжек на пути к рабочему решению и есть цель этой заметки.
Всё больше ресурсов блокируют в последнее время. У меня уже довольно давно имеется входная точка Tor внутри моего VPN. Однако, для того, чтобы ходить через Tor в Интернет необходимо настроить клиент соответствующим образом, чтобы он использовался socks-proxy
. Если только, не проксировать трафик прозрачно!
Однако, надо иметь в виду, что я не хочу гнать весь трафик через свой VPN.
Перед тем, как садиться за настройку прозрачного прокси, у меня уже был поднят свой DNS-сервер. В том числе через VPN я хожу на ресурсы по работе, которые доступны только внутри рабочей локальной сети. В связи с этим у меня и поднят DNS-сервер.
Входная точка Tor у меня тоже есть — об этом уже сказал.
Остальное, думаю, не имеет значения.
На текущий момент я уже поднял костыльное решение. Оно работает, хожу в twitter через него. Начну с конца.
Для того, чтобы сходить в Интернет через Tor, нужен клиент socks-proxy
. Но я хочу прозрачный прокси, ещё и с перехватом. Прозрачно перехватывать HTTP трафик умеет privoxy
. Чтобы не возиться с редиректами и маршрутами можно просто подменить DNS запись. Таким образом, клиентское устройство будет само отправлять запрос моему прокси серверу.
Но есть нюанс: privoxy
не умеет HTTPS. Но, есть squid
— в нём, конечно, полно мин, но его можно заставить атаковать мои устройства по принципу MITM.
Приведу диаграмму в качестве примера. На ней gosuslugi.ru
— ресурс, к которому я хочу ходить напрямую, а example.com
— ресурс, к которому я хочу ходить анонимно через Tor. Буковы рядом с доменами — условные IP адреса.
Начинаю новый раунд: ставлю squid
. Дело в том, что sslsplit
, как оказалось, не умеет работать с прокси. Но squid
должен уметь. Правда, не из коробки, но можно собрать с поддержкой MITM-атаки.
Для сборки нужно сначала установить зависимости:
apt build-dep squid
apt install libssl-dev
Внезапно, (я не знал) можно скачать сорцы через apt
:
apt source squid
Далее, в файл debian/rules
в переменную DEB_CONFIGURE_EXTRA_FLAGS
нужно добавить ключи конфигурации для включения SSL:
--enable-ssl \
--enable-ssl-crtd \
--with-openssl
По идее, теперь нужно только собрать да установить пакет в систему:
dpkg-buildpackage -d -uc -us
dpkg -i ../squid*.deb
Наткнулся на следующую ошибку:
In file included from ../../src/anyp/PortCfg.h:18:0,
from PortCfg.cc:10:
../../src/ssl/gadgets.h:83:45: error: ‘CRYPTO_LOCK_X509’ was not declared in this scope
typedef LockingPointer<X509, X509_free_cpp, CRYPTO_LOCK_X509> X509_Pointer;
^~~~~~~~~~~~~~~~
../../src/ssl/gadgets.h:83:61: error: template argument 3 is invalid
typedef LockingPointer<X509, X509_free_cpp, CRYPTO_LOCK_X509> X509_Pointer;
^
../../src/ssl/gadgets.h:89:53: error: ‘CRYPTO_LOCK_EVP_PKEY’ was not declared in this scope
typedef LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> EVP_PKEY_Pointer;
^~~~~~~~~~~~~~~~~~~~
../../src/ssl/gadgets.h:89:73: error: template argument 3 is invalid
typedef LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> EVP_PKEY_Pointer;
^
../../src/ssl/gadgets.h:116:43: error: ‘CRYPTO_LOCK_SSL’ was not declared in this scope
typedef LockingPointer<SSL, SSL_free_cpp, CRYPTO_LOCK_SSL> SSL_Pointer;
^~~~~~~~~~~~~~~
../../src/ssl/gadgets.h:116:58: error: template argument 3 is invalid
typedef LockingPointer<SSL, SSL_free_cpp, CRYPTO_LOCK_SSL> SSL_Pointer;
Если ты из ESR — ставь лайк! Да, надо поставить другую версию SSL библиотеки: libssl1.0-dev
.
Так, у меня ещё одна ошибка:
ErrorDetailManager.cc: In member function ‘virtual bool Ssl::ErrorDetailFile::parse(const char*, int, boo
l)’:
ErrorDetailManager.cc:215:35: error: invalid conversion from ‘const char*’ to ‘size_t {aka long unsigned
int}’ [-fpermissive]
if (!parser.parse(s, e)) {
^
In file included from ../../src/HttpMsg.h:16:0,
from ../../src/HttpRequest.h:16,
from ErrorDetailManager.h:13,
from ErrorDetail.h:13,
from ErrorDetailManager.cc:10:
../../src/HttpHeader.h:223:9: note: initializing argument 2 of ‘int HttpHeader::parse(const char*, size
_t)’
int parse(const char *header_start, size_t len);
^~~~~
Попробую использовать этот патч:
From f42a67c56f8b16ce1b09df6caef1543d30ebc1c7 Mon Sep 17 00:00:00 2001
From: Christos Tsantilas <chtsanti@users.sourceforge.net>
Date: Sun, 9 Nov 2014 14:45:46 +0200
Subject: [PATCH] Parser-NG: fixes to allow ecap and ssl subsystems build
---
src/adaptation/ecap/MessageRep.cc | 3 +--
src/ssl/ErrorDetailManager.cc | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/adaptation/ecap/MessageRep.cc b/src/adaptation/ecap/MessageRep.cc
index 4002856b042..8bbfeb1ae93 100644
--- a/src/adaptation/ecap/MessageRep.cc
+++ b/src/adaptation/ecap/MessageRep.cc
@@ -235,8 +235,7 @@ Adaptation::Ecap::RequestLineRep::method(const Name &aMethod)
theMessage.method = HttpRequestMethod(static_cast<Http::MethodType>(id));
} else {
const std::string &image = aMethod.image();
- theMessage.method = HttpRequestMethod(image.data(),
- image.data() + image.size());
+ theMessage.method.HttpRequestMethodXXX(image.c_str());
}
}
diff --git a/src/ssl/ErrorDetailManager.cc b/src/ssl/ErrorDetailManager.cc
index b798d4b2762..43fc4b00529 100644
--- a/src/ssl/ErrorDetailManager.cc
+++ b/src/ssl/ErrorDetailManager.cc
@@ -212,7 +212,7 @@ Ssl::ErrorDetailFile::parse(const char *buffer, int len, bool eof)
if ( s != e) {
DetailEntryParser parser;
- if (!parser.parse(s, e)) {
+ if (!parser.parse(s, e - s)) {
debugs(83, DBG_IMPORTANT, HERE <<
"WARNING! parse error on:" << s);
return false;
В bash
это будет выглядеть так:
wget https://github.com/squid-cache/squid/commit/f42a67c56f8b16ce1b09df6caef1543d30ebc1c7.patch -O debian/patches/9990-fix-ssl.patch
echo 9990-fix-ssl.patch >> debian/patches/series
Да, надо засовывать его в иерархию dpkg
, иначе dpkg-source
ругаться будет.[^1]
[^1]: Вывод: надо собирать всё из свежих сорцов своими руками — убивать на это больше времени, зато потом сидеть-пердеть и в ус не дуть, и оно рано или поздно точно соберётся (можно же самому всё починить!).
И ещё одна ошибка:
MessageRep.cc: In member function ‘virtual void Adaptation::Ecap::RequestLineRep::method(const Name&)’:
MessageRep.cc:236:27: error: ‘class HttpRequestMethod’ has no member named ‘HttpRequestMethodXXX’; did yo
u mean ‘HttpRequestMethod’?
theMessage.method.HttpRequestMethodXXX(image.c_str());
^~~~~~~~~~~~~~~~~~~~
Откатываю правку в этом файле из патча, который мы скачали. Надеюсь, сработает.
In file included from client_side.cc:132:0:
ssl/certificate_db.h:56:0: error: "Here" redefined [-Werror]
#define Here __FILE__, __LINE__
In file included from ../src/base/TextException.h:15:0,
from ../src/SBufExceptions.h:12,
from ../src/SBuf.h:14,
from ../src/http/MethodType.h:12,
from ../src/HttpRequestMethod.h:12,
from ../src/AccessLogEntry.h:18,
from acl/FilledChecklist.h:12,
from client_side.cc:61:
../src/base/Here.h:15:0: note: this is the location of the previous definition
#define Here() SourceLocation(__FUNCTION__, __FILE__, __LINE__)
Пошёл по пути наименьшего сопротивления, решил её, отредактировав патч debian/patches/CVE-2019-12526.patch
, чтобы макрос назывался в нём по-другому: Here1
.
А ещё я словил virtual memory exhausted: Cannot allocate memory
. Полагаю, дело лишь в количестве оперативы на моём VPS (2 ГиБ). Попробовал дать ключик, чтоб он собирал одним потоком, но не помогло. Придётся локально собирать. Это уже завтра. Могу попробовать запустить образ из reg.ru
в виртуалке, но, КМК, достаточно репу такую же собрать и каталог squid_biuld
стянуть.
Пришлось поставить локально машину на Debian. К сожалению, нашёл только 9.13 (на моём хосте 9.11). Кажется, не должно ничего сломать. Собралось нормально.
Так, по крайней мере теперь он понимает директивы для настройки перехвата HTTPS. Однако, надо теперь с ключами разобраться:
[root@GRayCloud squid_deb]# /usr/sbin/squid -YCN -d 9 -f /etc/squid/squid_privoxy.conf
FATAL: No valid signing SSL certificate configured for HTTPS_port 10.XXX.0.1:443
Squid Cache (Version 3.5.23): Terminated abnormally.
CPU Usage: 0.016 seconds = 0.012 user + 0.004 sys
Maximum Resident Size: 60176 KB
Page faults with physical i/o: 0
Собственно, ключи этими командами генерировал:
openssl genrsa -out /etc/squid/ssl/squid.key
openssl req -new -key /etc/squid/ssl/squid.key -out /etc/squid/ssl/squid.csr
openssl x509 -req -days 3650 -in /etc/squid/ssl/squid.csr -signkey /etc/squid/ssl/squid.key -out /etc/squid/ssl/squid.pem
openssl x509 -in /etc/squid/ssl/squid.pem -outform DER -out squid.der
По идее, squid.der
надо установить на клиентское устройство. Однако, например, на моём телефоне браузер не жалуется. Может быть, это как-то связано с моим VPN, который также по сертификатам работает.
Блять... Оказывается, squid
, когда перехватывает HTTPS, не ходит в DNS разрешать доменное имя! Он берёт IP из оригинального запроса! Что сделал squid
, когда я попытался сходить на myip.ru
? Залупился сам в себя! 10/10.
Попробую закомментировать данный кусок кода. Правда, я сначала закомментировал, а потом посмотрел патч: там, оказывается, ещё правки есть. В любом случае, откатить это на версии 3.5.23 не получится без правки патча.
Изучаю логи с отладкой. Кажется, я обосрался. Он прям печатает запрос:
2022/03/06 16:49:50.347| 11,2| client_side.cc(2352) parseHttpRequest: HTTP Client local=10.XXX.0.1:443 remote=10.YYY.0.30:58290 FD 13 flags=33
2022/03/06 16:49:50.347| 11,2| client_side.cc(2353) parseHttpRequest: HTTP Client REQUEST:
---------
CONNECT 10.XXX.0.1:443 HTTP/1.1
Host: 10.XXX.0.1:443
То есть, запрос изначально отправляется с IP, а не с DNS именем.
Честно говоря, я уже и не понимаю: что происходит. Я перечитал ещё раз эту статью. Есть вероятность, что я обосрался, и мне нужен четвёртый сквирт.
Обратил внимание, что автор использует некий "Peek and splice". Толком не читал: что это, но могу предположить, что имеется в виду. Думаю, речь о том, чтобы установить соединение с клиентом, принять от него условный GET
и только потом пойти к настоящему серверу по адресу, в который разрешится домен из запроса.
В общем, я добавил следующие опции в конфигу:
acl step1 at_step SslBump1
ssl_bump peek step1 all
ssl_bump splice all
ssl_bump server-first all
ssl_bump none all
never_direct allow all
— и всё заработало как надо. Дальше уже была возня с DNS, чтоб в твиттер пускало. И оно пускает!