Files
mtproxy_checker/docs/docker.ru.md
T

294 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Docker: образ mtproxy_checker
## Что внутри образа
| Компонент | Описание |
|-----------|----------|
| **База runtime** | Alpine Linux 3.20 |
| **Бинарники** | CLI: `/usr/local/bin/mtproxy_checker`. HTTP-сервис списка: `/usr/local/bin/mtproxy_checkerd` (см. ниже) |
| **Сертификаты** | Пакет `ca-certificates` (для TLS к реальным хостам при необходимости) |
| **ENTRYPOINT** | По умолчанию **CLI** — аргументы `docker run …` идут в `mtproxy_checker` |
| **Порты** | В режиме CLI ничего не слушает (только исходящий TCP). Образ объявляет **EXPOSE 8080** для режима API |
Одна команда `docker run` с entrypoint по умолчанию = **одна** проверка одного прокси; процесс завершается с **кодом выхода** (`0``4`), что удобно в CI и скриптах.
## HTTP API: `mtproxy_checkerd`
Лёгкий сервер на стандартной библиотеке Go: читает файл со списком `tg://` (как в разделе «файл — одна ссылка на строку»), **сразу после старта** выполняет первый цикл проверок, затем повторяет с интервалом. Результаты последнего цикла отдаются по HTTP в JSON.
### Запуск контейнера (смена entrypoint)
**Linux / macOS:**
```bash
docker run --rm -p 8080:8080 \
-v /path/to/proxies.txt:/data/proxies.txt:ro \
--entrypoint /usr/local/bin/mtproxy_checkerd \
mtproxy_checker:local
```
**Windows (PowerShell):**
```powershell
docker run --rm -p 8080:8080 `
-v "${PWD}\proxies.txt:/data/proxies.txt:ro" `
--entrypoint /usr/local/bin/mtproxy_checkerd `
mtproxy_checker:local
```
Готовый пример с переменными окружения: репозиторий **`docker-compose.api.yaml`** — `docker compose -f docker-compose.api.yaml up --build`.
### Переменные окружения
| Переменная | По умолчанию | Назначение |
|------------|--------------|------------|
| `MTPROXY_LIST_FILE` | `/data/proxies.txt` | Путь к файлу: одна `tg://` ссылка на строку; пустые строки и строки с `#` в начале пропускаются |
| `MTPROXY_CHECK_INTERVAL` | `5m` | Интервал между циклами (`time.ParseDuration`, например `5m`, `1h`) |
| `MTPROXY_HTTP_ADDR` | `:8080` | Адрес прослушивания HTTP |
| `MTPROXY_CHECK_TIMEOUT` | `15s` | Таймаут одной проверки (аналог `-timeout` CLI) |
| `MTPROXY_DC_ID` | `2` | DC id (аналог `-dc-id` CLI) |
| `MTPROXY_ALLOWED_IPS` | *(не задана)* | Если задана непустая строка — доступ к **всем** маршрутам только с перечисленных IP/CIDR; остальные получают **403** и JSON `{"error":"forbidden"}`. Формат: через запятую, пробелы допускаются: `192.168.1.10`, `10.0.0.0/8`, IPv6 и CIDR вида `2001:db8::/32`. Учитывается только **`RemoteAddr`** TCP-соединения; заголовок `X-Forwarded-For` **не** используется |
### HTTP
| Метод | Путь | Ответ |
|--------|------|--------|
| GET | `/health` | `200`, `{"status":"ok"}` |
| GET | `/api/v1/proxies` | `200`, JSON с полями `cycle_finished_at`, `next_check_after`, массив `proxies` |
Элемент `proxies[]`: `raw_line`, при успешном разборе — `url`, `ok`, `exit_code` (`0` OK, `1` ошибка проверки, `2` ошибка разбора URL/секрета, `3` прокси закрыл соединение, `4` таймаут), `error`, при необходимости `parse_error`, `checked_at`.
### Whitelist IP и Docker
Процесс видит **IP источника TCP** таким, каким его передал стек в контейнер. При пробросе порта с хоста (`-p 8080:8080`) на Linux часто это адрес **шлюза bridge** или **userland-proxy**, а не «настоящий» IP клиента с хоста. Имеет смысл задавать **CIDR подсети Docker** (например `172.17.0.0/16`), слушать только внутреннюю сеть, использовать **`--network host`** (на Linux) или ограничивать доступ на **обратном прокси** (nginx `allow` и т.п.).
## Требования
- [Docker Engine](https://docs.docker.com/engine/install/) (Linux) или Docker Desktop (Windows/macOS).
- Для `docker pull` из приватного registry — логин и токен.
## Сборка образа локально
**Linux / macOS:**
```bash
cd /path/to/mtproxy_checker
docker build -t mtproxy_checker:local .
```
**Windows (PowerShell):**
```powershell
cd C:\path\to\mtproxy_checker
docker build -t mtproxy_checker:local .
```
Проверка, что образ собран:
```bash
docker run --rm mtproxy_checker:local -timeout 5s 2>&1 | head -1
# ожидается сообщение usage (код выхода 2 — нормально без URL)
```
## Запуск под Linux
### Один прокси (ссылка `tg://`)
```bash
docker run --rm mtproxy_checker:local \
'tg://proxy?server=example.com&port=443&secret=eeYOURHEX...'
```
С флагами утилиты (таймаут, DC):
```bash
docker run --rm mtproxy_checker:local \
-timeout 25s -dc-id 2 \
'tg://proxy?server=example.com&port=443&secret=eeYOURHEX...'
```
Чтобы не светить секрет в истории shell, прочитайте его из файла и передайте флагами (образ запускает бинарник как `ENTRYPOINT`, отдельный `sh` без смены entrypoint использовать нельзя):
```bash
SECRET=$(tr -d ' \n' < secret.hex)
docker run --rm mtproxy_checker:local \
--server example.com --port 443 --secret "$SECRET"
```
### Сеть и DNS на Linux
- По умолчанию контейнер использует bridge Docker; нужен исходящий доступ к `server:port` и рабочий DNS.
- Если имена не резолвятся:
```bash
docker run --rm --dns 8.8.8.8 mtproxy_checker:local 'tg://proxy?...'
```
- Режим сети хоста (как на машине без NAT; используйте осознанно):
```bash
docker run --rm --network host mtproxy_checker:local 'tg://proxy?...'
```
На Docker Desktop для Windows/macOS `--network host` ведёт себя иначе, чем на Linux.
## Несколько MTProxy ссылок подряд
Утилита принимает **ровно один** прокси за запуск. Чтобы проверить много `tg://` ссылок, обходите их в оболочке.
### Вариант 1: цикл в bash
```bash
IMAGE=mtproxy_checker:local # или registry/owner/mtproxy_checker:latest
for url in \
'tg://proxy?server=a.example.com&port=443&secret=ee1111...' \
'tg://proxy?server=b.example.com&port=8443&secret=ee2222...' \
'tg://proxy?server=c.example.com&port=443&secret=dd3333...'
do
echo "=== $url ==="
if docker run --rm "$IMAGE" -timeout 20s "$url"; then
echo "OK"
else
echo "FAIL (код $?)"
fi
done
```
### Вариант 2: файл — одна ссылка на строку
`proxies.txt` (пустые строки и строки с `#` в начале можно пропускать):
```
tg://proxy?server=one.example.com&port=443&secret=ee...
tg://proxy?server=two.example.com&port=8443&secret=ee...
```
Скрипт:
```bash
IMAGE=mtproxy_checker:local
while IFS= read -r line || [ -n "$line" ]; do
line="${line#"${line%%[![:space:]]*}"}" # trim leading spaces
[ -z "$line" ] && continue
case "$line" in \#*) continue ;; esac
echo "=== $line ==="
docker run --rm "$IMAGE" -timeout 20s "$line" && echo OK || echo "FAIL ($?)"
done < proxies.txt
```
### Вариант 3: параллельно (`xargs`)
Осторожно: одновременно много контейнеров нагружают сеть и целевые прокси.
```bash
IMAGE=mtproxy_checker:local
grep -v '^\s*$\|^\s*#' proxies.txt | xargs -I{} -P 4 sh -c \
'echo "=== {}"; docker run --rm '"$IMAGE"' -timeout 20s "{}" || echo FAIL'
```
`-P 4` — не более четырёх проверок одновременно; уменьшите при необходимости.
### Вариант 4: итоговый код для CI
Если нужен «провал всего job при любом FAIL»:
```bash
set -e
IMAGE=mtproxy_checker:local
while IFS= read -r url; do
[ -z "$url" ] && continue
case "$url" in \#*) continue ;; esac
docker run --rm "$IMAGE" -timeout 25s "$url"
done < proxies.txt
```
## Запуск из PowerShell (Windows)
Одинарные кавычки с `tg://` в PowerShell неудобны; проще двойные:
```powershell
docker run --rm mtproxy_checker:local `
"tg://proxy?server=example.com&port=443&secret=eeYOURHEX..."
```
Несколько ссылок:
```powershell
$urls = @(
"tg://proxy?server=a.com&port=443&secret=ee...",
"tg://proxy?server=b.com&port=8443&secret=ee..."
)
foreach ($u in $urls) {
Write-Host "=== $u ==="
docker run --rm mtproxy_checker:local -timeout 20s $u
if ($LASTEXITCODE -ne 0) { Write-Host "FAIL exit $LASTEXITCODE" }
}
```
## Загрузка образа из Container Registry Gitea
1. Включите **Packages / Container Registry** на инстансе Gitea ([документация](https://docs.gitea.com/usage/packages/container)).
2. Создайте токен с правом на пакеты.
3. Логин:
```bash
docker login git.shts.su
# или ваш registry
```
4. Сборка workflow публикует теги `latest`, имя ветки/тега и `sha-…` — см. `.gitea/workflows/docker.yaml`.
```bash
docker pull git.shts.su/owner/mtproxy_checker:latest
docker run --rm git.shts.su/owner/mtproxy_checker:latest 'tg://proxy?...'
```
## Пример docker-compose
Одна проверка за `compose run`:
```yaml
services:
mtproxy-check:
image: mtproxy_checker:local
build: .
command: ['tg://proxy?server=example.com&port=443&secret=ee...']
```
```bash
docker compose run --rm mtproxy-check
```
Для списка прокси удобнее внешний bash-цикл или отдельный `command: ["sh","-c","..."]` с циклом по файлу, смонтированному в volume.
## Использование в CI другого проекта
```bash
docker run --rm registry.example.com/owner/mtproxy_checker:latest \
"tg://proxy?server=${MTPROXY_HOST}&port=${MTPROXY_PORT}&secret=${MTPROXY_SECRET}"
```
## Коды выхода и диагностика
| Код | Значение |
|-----|----------|
| 0 | Проверка прошла |
| 1 | Ошибка (сеть, протокол, неверный ответ) |
| 2 | Неверные аргументы CLI |
| 3 | Прокси закрыл TCP сразу после начального payload |
| 4 | Общий таймаут (`-timeout`) |
**Не путать с ping:** ICMP не используется.
Типичные сообщения:
- `connection refused` — порт закрыт или фильтр.
- `FAIL: timeout` — нет ответа за `-timeout`.
- Ошибки чтения/проверки ServerHello — несовместимый ответ или обрыв соединения.
Для отладки без `--rm` можно посмотреть логи контейнера по id; с `--rm` контейнер удаляется сразу после выхода.