Данный прокси-сервер предназначен для управления данными, запрашиваемыми браузером от http-серверов. =============================================================================== Основные функции (всё настраивается): 1) фильрация нежелательного контента (реклама/трекеры/прочий мусор); 2) принудительное и бессрочное кеширование полученных данных (в основном удобно для картинок и скриптов); 3) можно пропатчить принятую веб-страницу на лету (нужно дописывать код в исходник, на данный момент уже сделано для нейтрализации клонов stackoverflow); 4) чёрные/белые списки серификатов и certificate pinning по списку; 5) http/https-сниффер. Прекрасно подходит для просмотра сайтов через медленный интернет или с медленного устройства (благодаря п.1 и 2, ради которых изначально всё и затевалось), но вообще полезно в любом случае. Прокси-сервер написал для Linux-а, может быть скомпилирован в других UNIX (например FreeBSD). Под Windows наверно можно запустить через виртуалку с линуксом, скомпилировать нативно не получится (и переделывать долго). =============================================================================== Прокси-сервер состоит из нескольких модулей: 1) fproxy - основной запускаемый демон; 2) fproxy_r - вспомогательный прокси-сервер для пробрасывания точки выхода в интернет через TCP-туннель; 3) fproxy-dashboard - список активных испольняемых http-запросов; 4) ssl-client-wrapper, ssl-server-wrapper - ssl/tls-обёртки для сокетов; сам fproxy не линкуется с openssl напрямую, всё шифрование вынесено в отдельные процессы; в некотором роде это аналоги openssl s_client и openssl s_server. =============================================================================== Компиляция, установка и настройка Для компиляции требуются системные библиотеки zlib и openssl. В случае с Debian это пакеты zlib1g-dev и libssl-dev. Кроме того, нужны библиотеки: https://dev.m1089.ru/fcl https://dev.m1089.ru/fcrypt https://dev.m1089.ru/libsimpletcp (на странице первой из них общие инструкции по компиляции). В случае использования "единого пакета для компиляции" fproxy-v80-p.tgz последние три библиотеки в него уже включены и надо только запустить build-all.sh из архива. В случае отдельной компиляции только прокси - нужно запустить build.sh из его директории. Для работы прокси нужна заранее подготовленная структура директорий. Для её создания есть скрипт prepare-dir.sh - он создаёт подготовленную директорию fproxy-target/ со всем что требуется и кладёт туда примеры правил (в том числе много блокировок спамных доменов), а так же генерирует сертификат cacert.pem, который надо будет добавить после этого в браузер как доверенный CA для сайтов. В случае использования единого пакета этот шаг тоже включёнв build-all.sh. Если нужно ограничить права доступа юзера к файлам прокси-сервера, или наоборот (прокси-сервера к файлам юзера), оставив серверу необходимый минимум прав - можно воспользоваться скриптом install-secure.sh. В созданной директории с установкой имеются следующие файлы и директории: 1) директория bin/ - тут лежат запускаемые бинарники, их можно переместить в любое другое место (например, в /usr/local/bin); 2) proxy.sh - простой образец стартового скрипта прокси-сервера, можно либо использовать как есть, либо сделать на его основе (или с нуля) свой; опять же он может лежать в любом месте, не обязательно в рабочей директории, но если тут что-то менять, то надо не забыть отредактировать и пути в proxy.conf; 3) proxy.conf - файл общих настроек; как и предыдущие, может лежать где угодно; опции: - base_dir - сюда стоит прописать абсолютный путь к рабочей директории прокси-сервера; относительный тоже будет работать, но с ним не всегда удобно; - listen.ip, listen.port - ip-адрес и порт, прослушиваемый сервером, можно оставить стандартные; учтите, что на FreeBSD для того, чтобы работал адрес 127.0.0.10, его надо вручную добавить локальному интерфейсу, иначе доступен только 127.0.0.1; - helpers.ssl_client_wrapper и helpers.ssl_server_wrapper - сюда желательно прописать полные пути к соответствующим бинарникам; стандартные настройки будут работать только если они лежат в ./bin/ от рабочей директории сервера; - inet_ssl.calist - путь к файлу с бандлом доверенных центров сертификации; если этот файл расположен не в /etc/ssl/certs/ca-certificates.crt то надо указать тут правильный путь. Остальные настройки можно не рассматривать до тех пор, пока они не понадобятся. 4) файлы runtime-данных сервера: - cache_real/ индекс кеша, двухуровневая структура - домен 2 уровня, потом полный домен; - cache_data/ хэш-хранилище кеша; - saved_real/ saved_data/ аналогичное для сохранённых страниц не-кеша; - cert-pin/certs/ настройки сертификатов для каждого домена (общий режим, белый/чёрный списки, вопросы); - cert-pin/queue/ тут создаются файлы при появлении вопросов в качестве флажков для интерактивной программы управлением этими настройками, если она будет; - cert-pin/cache/ кеш известных проксе сертификатов для дополнения неполных цепочек, принятых от сайтов (это НЕ список доверия, все эти сертификаты действительны только после прохождения проверок на общих основаниях); - dyn-certs/ кеш для сгенерированных сертификатов которые шлются браузеру; - internal/ сейчас тут хранится сокет для запросов от скачивателя AIA сертификатов; - log/ логи; - pem/ корневой сертификат и приватные ключи для генерации сертификатов сайтов; - proxy_temp/ хранение запросов которые слишком большие для хранения их в памяти; - tmp/ временные файлы; - dyn-cert-serial файл с текущим серийным номером генерируемого сертификата (начальное содежание - символ '0' и перевод строки после него); - mincache.date если файл есть и в нём тут записано число больше 0, то весь кеш раньше этого времени будет игнорироваться; - offline.flag если файл есть и в нём тут записано число больше 0, то прокси будет работать в режиме "интернет-архива" - на каждый запрос сначала искать в saved_real/ данные, близкие по времени к указанному числу, и только если не нашлось - проксировать запрос; - rules_*.txt различные правила, на данный момент их изменения учитываются только после перезапуска прокси. Простейший вариант установки - запустить всё из под своего обычного юзера с обычными правами на всё (можно даже прямо из директории fproxy-target/, созданной скриптом prepare-dir.sh). Но по ряду причин имеет смысл сделать по-другому. Для прокси создаётся отдельный юзер и группа, ему выдаются эксклюзивные права на чтение данных прокси, и права на запись в несколько мест, где они нужны. Права "только чтение" можно реализовать, поставив владельца root и группу прокси, и поставив доступ 0640 или 0750. Делать что бы то ни было из данных world-readable в любом случае плохая идея, всё же там лежит вся история браузера, а где-то и сохранённое содержание страниц, а так же ключи, с помощью которых браузеру можно делать MITM. Один из вариинтов расстановки прав на файлы реализует скрипт instll-secure.sh. Для работы программы fproxy-dashboard ей нужен только доступ на чтение к файлу BASE/log/dashboard и ничего другого. Пример запуска: fproxy-dashboard --loop --highlight --basedir=/home/proxy =============================================================================== Особенности 1. Отдельные модули для разворачивания шифрованного SSL/TLS-туннеля, один из которых при желании можно использовать как самостоятельную программу типа ssl-telnet. Ещё можно заменить их на какие-то альтернативные реализации (например с другой крипто-библиотекой), при этом остальная часть прокси ничего не заметит. Аналогично с инкрементальными обновлениями, ничего даже не нужно перезапускать. А ещё можно их исходники использовать как демки по работе с OpenSSL. Код старался делать максимально понятным и простым. У клиента есть хранилище сертификатов для: Клиент поддерживает в cert-pin/certs/domain.name.tld/ настройки проверки сертификатов для домена domain.name.tld: A{...} - этот сертификат в белом списке и принимается без проверки; D{...} - этот сертификат в чёрном списке и не принимается никак; Q{...} - этот сертификат был прислан сайтом и выглядит подозрительно, его можно переименовать в A{...} чтобы добавить в белый список; P - если в директории есть файл с таким именем (из одной буквы) то домен работает в режиме certificate pinning - обычные проверки доверия отключаются, и принимаются только сертификаты из белого списка; Серверная часть сама генерирует сертификаты ко всем сайтам на лету, ей нужен только корневой сертификат, добавленный как trusted root CA в браузер. 2. Возможность пробросить точку выхода в интернет через, например, ssh port forwarding. Для этого на удалённом сервере надо запустить (да, лучше два раза) ./fproxy_r 1.2.3.4:1115 & ./fproxy_r 1.2.3.4:1116 & (где 1.2.3.4:1115 - адрес и порт, которые будет слушать удалённый демон), а на локальном компьютере дописать в proxy.conf опции rproxy.host_dns=2.3.4.5 rproxy.port_dns=1115 rproxy.host_data=2.3.4.5 rproxy.port_data=1116 (где 2.3.4.5 - адрес, под которым на локаьном компьютере видны те порты удлённого сервера) и либо запускать демон с аргументом --proxy, либо настроить использование этого туннеля детально по урлам в rules_rproxy.txt. Это не тоже самое что запустить само прокси на удалённом сервере. Тут важно что кеш и расшифровка SSL/TLS находятся на локальном компе, а пробрасывается только "внешний" конец. 3. Единообразный формат файлов правил для: блокировки загрузки страниц, блокировки куков, управления кешированием, включения сниффера, включения raw-режима (для real-time стримингов). 4. Аналог /etc/hosts но усовершенствованный: возможность сопоставления айпи-адреса не только по хосту, но и по порту и по протоколу, а так же сменить порт и протокол подключения. 5. Кеш, управляемый прописанными ему настройками, а не заголовками, присланными сервером. Заголовки управления кешированием часто не отражают действительность (или отражают мнение владельца сайта, которое может расходиться с критериями удобства пользования этим сайтом), поэтому сейчас они игнорируются. Думаю что стоит сделать их учёт по принципу "если сайт разрешил кешировать то значит можно, а если нет - разбираемся сами можно или нельзя", но пока руки не дошли. Кеш хранится в интуитивно понятно организованном дереве директорий, хранится бессрочно, но можно либо вручную удалять отдельные сохранения, либо настройкой задать "игнорировать всё что сохранено раньше такого-то времени". 6. Кроме кеша есть ещё сохранения - это те страницы, которые не берутся с диска при запросе к ним, но на всякий случай всё равно сохраняются. При включении оффлайн-режима они тоже смотрятся (в файл offline.flag надо прописать предпочтительное время, за которое будут искаться сохранённые страницы при обращении к ним). При настройке сохранений учтите, что, несмотря на то, что сохраняются только ответы (содержимое POST-запросов не сохраняется), в них всё же могут быть некоторые данные, которые стоит беречь от кражи, а сохранённые на диске страницы - дополнительный вектор атаки. =============================================================================== ssl-client-wrapper можно использовать как самостоятельную программу. Если её запускать в контексте рабочей директории прокси-сервера - она будет использовать общие с ним настройки сертификатов. Пример использования: $ host ya.ru - узнаём ip-адрес ya.ru has address 87.250.250.242 $ ./ssl-client-wrapper T/etc/ssl/certs/ca-certificates.crt - указать путь к бандлу доверенных RootCA C87.250.250.242:443/ya.ru - подключиться по адресу + отправить SNI В ответ придёт много отладочных логов: 1) предоставленный сервером сертификат DEBUG: cert[-1] subject = /C=RU/L=Moscow/OU=ITO/O=Yandex LLC/CN=yandex.ru DEBUG: cert[-1] issuer = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA 2) предоставленная сервером цепочка сертификатов DEBUG: cert[0] subject = /C=RU/L=Moscow/OU=ITO/O=Yandex LLC/CN=yandex.ru DEBUG: cert[0] issuer = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA DEBUG: cert[1] subject = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA DEBUG: cert[1] issuer = /C=PL/O=Unizeto Technologies S.A./OU=Certum Certification Authority/CN=Certum Trusted Network CA DEBUG: cert[2] subject = /C=PL/O=Unizeto Technologies S.A./OU=Certum Certification Authority/CN=Certum Trusted Network CA DEBUG: cert[2] issuer = /C=PL/O=Unizeto Sp. z o.o./CN=Certum CA DEBUG: cert[-1] issued by cert[1] 3) лог неудачной попытки закешировать сертификат (программа была запущена вне контекста прокси) DEBUG: system error while cache-save cert './cert-pin/cache/2mvvwazq2up3clvpp8120nkvyda9hb46.*' 4) сообщение об успешном построении доверенной цепочки DEBUG: cert[1] was issued by something from trusted-cert-store, chain ended CERT: 0=MIIIpTCCB42gAwIBAgIQZk74Px48oykTjfGIx6WlPjANBgkqhkiG9w0BAQsF... CERT: 1=MIIEqDCCA5CgAwIBAgIRAOQFR4MODGRSl296NUnA3UgwDQYJKoZIhvcNAQEL... CERT: 2=MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYT... DEBUG: check wildcard 'yandex.ru' against needed name 'ya.ru' DEBUG: check wildcard 'ya.ru' against needed name 'ya.ru' 5) настройки TLS-сессии DEBUG: protocol = TLSv1.3 DEBUG: cipher = TLS_AES_256_GCM_SHA384 DEBUG: verify_result = 0 DEBUG: server_cert subject: /C=RU/L=Moscow/OU=ITO/O=Yandex LLC/CN=yandex.ru DEBUG: server_cert issuer: /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA OK: connection to 87.250.250.242:443/ya.ru established Теперь можно отправлять HTTP-запрос: GET / HTTP/1.1 400 Bad request Connection: Close Content-Length: 0 Плюсы и минусы (+) Модульность (-) Из-за изоляции OpenSSL работает медленнее чем могло бы (+) Гибкая настраиваемость под конкретные нужды (+-) Много настроек прямо в исходном коде в виде #define и не только (+-) IPv6 не поддерживается (-) Нет интерактивного приложения для настройки и управления (-) Код местами весьма плох и костылен (-) До сих пор нет поддержки Access-Control-Allow-Origin с не '*' в закешированных ответах - но это почти нигде не заметно (-) До сих пор нет поддержки учёта настроек кеширования, присылаемых сервером (-) Скачивать через него большие файлы (не в raw режиме) неэффективно - сначала прокси скачает файл себе на диск, затем будет через localhost-сеть отдавать его браузеру, который опять будет сохранять его на диск, а ещё там где-то (а может и в нескольких местах) прописано ограничение в 10мбайт на запрос