Задача 1: Улучшить качество работы CensorTracker

Необходимо написать proxy-сервер (аналогичный squid, 3proxy, dante …) на Go. 

Желательно оставаясь в рамках абстракций языка, но допустимо использование специфичных для Linux (но не для WIndows/MacOS/*BSD) библиотек, если есть возможность сделать работу более оптимальной (при тех же ресурсах обрабатывать больше запросов). 

Основные требования:

— Go

— Поддержка проксирования поверх https (остальные (нешифрованный HTTP, SOCKS), на самом деле, даже и не нужны). Transparent/MITM — тоже не нужно. Просто обычное проксирование поверх HTTPS, с указанным в файле конфигурации ключом и сертификатом. задача со звёздочкой — авторизация клиентов по клиентским сертификатам используя X.509

— Авторизация по юзеру-паролю, верифицируя реквизиты через сокет (например, по tcp) с настраиваемым временем кеширования «правильности» (кешировать на заданное время и ответ о невалидности и о валидности, желательно возможность отдельно выбирать время кеширование для каждого из вариантов). задача со звёздочкой — лимитирование пропускной полосы на основе полученного от «верификатора» (в случае валидности) значения. В идеале — учёт и полосы per-user в целом, и per-connection.

— Максимально возможная (без ухода в чёрную магию) оптимизация обработки запросов, т.к. предполагается жёсткий хайлод. Как минимум, чтобы результаты производительности было не сильно (10% max) хуже производительности squid’а без авторизации

— Возможность указания в конфигурации:

  •   TCP (если будет бесплатно по времени — QUIC крайне приветствуется, но на правах «со звёздочкой») портов (любого количества) для прослушивания. С поддержкой указания для каждого из них отдельной пары fullchain-сертификата и ключа
  •   указание разрешённых «целевых портов» (порт сервера, к которому идёт подключение через прокси). Со звёздочкой — так же, поддержка per-user списка разрешённых портов полученного от верификатора при авторизации.
  •   поддержка указания DNS-резолвера. Со звёздочкой — поддержка DoH-резолверов.
  •   поддержка указания «вышестоящего» прокси (HTTP, HTTPS, SOCKS{4,5}) в зависимости от запрашиваемого домена.
  •   настраиваемые таймауты. Со звёздочкой — файлы с ошибками (с указанием mime-типа для отдачи в Content-Type)

желательно придерживаться некоего подобия модульной инфраструктуры (в обоих смыслах: и распределение кода по подпроектам (package), для читабельности, и написание процесса обработки так, чтобы в случае не-использования какой-то фцнкциональности (например, неприменения замедления трафика) при обработке процесса не тратилось время на прохождение этой цепочки.

очень желательно иметь подробную историю коммитов (коммитить как можно чаще, при реализации каждого этапа).

– приз: 800$

Примечание:

Задачи со звёздочками — менее приоритетные, чем основной список (т.е. лучше реализовывать только если хватит времени, а до того момента лучше иметь на их месте заглушку или вообще не учитывать (контекстозависимо).

Задача про авторизацию по X509 самая низкоприоритетная. вторая снизу — QUIC.

— первая по приоритетности среди «звёздочек» — DoH, вторая — лимитирование скорости. Впрочем, если есть ощущение, что добавить X509 и/или QUIC будет легче и быстрее — можно взяться за них вместо лимитирования скорости

Задача 2: ​​Тестирование работоспособности VPN-сервисов 

Нужно протестировать работоспособность (по сути, по очереди меняя маршрут по-умолчанию) VPN-сервисов (предоставляющих свои приложения) (PIA, NordVPN, Protonvpn для начала) через свою распределённую VPN-сеть на базе https://tinc-vpn.org.

Основная проблема в том, что эти приложения переписывают маршруты (включая маршруты по умолчанию) по только им известной логике и даже попытка «пересилить» их прописыванием «умолчального» маршрута через свою VPN используя более конкретные подсети (две по /1 и даже 4 по /2) не приносит успеха, и они всё равно не работают.

Пока из придуманных потенциальных решений были мысли об использовании их в изолированных неймспейсах (например, через стандартные утилиты вроде `nsenter`, или через `ip netns`, или через `firejail`, или даже контейнерах, например, в docker. В общем, по вкусу). Идея в том, чтобы изолировать сеть, с которой работают они от реальной,

в основном неймспейсе менять маршрут «по умолчанию», выбирая серверы из своей VPN, через которые будет идти трафик, а трафик из другого неймспейса — чтобы вообще не знал какой сейчас выбран текущий шлюз по умолчанию и просто шёл через основной неймспейс (в упрощённой терминологии — «хостовую систему»).

Управлять всем этим необходимо из программы, написанной на Go. 

На выходе должна получиться такая схема:

— Управляющее приложение настраивает маршрут по умолчанию через выбранный шлюз

— Запускает приложение VPN в отдельном неймспейсе или контейнере

— Приложение VPN подключается к своей сети

— (вот тут продумать каким образом можно реализовать возможность маршрутизации управляющим приложением трафика через полученное подключение. Например, поднять в контейнере с vpn также прокси-демон. Либо пробросить VPN-интерфейс обратно в общий неймспейс, и прописать через него маршрут до сервера, тестируемого на доступность через подключение к VPN)

— Управляющее приложение выполняет запрос (через интеграцию с libcurl) на тестовый(е) сайт(ы).

— Проверяет ответы (либо ловит таймауты).

— На основе этого выполняет разные действия (последние пункты уже есть в текущей реализации, но если удобнее будет написать с нуля — достаточно просто выводить текст на стандартный вывод)

Предполагаемая основная сложность — в построении маршрутизации и, в частности, чтобы она не разваливалась.

Приз – 300$