Информация о проекте

Общее

Название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;
}