Задача 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$