Robin Proxy Bridge
WordPress-мост: разворачивает исходящие запросы Robin Image Optimizer на собственный обратный прокси через pre_http_request, не изменяя код плагина
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/boris0024/robin-proxy-bridge/archive/refs/heads/main.zipПлагин WordPress, который разворачивает исходящие запросы Robin Image Optimizer на ваш собственный обратный прокси.
Нужен в одной ситуации: плагин установлен, настроен и работает, но его API (dashboard.robinoptimizer.com) недоступно с вашего сервера. Картинки не жмутся, WebP не создаётся, а в логах плагина висят неудачные запросы.
Обычные пути решения плохие: форкать чужой плагин больно на каждом обновлении, менять оптимизатор дорого, если библиотека уже обработана наполовину. Этот мост не трогает код Robin вообще.
Как это работает
WordPress пропускает все исходящие HTTP-запросы через свой HTTP API, а тот даёт фильтр pre_http_request, который срабатывает до отправки. Плагин ловит запрос, подменяет адрес и выполняет его сам.
Три точки перехвата:
pre_http_request- запрос к API оптимизатора разворачивается на прокси.http_response- в теле ответа переписываются ссылки на скачивание результата. Бесплатный тариф Robin отдаёт JSON со ссылкой на готовый файл, и без подмены плагин пошёл бы за ним напрямую, снова в недоступный хост.http_api_curl- точечно отключает проверку сертификата, если прокси работает на самоподписанном (по умолчанию проверка включена).
Приём универсальный. Замените хост через фильтр rpb_target_host, и тот же мост будет работать для любого плагина, который ходит в недоступный сервис через WP HTTP API:
add_filter( 'rpb_target_host', function () {
return 'api.example-service.com';
} );
Почему не WP_PROXY_HOST
В WordPress есть встроенная поддержка прокси через константы в wp-config.php. Она не подходит по трём причинам:
- через прокси пойдут все запросы WordPress: обновления ядра, тем, других плагинов, а
WP_PROXY_BYPASS_HOSTSэто список исключений, а не белый список; - нужен полноценный прямой прокси (squid, 3proxy), то есть отдельный демон, который придётся закрывать от посторонних;
- здесь используется обратный прокси на nginx, который умеет ходить ровно к одному хосту и прячется за секретным путём.
Установка
1. Прокси на сервере, с которого API доступно
Возьмите nginx/robin-proxy.conf, замените плейсхолдеры и подключите:
cp nginx/robin-proxy.conf /etc/nginx/sites-available/robin-proxy
# сгенерируйте свой секретный путь:
echo "rp_$(openssl rand -hex 16)"
# впишите его, IP вашего сайта в allow и пути к сертификатам
ln -s /etc/nginx/sites-available/robin-proxy /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Строку limit_req_zone нужно положить в nginx.conf, в блок http:
limit_req_zone $binary_remote_addr zone=robin_proxy_limit:1m rate=10r/s;
2. Плагин на сайте
Скопируйте папку в wp-content/plugins/robin-proxy-bridge, активируйте, откройте Настройки → Robin Proxy Bridge:
- включите прокси;
- впишите полный адрес вместе с секретным путём:
https://proxy.example.com:8443/rp_ваш_секрет; - оставьте проверку сертификата включённой, если у прокси нормальный сертификат;
- нажмите «Проверить прокси».
Ответ с любым кодом кроме 404 означает, что туннель работает. Код 404 обычно значит, что секретный путь в настройках не совпадает с location в nginx.
Обновление с версии 1.0.0
В 1.0.0 проверка TLS-сертификата была отключена жёстко, в 1.1.0 она стала настройкой и включена по умолчанию.
Если ваш прокси работает на самоподписанном сертификате, сразу после обновления запросы начнут падать:
cURL error 60: SSL certificate problem: self-signed certificate
Лечится одним из двух способов:
- выпустить нормальный сертификат Let's Encrypt на домен прокси (правильный путь);
- снять галку «Проверять сертификат» в настройках плагина.
Безопасность
Прочитайте, прежде чем поднимать это в продакшене.
- Закрывайте прокси по IP.
allow <IP сайта>; deny all;в конфиге это главный рубеж. Открытый порт находят сканеры: на боевом сервере за сутки набегает больше сотни посторонних запросов. - Секретный путь это секрет. Он попадает в настройки WordPress, в бэкапы базы и, что неприятнее, в логи самого Robin Image Optimizer открытым текстом, потому что тот пишет полный URL скачивания. Кто получил доступ к логам сайта, получил доступ к прокси.
- Не выключайте проверку сертификата без нужды. Через прокси идут файлы, а на платном тарифе ещё и ключ лицензии в заголовке
Authorization. Лучше выпустить Let's Encrypt на домен, чем жить с самоподписанным сертификатом. - Ротируйте секретный путь, если он мог утечь: поменяйте
locationв nginx и адрес в настройках плагина.
Проверено на
| Компонент | Версия |
|---|---|
| WordPress | 6.7.5 |
| Robin Image Optimizer | 2.0.5 |
| PHP | 8.3.31 |
| nginx | 1.22.1 и 1.31.1 |
Версия 1.1.0 проверена на боевой связке с реальным прокси: перехват запроса к API отдаёт HTTP 200 через прокси, ссылка на скачивание в ответе переписывается корректно, запросы к посторонним хостам (api.wordpress.org) остаются нетронутыми, а с включённой проверкой самоподписанного сертификата запрос ожидаемо падает с cURL error 60.
Результат на двух боевых сайтах: 7 684 изображения сконвертированы в WebP, 1 309.7 МБ оригиналов против 443.2 МБ WebP, то есть минус 66% веса картинок.
Что этот плагин не делает
Он не отдаёт WebP посетителям. Отдачей занимается сам Robin Image Optimizer: по умолчанию он подставляет теги <picture> в HTML через выходной буфер PHP. Режим отдачи средствами сервера у Robin реализован только для Apache через .htaccess, на nginx он в настройках недоступен. Этот мост решает другую задачу: доставить запрос до API, чтобы WebP вообще создался.
Лицензия
GPL-2.0-or-later, как и сам WordPress. См. LICENSE.
Проект не связан с разработчиками Robin Image Optimizer и не аффилирован с ними. Robin Image Optimizer распространяется по своей лицензии, его код в этот репозиторий не входит.