Эта статья — не обзор сервисов, а разбор рабочей схемы. Мы держим на своём сервере Claude Code, двух ИИ-агентов техподдержки и контейнер с графовой памятью. Все они обращаются к API Anthropic и OpenAI, и все ходят туда через прокси для ИИ, который мы подняли сами. Ниже — как именно это устроено, что проверять и где схема ломается.
Сразу оговорим главное: прокси для ИИ — это две разные задачи, и путать их дорого. Доступ к API из кода и доступ к веб-интерфейсу ChatGPT в браузере закрываются разными способами. Схема, которая идеально работает для первой задачи, для второй не работает вовсе — и мы это измерили.
Что именно блокируется: проверяем, а не угадываем
Прежде чем что-то настраивать, стоит посмотреть, как выглядит отказ. Мы дёрнули эндпоинты с российского сервера напрямую и через свой прокси. Вот реальные коды ответов:
| Адрес | Напрямую из РФ | Через наш прокси | Что это значит |
|---|---|---|---|
api.anthropic.com | 403 | 405 Method Not Allowed | Прокси работает: 405 — это ответ самого API на GET вместо POST |
api.openai.com/v1/models | 403 | 401 Missing bearer authentication | Прокси работает: API просит ключ, значит запрос дошёл |
chatgpt.com | 403 | 403 cf-mitigated: challenge | Прокси НЕ помог: сработала защита Cloudflare |
Разберём, почему это важно. 403 напрямую — отказ по географии: запрос отклонён до всякой авторизации, просто потому что пришёл с российского адреса. 405 и 401 через прокси — это успех, хотя коды и выглядят как ошибки: сервер API нас принял и ответил по делу. Именно так и выглядит правильно настроенный прокси для Claude Code или прокси для OpenAI — не «200 OK», а внятная ошибка приложения вместо глухого отказа.
А вот третья строка — та самая ловушка, на которой спотыкается почти любой самодельный прокси для ChatGPT. Заголовок cf-mitigated: challenge означает, что Cloudflare не заблокировал нас по стране, а выдал проверку: «докажи, что ты браузер живого человека». Датацентровый IP зарубежного VPS эту проверку проходит плохо, и веб-интерфейс ChatGPT через такой прокси остаётся недоступным. Для API это не помеха вообще, для браузера — стена. К этому вернёмся в конце.
Почему не VPN на весь компьютер
Самый частый совет — «включи VPN». Для разработки он плохо подходит, и вот почему.
- Под прокси нужен один процесс, а не вся машина. Когда через туннель уходит весь трафик, туда же уезжают запросы к вашей БД, к внутренним сервисам, к панели хостинга. Часть из них отвалится по белым спискам IP, часть просто станет медленнее.
- Сервер — не ноутбук. На боевом сервере глобальный VPN означает, что сайт начнёт отвечать клиентам через чужой адрес или не отвечать вовсе. Нам нужно было ровно обратное: сайт работает как раньше, а к ИИ-сервисам ходят только конкретные инструменты.
- Автозапуск. Кроны и systemd-юниты поднимаются раньше, чем графический VPN-клиент, и молча падают с ошибкой сети.
- Диагностика. При глобальном туннеле невозможно ответить на вопрос «этот запрос ушёл через прокси или напрямую» — а без ответа на него утечки не ловятся.
Поэтому мы сделали адресный выход: прокси знают только те процессы, которым он нужен. Остальная система его даже не видит — этот запрет мы прописали отдельно, о нём ниже.
Схема целиком
Прокси для нейросетей у нас собран из двух звеньев. Цепочка выглядит так:
claude / ИИ-агенты / контейнер с памятью
→ privoxy на 127.0.0.1:8118 (локальный переходник HTTP → SOCKS5)
→ SOCKS5 на зарубежном VPS :3128 (свой, доступ по белому списку IP)
→ api.anthropic.com / api.openai.com
Два звена вместо одного — не усложнение ради усложнения. У каждого своя роль:
- SOCKS5 на зарубежном сервере даёт не-российский адрес. Это то, за чем всё затевалось.
- privoxy на localhost — переходник. Инструменты настраиваются переменными
HTTPS_PROXYиHTTP_PROXY, то есть ждут HTTP-прокси, а наш апстрим — SOCKS5. privoxy принимает HTTP-запрос и отдаёт его в SOCKS. Заодно он избавляет от необходимости прописывать адрес и порт VPS в десяти местах: сменится апстрим — правим одну строку в одном конфиге.
Дальше — по шагам, ровно в том порядке, в каком это делали мы.
Шаг 1. Сервер за пределами РФ
Нужен самый простой VPS. Требования скромные: 1 ядро, 1 ГБ памяти, статический IPv4. SOCKS5-прокси почти не потребляет ресурсов — он только переливает байты; у нас на этой машине живут ещё две службы, и нагрузки не видно.
Что действительно важно при выборе:
- Локация. Европа даёт отклик в пределах десятых долей секунды до API — нам хватает. Проверяйте, что провайдер вообще пускает трафик к нужным сервисам.
- Выделенный IP, не общий NAT. Прокси на общем адресе рискует поймать чужую репутацию.
- Оплата из России. Банальность, но половина зарубежных хостеров отсекается именно здесь.
Мы берём серверы у Aeza — там есть европейские локации, оплата картой РФ и почасовая тарификация, то есть эксперимент с прокси можно свернуть без потерь. Ссылка партнёрская; цена по ней для вас та же. Конкретные тарифы не приводим намеренно — они меняются чаще, чем обновляются статьи, смотрите актуальные на сайте.
После заказа вам выдадут IP и пароль root. Дальше все команды выполняются на сервере, адрес в примерах — из документационного диапазона, подставляйте свой:
ssh root@203.0.113.10
Шаг 2. SOCKS5-сервер: dante
Мы используем dante — он умеет именно SOCKS5, стабилен и не требует настройки TLS. Установка:
apt update && apt install -y dante-server
Теперь конфиг /etc/danted.conf. Вот он целиком, с нашей боевой логикой доступа:
logoutput: /var/log/danted.log
internal: eth0 port = 3128
external: eth0
method: none
user.privileged: root
user.notprivileged: nobody
client pass {
from: 203.0.113.50/32 to: 0.0.0.0/0
log: connect disconnect error
}
client block {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect error
}
pass {
from: 203.0.113.50/32 to: 0.0.0.0/0
protocol: tcp udp
}
block {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect error
}
Здесь 203.0.113.50 — адрес машины, с которой вы будете ходить (ваш сервер или домашний IP). Разберём неочевидное.
Почему method: none — и почему это не дыра
method: none означает «без логина и пароля». Звучит пугающе, но защита здесь построена иначе: пускаем строго по IP, всё остальное — block. Для схемы «сервер ходит к серверу» это надёжнее пароля: пароль может утечь в git, в лог или в чужой транскрипт, а белый список не утекает никуда.
Чего делать нельзя: оставить method: none и не настроить block. Открытый SOCKS5 находят сканерами за часы, и дальше через ваш адрес пойдёт чужой спам и брутфорс — с предсказуемым письмом от хостера. Мы видели, как из-за этого блокировали сервер целиком, вместе с данными на нём.
Ловушка: две версии dante с несовместимыми конфигами
Это стоило нам часа. В старых дистрибутивах (у нас на этой машине Ubuntu 16.04 и dante 1.1.19) синтаксис другой, чем во всех примерах из интернета, написанных под ветку 1.4:
| Смысл | Старый синтаксис (1.1.x) | Новый (1.4.x) |
|---|---|---|
| Метод аутентификации | method: none | socksmethod: none |
| Правило пропуска | pass { } | socks pass { } |
Конфиг «не той» версии не принимается вовсе. Поэтому перед запуском всегда проверяйте его разбором, а не надеждой:
danted -V -f /etc/danted.conf
Команда либо промолчит, либо укажет строку с ошибкой. И только после этого — запуск.
Файрвол: белый список нужен в двух местах
Правила внутри dante — первый рубеж, но не единственный. Продублируйте их в файрволе:
iptables -A INPUT -p tcp --dport 3128 -s 203.0.113.50 -j ACCEPT
iptables -A INPUT -p tcp --dport 3128 -j DROP
Зачем два раза одно и то же: конфиг демона можно случайно перезаписать при обновлении пакета, файрвол — отдельный слой. У нас правила лежат в скрипте, который вызывается при загрузке; проверьте, что ваши правила переживают перезагрузку — иначе первый же ребут откроет порт всему интернету, и вы об этом не узнаете.
Шаг 3. Автозапуск, который не переживает перезагрузку
Отдельный раздел, потому что ошибка здесь тихая и вылезает через недели — в момент внеплановой перезагрузки.
Пакетный init-скрипт dante в старых системах объявляет зависимости так, что демон стартует раньше, чем сетевая карта получает адрес. В конфиге указано internal: eth0 — привязываться не к чему, и служба падает. Проверить это «после ребута» уже поздно: прокси просто нет, а ИИ-инструменты отваливаются без объяснений.
Мы заменили init-скрипт на свой юнит /etc/systemd/system/danted.service:
[Unit]
Description=Dante SOCKS5 server
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/danted.pid
ExecStart=/usr/sbin/danted -D -f /etc/danted.conf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Ключевые строки — After=network-online.target (ждём сеть) и Restart=on-failure (поднимаемся сами). Включаем и проверяем, что перезапуск действительно работает:
systemctl daemon-reload
systemctl enable --now danted
kill -9 $(cat /var/run/danted.pid)
sleep 7; systemctl is-active danted # ждём: active
Если старый init-скрипт остался включённым, отключите его, иначе две службы будут драться за порт.
Шаг 4. Переходник на своей стороне: privoxy
Возвращаемся на машину, где живёт Claude Code. Ставим privoxy:
apt install -y privoxy
И приводим /etc/privoxy/config ровно к двум значимым строкам — у нас в бою так и есть:
listen-address 127.0.0.1:8118
forward-socks5t / 203.0.113.10:3128 .
Разберём обе, в них весь смысл шага.
listen-address 127.0.0.1:8118
Только петлевой интерфейс. Если написать 0.0.0.0:8118, вы получите открытый HTTP-прокси, доступный всему интернету, — то же самое, от чего защищались на предыдущем шаге, но уже на своей машине.
forward-socks5t — буква t не опечатка
Это самое ценное место статьи. Есть два похожих варианта: forward-socks5 и forward-socks5t.
При socks5 privoxy сам резолвит доменное имя локально и в SOCKS отправляет уже готовый IP. Соединение работает, всё выглядит правильно — но список всех сервисов, куда вы обращаетесь, уходит открытыми DNS-запросами к резолверу хостера или к публичному DNS. Трафик спрятан, а маршрут посещений виден со стороны.
При socks5t имя передаётся в SOCKS как имя и резолвится на зарубежном VPS. Утечки нет.
Проверяется это замером, а не верой. Смотрим счётчик DNS-транзакций до и после проксированного запроса:
resolvectl statistics | grep -i 'Total Transactions'
curl -x http://127.0.0.1:8118 -o /dev/null -s https://api.anthropic.com/v1/messages
resolvectl statistics | grep -i 'Total Transactions'
У нас прирост ровно 0 — локальный резолвер не потревожен, имя ушло в туннель. Если счётчик подрос, у вас socks5 без t. Это, пожалуй, самая распространённая незамеченная ошибка в самодельных прокси для нейросетей.
Шаг 5. Подключаем Claude Code и остальные инструменты
Осталось сказать инструментам, где искать выход. Прокси для Claude Code включается переменными окружения — своего формата настроек тут не нужно.
Claude Code читает стандартные переменные окружения. Проверить прокси можно сразу, одной командой:
HTTPS_PROXY=http://127.0.0.1:8118 HTTP_PROXY=http://127.0.0.1:8118 claude
Чтобы не печатать это каждый раз, мы завели алиас в ~/.bashrc. Заодно — ограничение памяти, потому что длинные сессии умеют раздуваться и выселять с сервера соседние службы:
alias claude='HTTPS_PROXY=http://127.0.0.1:8118 HTTP_PROXY=http://127.0.0.1:8118 systemd-run --scope -q -p MemoryHigh=1800M -p MemoryMax=2500M -p MemorySwapMax=1G claude'
Второй способ — блок env в файле настроек Claude Code, он действует независимо от оболочки. Выбирайте один и знайте, какой у вас: иначе будете искать, почему прокси «то есть, то нет».
Где алиас не сработает
Алиас живёт только в интерактивной оболочке. Кроны, systemd-юниты и докер-контейнеры его не видят — и это ровно та ситуация, в которой мы потеряли время дважды. Если ИИ-инструмент запускается по расписанию или как служба, переменные нужно прописать явно:
[Service]
Environment=HTTPS_PROXY=http://127.0.0.1:8118
Environment=HTTP_PROXY=http://127.0.0.1:8118
Обратная сторона той же монеты: переменная NO_PROXY=*, прописанная в юните «на всякий случай», молча отключает прокси у всего, что этот юнит запускает. У нас так однажды перестали уходить служебные сообщения.
Шаг 6. Проверка: что должно ответить
Финальный чек-лист: убеждаемся, что прокси для Claude Code и прокси для OpenAI действительно поднялись. Выполняйте на машине с privoxy:
# 1. Выходной адрес — должен быть адресом VPS, а не вашим
curl -x http://127.0.0.1:8118 https://api.ipify.org
# 2. API Anthropic — ждём 405 (это успех, см. начало статьи)
curl -x http://127.0.0.1:8118 -o /dev/null -w '%{http_code}\n' https://api.anthropic.com/v1/messages
# 3. API OpenAI — ждём 401
curl -x http://127.0.0.1:8118 -o /dev/null -w '%{http_code}\n' https://api.openai.com/v1/models
⚠️ Флаг, который делает проверку бессмысленной
Никогда не проверяйте прокси с --noproxy '*'. Этот флаг отключает и тот прокси, который вы указали ключом -x: запрос уходит напрямую, а результат выглядит успешным. Мы попались на это при отладке и полчаса радовались работающему туннелю, которого не было.
Если в оболочке остались унаследованные переменные, снимайте их явно при проверке:
env -u HTTP_PROXY -u HTTPS_PROXY curl -x http://127.0.0.1:8118 https://api.ipify.org
Чтобы прокси не стал выходом для чужого кода
На сервере с сайтом есть уязвимость целого класса: если в PHP найдут SSRF или загрузку файлов, злоумышленник получит готовый выход в интернет с чужого адреса — ваш же прокси. Поэтому мы запретили веб-пользователю ходить на порт privoxy:
-A ufw-before-output -o lo -p tcp --dport 8118 -m owner --uid-owner www-data -j REJECT
Правило ставится до общего разрешения на loopback, иначе не сработает. Смысл: прокси доступен только root-инструментам, а код сайта его не видит вообще. Заодно это отсекает скучный сценарий, когда прокси начинает использовать чужой скрипт, оказавшийся на сервере.
Сколько нагрузки это держит
Цифры из нашего лога, чтобы было с чем сравнивать. Через один такой SOCKS5 на самом дешёвом VPS проходит:
| Дата | Соединений за сутки |
|---|---|
| 16 сентября | 29 395 |
| 17 сентября | 18 268 |
| 18 сентября | 26 618 |
Это трафик Claude Code, двух ИИ-агентов, контейнера с памятью и синхронизации по расписанию — то есть порядка 20–30 тысяч соединений в сутки на одном ядре, без заметной нагрузки. Вывод практический: под задачи разработки нет смысла брать мощный сервер, узким местом станет что угодно раньше, чем прокси.
Отклик до API через европейский VPS у нас 0,2–0,4 секунды. На фоне времени, которое модель думает над ответом, этой задержки не видно.
ChatGPT в браузере: почему сервер здесь не помогает
Возвращаемся к третьей строке первой таблицы. Свой SOCKS5 на VPS полностью решает задачу для API: Claude Code, OpenAI API, ИИ-агенты, скрипты. Но если вы откроете через него веб-интерфейс ChatGPT, вы получите 403 с заголовком cf-mitigated: challenge — проверку Cloudflare.
То есть прокси для ChatGPT в браузере — это отдельная история, и дешёвый VPS её не закрывает. Причина не в стране, а в типе адреса. Датацентровые IP видны как серверные, и защита от ботов относится к ним иначе, чем к адресам живых пользователей. Добавьте сюда, что один адрес VPS обычно уже примелькался: с него ходят и другие клиенты хостера.
Для браузерных сценариев нужен адрес, который выглядит как пользовательский, — мобильный прокси оператора сотовой связи или резидентный. Мобильный вариант устроен так, что за одним адресом сидят десятки живых абонентов, поэтому к нему и относятся как к живому. В наличии сейчас есть зарубежные локации — Эстония, Великобритания, Испания, Латвия, Казахстан; на странице каталога видно остатки по городам. Если нужен адрес, не разделяемый ни с кем, смотрите элитные мобильные.
Когда таких адресов нужно много и постоянно, дешевле поставить свою ферму: об этом отдельно — ProxyFarm.
Что выбрать под свою задачу
| Задача | Что подходит | Почему |
|---|---|---|
| Claude Code, API Anthropic и OpenAI, скрипты | Свой SOCKS5 на зарубежном VPS | API проверку на «живого пользователя» не делает; стоит дёшево, держит десятки тысяч соединений |
| Веб-интерфейс ChatGPT, один аккаунт | Мобильный или резидентный прокси | Датацентровый адрес ловит challenge Cloudflare |
| Несколько аккаунтов ИИ-сервисов | Отдельный мобильный прокси на аккаунт | Общий адрес связывает аккаунты между собой |
| Парсинг с ИИ-обработкой, объёмы | Своя ферма мобильных прокси | На потоке аренда дороже железа |
Частые ошибки
socks5вместоsocks5t— туннель есть, DNS течёт. Проверяется приростом счётчика транзакций.- Проверка с
--noproxy '*'— отключает и проверяемый прокси. Запрос идёт напрямую и «работает». - Белый список в одном месте. Либо конфиг демона, либо файрвол — оба слоя нужны, потому что каждый по отдельности легко потерять.
- Конфиг под другую ветку dante.
socksmethodв версии 1.1.x не примется. Всегдаdanted -V -fперед запуском. - Автозапуск не проверен ребутом. Служба, поднявшаяся раньше сети, падает молча.
- Алиас вместо переменных в юните. Всё, что запускается по расписанию, прокси не увидит.
- Перезапуск privoxy на ходу. Рвёт все текущие соединения: запрос «в моменте» упадёт. Делайте это в паузе.
- Ожидание кода 200. Для API правильный ответ — 401 или 405. Требование «двухсотки» заставляет чинить то, что уже работает.
Частые вопросы
Можно ли обойтись без privoxy и указать SOCKS5 напрямую?
Если инструмент умеет SOCKS — да. Но большинство настраивается через HTTPS_PROXY, где ожидается HTTP-прокси, поэтому переходник оказывается проще, чем подгонка каждого клиента. Плюс адрес апстрима остаётся в одном файле: при смене VPS правите одну строку, а не десять мест.
Подойдут ли бесплатные прокси из списков?
Для ИИ-сервисов — нет. Такой адрес уже засвечен сотнями пользователей, а сам прокси видит весь ваш трафик, включая ключи API в заголовках. Ключ от API — это ваши деньги; отдавать его незнакомому узлу не стоит.
Сколько ждать задержки?
Через европейский VPS у нас 0,2–0,4 секунды до API. Заметно это только на очень частых мелких запросах; в работе Claude Code не ощущается.
Мобильный прокси подойдёт для API?
Подойдёт, но это лишние деньги: API не проверяет «живость» адреса. Мобильные берите под браузерные сценарии, где решает репутация IP.
Чем отличается прокси для ChatGPT от прокси для Claude Code?
Требованиями к адресу. Прокси для Claude Code обслуживает только API, и ему достаточно любого не-российского IP — подойдёт дешёвый VPS. Прокси для ChatGPT в браузере проходит ещё и проверку на «живость» адреса, поэтому датацентровый IP там не годится. Если вы работаете с ChatGPT через API, а не через сайт, разницы нет: хватит той же схемы, что и для Claude Code.
Как понять, что прокси перестал работать?
Симптом — инструмент внезапно получает 403 там, где раньше работал. Первое, что проверять: не сменился ли IP вашей машины. Доступ у нас открыт по белому списку, и смена адреса выключает прокси молча, без сообщений.
Можно ли на том же сервере держать ещё что-то?
Да. У нас на этой машине рядом с SOCKS5 работают другие службы, и прокси им не мешает: он почти не потребляет ресурсов. Разделяйте только порты и следите, чтобы правила файрвола не перетирали друг друга.
Коротко
- API и браузер — разные задачи. Прокси для нейросетей под API и под веб-интерфейс устроены по-разному: для Claude Code и OpenAI API хватает своего SOCKS5 на дешёвом зарубежном VPS; для веб-ChatGPT нужен мобильный или резидентный адрес, иначе Cloudflare выдаёт challenge.
- Правильный ответ проверки — не 200. 405 у Anthropic и 401 у OpenAI означают, что прокси работает.
- Буква
tвsocks5tрешает, течёт ли ваш DNS. Проверяется приростом счётчика транзакций: норма — ноль. - Белый список в двух местах и проверка ребутом. Открытый прокси находят за часы, а служба, стартующая раньше сети, падает молча.
- Прокси — только тем процессам, которым он нужен. Веб-пользователю доступ на порт закрыт: иначе SSRF в сайте превращается в готовый выход в интернет.
Если нужен адрес, который выглядит как пользовательский, — мобильные прокси Frigate Proxy с оплатой в рублях и заменой при проблемах. А про то, как поднять личный туннель для остального трафика, мы писали отдельно: как поднять свой VPN.