diff --git a/docker/docker-proxy-container-via-shadowsocks-and-tun2socks.md b/docker/docker-proxy-container-via-shadowsocks-and-tun2socks.md index a37f354..de359ec 100644 --- a/docker/docker-proxy-container-via-shadowsocks-and-tun2socks.md +++ b/docker/docker-proxy-container-via-shadowsocks-and-tun2socks.md @@ -228,12 +228,12 @@ ls /dev/net/tun **Третьим стартует** контейнер `audiobookshelf`. В нём почти все по старому. Но теперь он зависит от `tun2socks`, так что гарантированно запустится после него. Кроме того, у него нет проброса портов `8000:80` (они у нас теперь - в контейнере tun2socks). Вместо этого у него `network_mode: "service:tun2socks"`. Это значит, что он будет - использовать сетевой стек контейнера tun2socks. В результате весь его трафик будет идти через TUN-интерфейс - Дальше уже `tun2socks` определит что с ним делать. Если трафик пришел снаружи, с порта 8000, то он попадёт - в Audiobookshelf, как и раньше. Если же сам Audiobookshelf начнет что-то скачивать, то запрос уйдет через - TUN-интерфейс, попадет в `tun2socks`, который отфорвардит его через SOCKS5-прокси `ss-ru` на Outline/VPS - (на внешнем хостинге). + в контейнере tun2socks). Вместо этого у него `network_mode: "service:tun2socks"`. В целом, `network_mode: + "service:...` -- это мощная, но специфичная функция Docker, которая 'склеивает' сетевые стеки контейнеров в один, + а это значит, что контейнер `audiobookshelf` будет использовать сетевой стек контейнера `tun2socks` и в результате + весь трафик будет идти через TUN-интерфейс. Дальше уже сам `tun2socks` определит что с ним делать. Если трафик пришел снаружи, с порта 8000, то он попадёт в Audiobookshelf, как и раньше, а если же сам Audiobookshelf начнет что-то + скачивать, то запрос уйдет через TUN-интерфейс, попадет в `tun2socks`, который отфорвардит его через SOCKS5-прокси + `ss-ru` на Outline/VPS (на внешнем хостинге). ## Запуск и проверка @@ -275,3 +275,52 @@ sudo docker logs audiobookshelf --tail 100 ...и Google и ИИ-ассистенты в помощь. Node.js -- это не самая простая среда для отладки. + +## P.S. Важное замечание о защите Audiobookshelf от SSRF + +Во время настройки, в логах, можно столкнуться с ошибкой вида: `Call to 172.25.0.3 is blocked` или `invalid feed payload`. +Это не ошибка сети и не проблема RSS. Это встроенная защита Audiobookshelf от SSRF атак. + +### Что такое SSRF + +SSRF (Server Side Request Forgery) — это тип атаки, когда сервер заставляют делать запросы во внутреннюю сеть. +Например злоумышленник может подложить RSS-фид c ссылкой на внутренний сервис. Например: `http://127.0.0.1:8080/admin` +или `http://172.25.0.3:5000`. + +Если сервер загрузит такой URL, атакующий потенциально сможет: + - читать внутренние сервисы + - получать токены + - обращаться к Docker API + - сканировать внутреннюю сеть + +Поэтому многие современные приложения блокируют такие запросы. И Audiobookshelf не исключение. + +Audiobookshelf использует библиотеку `ssrf-req-filter`. Она проверяет IP адрес, в который резолвится домен, и блокирует некоторые диапазоны: + - `127.0.0.0/8` + - `10.0.0.0/8` + - `172.16.0.0/12` + - `192.168.0.0/16` + - `169.254.0.0/16` + +То есть любые внутренние адреса. Включая адреса Docker сети. + +Когда использовалась схема `Audiobookshelf → HTTP Proxy → Shadowsocks` то HTTP proxy находился в Docker сети. Например: +`privoxy:8118` или `redsocks:12345` + +После DNS-резолва запрос фактически отправлялся на адрес контейнера прокси внутри Docker сети. Например, `172.25.0.3`. И +SSRF-фильтр Audiobookshelf это видел и блокировал запрос. Именно поэтому в логах появлялось: `Call to 172.25.0.3 +is blocked`. + +### Почему HTTP_PROXY часто ломает Audiobookshelf + +Audiobookshelf использует библиотеку axios. А он: + - плохо работает с редиректами через прокси + - иногда резолвит DNS на стороне прокси + - иногда резолвит DNS локально + +В результате: часть запросов проходит; часть падает; RSS может читаться, но mp3 не скачиваются и так далее. + +Опытным путем я определил, что наиболее надёжный способ — сетевой туннель (`tun2socks`), при котором приложение не знает о прокси вообще. + + +