Информация о проекте
Общее
Название —
backconnect
Цена —USD 8'800
Техническое задание
Балансировщик и распределитель нагрузки
- Эффективное распределение входящего трафика по серверам.
- Возможность добавления или удаления серверов на лету.
- Интеграция с поддоменом для backconnect прокси (
cn.example.com).
API Wrapper
- Реализация endpoint'ов для управления сервисом (авторизация, управление трафиком, статистика, мониторинг).
- Система управления сессиями и логика роутинга (в том числе гео-роутинг).
Безопасность и мониторинг
- Динамическое управление доступом и блокировками.
- Автоматизированное логирование для аудита и реагирования на инциденты.
- Мониторинг в реальном времени: состояние серверов, нагрузка, потребление трафика.
Приложенные файлы
TZ 00 .txt
Общее техническое задание.
Необходимо сделать только backend для роутинга на основной backconnect-сервис
Конечная цель: реализация аналога прокси oxylabs.com с возможностью масштабирования на горячую (добавление|убавление серверов, новых приложений на лету)
==========================
Общий концепт
Наш домен: example.com
поддомен для бекконекта - cn.example.com
поддомен для основной прокси - pr.example.com
Есть подконтрольные нам разные мобильные приложения в которых внедрен наш код
Как только пользователь открывает приложение - его устройство подключается к домену cn.example.com ( на этом поддомене будет висеть какой-то балансировщик для бекконект серверов)
И на сервере к которому устройство подключилось - поднимается бэкконект прокся, сохраняя (или отправляя) куда-то? данные о бекконекте
Основная прокся которая будет стоять на серверах (pr.example.com) Должна иметь информацию о всех доступных бекконект проксях которые у нас есть
(для того чтобы каждый пользователь проксей имел доступ к полному пулу)
==========================
Тех задачи основной прокси
Все роутинги выполняются с помощью изменения ЛОГИНА в авторизации прокси
Поддержка ipv6 + ipv4 ОБЯЗАТЕЛЬНА
1) роутинг по гео:
Постфикс в логине обозначается как "cc" например cc-US, без учета регистра (пример: customer-user000-cc-us)
гео указывается в формате ISO-3166-2 (US - usa, CA - canada, GB - uk, IN - india)
Если выбраного юзером гео нету - страну выбирать рандомно.
2) роутинг по сессиям:
Постфикс в логине обозначается как "sessid" и "sesstime" (пример: customer-user000-cc-us-sesstime-5-sessid-100000000)
sessid и sesstime используются для того чтобы пользователь имел один и тот-же ip адресс нужное для него количество времени
sesstime может быть от 1 до 120 ( значение в минутах), тоесть при попытке отправить запрос с сессией -
прокся должна проверить существует ли такая сессия для конкретного пользователя, если нету - создать сохранить где-то нужный роутинг у себя на заданое время
Если сессия уже создана и заданое изначально время в ней не прошло, а пользователь пытается тот-же sessid использовать с новым гео,
либо с новым sesstime - выдавать нужно ip адрес который был изначально присвоен данной сессии
Если сессия ещё не закончилась, а ip адрес который был ей выдан - пропал по какой либо причине (пользователь закрыл приложение к примеру)
Нужно выдавать этой сессии новый ip из того-же гео которые было (даже если гео не было указано изначально) // может тут надо дополнительно просматривать всю базу бекконекта в поиске старого ip который был у сессии?
3) Пользователи:
подсчет расхода трафика пользователя (вычитая потраченый траф с его баланса)
создание, изменение данных, удаление профилей пользователей (у пользователя есть логин,пароль,количество трафика)
пополнение баланса трафика
4) Статистика:
(графики мы сами можем сделать, нужны только данные)
(100% будут исправления + изменения в этом пункте)
все данные должны отображаться за выбранный период времени
Количество онлайн серверов (для каждого поддомена свой счетчик)
Текущая и максимальная предельная нагрузка Mbit/s либо gbit/s для серверов (в сумме)? ( для каждого поддомена свой счетчик)
общая нагрузка (Mbit/s) (счетчик + график)
нагрузка mbit/s по каждому юзеру (табличка) // пункт под сомнениями
общее потраченое количество трафика (gb) (счетчик)
общее количество онлайн проксей (график)
общее количество онлайн проксей (график по каждому приложению)
общее количество онлай проксей по странам (табличка + график для топ стран по онлайну?)
общее потраченное количество трафика каждого юзера(n топ юзеров)
P.S МНОГО СТАТИСТИКИ НЕ БЫВАЕТ!
5) Внедряемся в приложения за деньги? // пункт под сомнениями
Возможно стоит сделать ещё для каждого приложения подсчет сколько через их пользователей прокачали трафика
чтобы в будущем была возможность у разрабов прил зарабатывать с продажи трафика их юзеров.
6) Мониторинг, жопная безопасность:
Нужна возможность динамически блочить/анлочить домены,айпи адреса, порты у проксей.
Т.е должен быть некий список правил типа
залочить для ВСЕХ домен google.com
анлокнуть для юзера user707 google.com
и у всех кроме user707 должен НЕ работать гугл
Логи!Нужно продумать логирование действий каждого юзера( чтобы при необходимости можно было предоставить интересующие федералов логи)
==========================
Backconnect API
Peer - удаленный прокси-сервер подключенный к Backconnect
Byte order: Big Endian
Request/Response format:
+-----------+------------+-------+--------------+
| Frame Len | Req. Token | TAG | Message Data |
+-----------+------------+-------+--------------+
| int32 | int64 | int16 | byte... |
+-----------+------------+-------+--------------+
где:
Frame Len: длина фрейма (все что после Frame Len)
TAG: тэг сообщения, указан в .proto схемах
Req. Token:
Request Token - идентификатор запроса, так например: когда вы отправляете запрос с Request Token = 1
вы получаете ответ с этим же числом, это позволяет клиенту получить ответ на конкретный RPC вызов
Message Data: сериализованные данные (в основном Protobuf, но есть также Raw схемы сообщений)
Пока TLS не будет использован, в будущем могут быть изменения по этому пункту (то есть нужно проектировать так, чтобы в любой момент можно было активировать TLS)
Соединение с бекконнектом должно быть одно, либо пул соединений
Сразу после подключения, необходимо авторизоваться по секретному ключу выполнив RPC вызов AuthRequest.
ListPeers позволяет получить количество подключенных пиров. В ответе список с Peer, каждый объект Peer содержит 'id',
это уникальный идентификатор пира, с его помощью можно установить соединение через конкретное устройство/ip адрес/пир (как удобно)
Поскольку один пир может установить несколько соединений (c несколькими remote), у каждого соединения также
будет свой 'stream_id'. C помощью 'peer_id' и 'stream_id' можно:
1) Изменить состояние соединения (закрыть)
2) Получить состояние соединения (соединение закрыто/соединение установлено/не удалось открыть/пир отлючился)
3) Отправка данных в конкретный пир в конкретное соединение
Схемы сообщений:
Protobuf messages:
* - обязательные поля
Request: AuthRequest:
Description: авторизация
Params:
* string key - ключ авторизации
Response: AuthResponse:
params:
* LoginCodes result - результат авторизации
Request: ListPeers:
Description: запрос подключенных пиров
Response: Peers:
params:
List<Peer> - список с информацией о пирах, может быть пустым
Request: OpenStream:
Description: установить соединение с удаленным хостом через Peer
Params:
* int64 peer_id - id пира с которого установить соединение
* string host - hostname удаленного сервера с которым установить соединение <IPv4 / IPv6 / Domain>
* int32 port - порт удаленного сервера с которым установить соединение (ranges: 0 - 65535)
int32 timeout - необязательный параметр, таймаут подключения (ranges: 0 - 30 seconds)
Response: StreamStatus:
params:
* int64 peer_id - ID пира
* int64 stream_id - ID соединения; 0 если соединение неуспешно
* StatusCode status - статус соединения, см. в .proto файле
StreamStatus:
Description:
1) сообщает об изменении статуса соединения (если клиент получил данное сообщение: Backconnect -> Client)
2) изменяет статус соединения (если отправлен клиентом: Client -> Backconnect)
params:
* int64 peer_id - ID пира
* int64 stream_id - ID соединения; (в сообщение от сервера может быть 0 если соединение неуспешно)
* StatusCode status - статус соединения, см. в .proto файле
Raw messages:
StreamWrite: обмен данными между клиентом и сервером
Scheme:
+---------+-----------+-----------+---------+
| Peer ID | Stream ID | Data Len. | Data |
+---------+-----------+-----------+---------+
| int64 | int64 | int32 | byte... |
+---------+-----------+-----------+---------+
где:
Peer ID: идентификатор пира
Stream ID: идентификатор соединения
Data Len: длина данных
Data: raw-данные
bc-api.proto
protobuf основного backconnect-сервиса
package BackconnectAPI;
option java_package = "bcapi";
// TAG: 0x0000
message AuthRequest {
required string key = 1;
}
// TAG: 0x0001
message AuthResponse {
enum LoginCodes {
AUTH_FAILED = -1;
AUTH_SUCCESSFUL = 0;
}
required LoginCodes result = 1;
}
// TAG: 0x0002
message ListPeers {
}
// TAG: 0x0003
message Peers {
repeated Peer peers = 1;
}
// TAG: 0x0004
message OpenStream {
required int64 peer_id = 1;
required string host = 2;
required int32 port = 3;
optional int32 timeout = 4;
}
// TAG: 0x0005
message StreamStatus {
enum StatusCode {
PEER_NOT_FOUND = 0;
PEER_DISCONNECTED = 1;
CONNECTION_FAILED = 2;
CONNECTION_CLOSED = 3;
CONNECTION_SUCCESSFUL = 4;
}
required int64 peer_id = 1;
required int64 stream_id = 2;
required StatusCode status = 3;
}
// 0x0006
// message StreamWrite
message Peer {
required int64 id = 1;
required string ip_address = 2;
required int64 connect_time = 3;
}
