Termux предоставляет полноценную Linux‑среду на Android‑устройствах, позволяя устанавливать компиляторы, библиотеки и запускать серверные приложения непосредственно на смартфоне. В этой статье мы рассмотрим, как создать простой сетевой прокси‑сервер с использованием библиотеки libproxy, которая автоматически определяет настройки прокси в системе и упрощает работу с сетью.
Подготовка окружения в Termux
Для начала нужно установить базовые инструменты разработки и необходимые зависимости.
pkg update && pkg upgrade -y
pkg install -y git clang make autoconf automake libtool pkg-config openssl-dev libxml2-dev
Эти пакеты обеспечат компилятор clang, систему сборки make и заголовочные файлы, требуемые для сборки libproxy.
Установка libproxy
Библиотека libproxy не входит в стандартные репозитории Termux, поэтому её необходимо собрать из исходных кодов.
# Склонировать репозиторий libproxy
git clone https://github.com/libproxy/libproxy.git
cd libproxy
# Подготовить сборочную среду
./autogen.sh
./configure --prefix=$HOME/.local
make -j$(nproc)
make install
После установки библиотека будет находиться в каталоге $HOME/.local. Добавьте путь к библиотекам в переменную окружения, чтобы система могла их находить:
export PKG_CONFIG_PATH=$HOME/.local/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
Создание простого HTTP‑прокси
Ниже представлен минимальный пример прокси‑сервера на C, использующего API libproxy для получения системных настроек прокси. Прокси прослушивает локальный порт 8080 и перенаправляет HTTP‑запросы согласно найденным правилам.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <proxy.h> // libproxy header
#define LISTEN_PORT 8080
#define BUFFER_SIZE 4096
/ Функция получения URL‑прокси из libproxy /
static char get_proxy_for_url(const char url)
{
pxProxyFactory factory = px_proxy_factory_new();
if (!factory) return NULL;
char **proxies = px_proxy_factory_get_proxies(factory, url);
px_proxy_factory_free(factory);
if (!proxies || !proxies[0]) return NULL;
char result = strdup(proxies[0]);
px_proxy_factory_free_proxies(proxies);
return result;
}
int main(void)
{
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) { perror("socket"); return 1; }
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(LISTEN_PORT);
if (bind(listen_fd, (struct sockaddr )&addr, sizeof(addr)) < 0) {
perror("bind"); close(listen_fd); return 1;
}
if (listen(listen_fd, 10) < 0) { perror("listen"); close(listen_fd); return 1; }
printf("[+] Прокси запущен на порту %d
", LISTEN_PORT);
while (1) {
int client_fd = accept(listen_fd, NULL, NULL);
if (client_fd < 0) { perror("accept"); continue; }
char buffer[BUFFER_SIZE];
ssize_t len = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);
if (len <= 0) { close(client_fd); continue; }
buffer[len] = '\0';
/ Извлекаем первую строку запроса, например: GET http://example.com/ HTTP/1.1 /
char method[8], url[256];
if (sscanf(buffer, "%7s %255s", method, url) != 2) {
close(client_fd); continue;
}
char proxy = get_proxy_for_url(url);
if (proxy) {
printf("[i] Для %s найден прокси %s
", url, proxy);
/ Если прокси указан, просто передаём запрос клиенту без изменений –
реальная реализация должна открыть соединение с прокси и ретранслировать /
free(proxy);
} else {
printf("[i] Прокси для %s не найден, соединяемся напрямую
", url);
}
/ Простейшее пробросное соединение к целевому хосту /
char host[128];
int port = 80;
if (sscanf(url, "http://%127[^:/]:%d", host, &port) == 2) {
/ host и порт указаны явно /
} else if (sscanf(url, "http://%127[^/]/", host) == 1) {
/ порт по умолчанию 80 /
} else {
close(client_fd); continue;
}
int remote_fd = socket(AF_INET, SOCK_STREAM, 0);
if (remote_fd < 0) { perror("socket remote"); close(client_fd); continue; }
struct sockaddr_in remote_addr = {0};
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(port);
if (inet_pton(AF_INET, host, &remote_addr.sin_addr) <= 0) {
/ Попытка разрешить имя через DNS /
struct hostent he = gethostbyname(host);
if (!he) { perror("gethostbyname"); close(remote_fd); close(client_fd); continue; }
memcpy(&remote_addr.sin_addr, he->h_addr, he->h_length);
}
if (connect(remote_fd, (struct sockaddr )&remote_addr, sizeof(remote_addr)) < 0) {
perror("connect remote"); close(remote_fd); close(client_fd); continue;
}
/ Перешлём исходный запрос /
send(remote_fd, buffer, len, 0);
/ Перенаправим ответ клиенту /
while ((len = recv(remote_fd, buffer, BUFFER_SIZE, 0)) > 0) {
send(client_fd, buffer, len, 0);
}
close(remote_fd);
close(client_fd);
}
close(listen_fd);
return 0;
}
Код демонстрирует лишь базовый механизм: чтение HTTP‑запроса, получение системного прокси через libproxy и прямое соединение с целевым сервером. Для полноценного прокси‑серверного решения необходимо добавить поддержку HTTPS CONNECT, многопоточность (или асинхронный I/O) и обработку ошибок.
Сборка и запуск
Сохраните пример в файл simple_proxy.c и соберите его, указав путь к установленной библиотеке.
clang -o simple_proxy simple_proxy.c \
-I$HOME/.local/include \
-L$HOME/.local/lib -lproxy -lxml2 -lssl -lcrypto
# Запуск
./simple_proxy
После запуска в терминале появится сообщение [+] Прокси запущен на порту 8080. Настройте в браузере Android или в приложении curl прокси‑настройку:
curl -x http://127.0.0.1:8080 http://example.com
Отладка и улучшения
Для упрощения отладки рекомендуется использовать:
strace– просмотр системных вызовов.tcpdump(черезtermux-tools) – анализ сетевого трафика.- Логирование в файл вместо
printfдля длительной работы.
Возможные улучшения:
- Поддержка
HTTPS CONNECTи TLS‑терминации. - Асинхронная обработка соединений с помощью
libuvилиepoll. - Кеширование DNS‑результатов и поддержка HTTP/2.
Заключение
Создание собственного сетевого прокси в Termux с использованием libproxy позволяет быстро реализовать адаптивные решения, учитывающие системные настройки прокси. Такой подход удобен для разработки мобильных тестовых стендов, отладки сетевых приложений и обучения принципам работы прокси‑серверов.
Если вам требуется профессиональная разработка, настройка инфраструктуры или консалтинг в сфере IT, обратитесь к специалистам RybinskLab. Мы предоставляем комплексные IT‑услуги в Рыбинске, помогая реализовать проекты любой сложности.