add: Прозрачный прокси контейнера через Shadowsocks и tun2socks (fin)

This commit is contained in:
2026-03-06 19:46:00 +03:00
parent e63a980b2b
commit f2f6bb65d2

View File

@@ -1,13 +1,13 @@
# Прозрачный прокси контейнера через Shadowsocks и tun2socks # Прозрачный прокси контейнера через Shadowsocks и tun2socks
У меня есть Docker-контейнер Audiobookshelf, в котором я слушаю аудио-книги и подкасты. Он сам скачивает подкасты У меня есть Docker-контейнер Audiobookshelf, в котором я слушаю аудиокниги и подкасты. Он сам скачивает подкасты
из интернета и это очень удобно (все нужные мне подкасты в одном месте). Работал контейнер на домашнем NAS Synology из интернета, и это очень удобно (все нужные мне подкасты в одном месте). Работал контейнер на домашнем NAS Synology
(в нем есть Docker Station с веб-интерфейсов). Книг у меня в "библиотеке" уже более тысячи, а подкастов и того больше, (в нем есть Docker Station с веб-интерфейсом). Книг у меня в "библиотеке" уже более тысячи, а подкастов и того больше,
так что домашний NAS с доступом из интернет -- идеальное решение. так что домашний NAS с доступом из интернета идеальное решение.
Все отлично работало и подкасты обновлялись, пока не настало DPI. Где-то в первой декаде января 2026 подкасты перестали Все отлично работало и подкасты обновлялись, пока не настал DPI. Где-то в первой декаде января 2026 года подкасты перестали
обновляться. Проверки показали, что это из-за блокировок на уровне провайдера. Mp3-файлы файлы размещены на обновляться. Проверки показали, что это из-за блокировок на уровне провайдера. Mp3-файлы размещены на
DigitalOcean, и заблокирован именно он. Audiobookshelf получает ссылки через RSS-фиды, видит новые эпизоды, и зависает DigitalOcean, и заблокирован именно он. Audiobookshelf получает ссылки через RSS-фиды, видит новые эпизоды и зависает
при скачивании. при скачивании.
## Как решить проблему DPI? ## Как решить проблему DPI?
@@ -35,22 +35,22 @@
Контейнер Audiobookshelf на Synology работает по 8000 порту. Nginx на Orange Pi 5 Plus проксирует на этот порт на Контейнер Audiobookshelf на Synology работает по 8000 порту. Nginx на Orange Pi 5 Plus проксирует на этот порт на
IP-адресе Synology, добавляет SSL и обновляет сертификат Let's Encrypt (на самом деле у меня для этой цели используется IP-адресе Synology, добавляет SSL и обновляет сертификат Let's Encrypt (на самом деле у меня для этой цели используется
Traefik на k3s и все еще проходдит через VIP-адрес Keepalive, но для простоты я опускаю эти детали). На роутере Traefik на k3s и все еще проходит через VIP-адрес Keepalive, но для простоты я опускаю эти детали). На роутере
настройка проброс 443-порта на Orange Pi. Внешний DNS настроен на IP-адрес роутера (A- и AAAA-записи) и так я могу настроен проброс 443-порта на Orange Pi. Внешний DNS настроен на IP-адрес роутера (A- и AAAA-записи), и так я могу
слушать подкасты из любой точки мира. слушать подкасты из любой точки мира.
Скачивание подкастов внутри Audiobookshelf идет напрямую. Контейнер сразу обращается к Роутеру и пытается скачать Скачивание подкастов внутри Audiobookshelf идет напрямую. Контейнер сразу обращается к Роутеру и пытается скачать
mp3-файл. И это ему не удаётся из-за DPI. mp3-файл. И это ему не удаётся из-за DPI.
### Новая схема ### Новая схема
К счастью, проверки показали, что у провайдеров (даже у Российских) нет блокировок DigitalOcean. А значит эпизоды К счастью, проверки показали, что у провайдеров (даже у российских) нет блокировок DigitalOcean. А значит, эпизоды
подкастов можно скачать на VPS/VDS виртуалке, и нужно только настроить Audiobookshelf так, чтобы он скачивал mp3-файлы подкастов можно скачать на VPS/VDS-виртуалке, и нужно только настроить Audiobookshelf так, чтобы он скачивал mp3-файлы
через прокси. При этом прослушивание книг и подкастов должно работать по старой схеме, без изменений. через прокси. При этом прослушивание книг и подкастов должно работать по старой схеме, без изменений.
Как-то так: Как-то так:
```text ```text
Интернет для upload Интернет для прослушивания Интернет для скачивания Интернет для прослушивания
▲ ▲ ▲ ▲
│ │ │ │
│ │ │ │
@@ -79,19 +79,19 @@ Traefik на k3s и все еще проходдит через VIP-адрес K
Почему так сложно? Почему так сложно?
- Во-первых, на VPS/VDS, где я держу свои проекты, уже был настроен Shadowsocks-сервер (Outline), Не для обхода - **Во-первых**, на VPS/VDS, где я держу свои проекты, уже был настроен Shadowsocks-сервер (Outline), не для обхода
блокировок, а для безопасного доступа и администрирования (а еще для того чтоб посещать Госуслуги и другие ресурсы, блокировок, а для безопасного доступа и администрирования (а еще для того, чтобы посещать Госуслуги и другие ресурсы,
находясь в поездках за границей). Поэтому было логично использовать его. находясь в поездках за границей). Поэтому было логично использовать его.
- Во-вторых, для Docker не существует полноценного VPN-клиента Shadowsocks. Есть только прокси-клиенты (ss-local), - **Во-вторы**х, для Docker не существует полноценного VPN-клиента Shadowsocks. Есть только прокси-клиенты (ss-local),
которые предоставляют SOCKS5 интерфейс. которые предоставляют SOCKS5-интерфейс.
- При этом, и это в-третьих, Audiobookshelf не умеет работать с SOCKS5. Ему нужен настоящий HTTP, причем из-за - При этом и это **в-третьих** Audiobookshelf не умеет работать с SOCKS5. Ему нужен настоящий HTTP, причем из-за
встроенной в Audiobookshelf защиты от SSRF атак он не может работать даже с HTTP-прокси, который находится встроенной в Audiobookshelf защиты от SSRF-атак он не может работать даже с HTTP-прокси, который находится
в Docker сети (например, Privoxy). Ему нужно сделать прозрачную сеть через TUN интерфейс -- тогда он будет в Docker-сети (например, Privoxy). Ему нужно сделать прозрачную сеть через TUN-интерфейс тогда он будет
доволен. доволен.
- Для этого, в-четвертых, нужно сделать так, чтобы весь трафик контейнера Audiobookshelf автоматически - Для этого, **в-четвертых**, нужно сделать так, чтобы весь трафик контейнера Audiobookshelf автоматически
шел через единственный контейнер (tun2socks), который будет форвардить и http, и https через Shadowsocks (для шел через единственный контейнер (tun2socks), который будет форвардить и http, и https через Shadowsocks (для
скачивания подкастов) и отдавать http-трафик на порт 8000 для прослушивания через Nginx. Именно такая схема скачивания подкастов) и отдавать http-трафик на порт 8000 для прослушивания через Nginx. Именно такая схема
не будет ломать работу SSRF-фильтра и защитит от этого тип атаки (_можно было, конечно, откатить Audiobookshelf не будет ломать работу SSRF-фильтра и защитит от этого типа атаки (_можно было, конечно, откатить Audiobookshelf
до древней версии 2.6.0, где дыра SSRF еще была, но это не самое безопасное решение, да и на DockerHub уже нет до древней версии 2.6.0, где дыра SSRF еще была, но это не самое безопасное решение, да и на DockerHub уже нет
этой версии_). этой версии_).
@@ -114,14 +114,14 @@ services: audiobookshelf:
- TZ=Europe/Moscow - TZ=Europe/Moscow
``` ```
Тут, вроде все просто. На Synology есть папка `/volume1/music/` уже с завода. В ней я создал папки `_podcasts` Тут, вроде, всё просто. На Synology есть папка `/volume1/music/` уже с завода. В ней я создал папки `_podcasts`
и `_audio_books` для хранения книг и подкастов, и смонтировал эти папки в контейнер. Также добавил папки `config` и `_audio_books` для хранения книг и подкастов и смонтировал эти папки в контейнер. Также добавил папки `config`
и `metadata` для хранения конфигурации и метаданных. Эти папки создадются при первом запуске контейнера, и будут и `metadata` для хранения конфигурации и метаданных. Эти папки создаются при первом запуске контейнера и будут
расположены рядом `compose.yml` (в каталоге `/volume1/docker/audiobookshelf/`... папка `/volume1/docker/` тоже расположены рядом с `compose.yml` (в каталоге `/volume1/docker/audiobookshelf/`). Папка `/volume1/docker/` тоже
будет создана при установке приложения Docker Station на Synology... нам нужно только создать каталог `audiobookshelf/` будет создана при установке приложения Docker Station на Synology; нам нужно только создать каталог `audiobookshelf/`
и и выбрать ее при создании проекта в Docker Station). и выбрать его при создании проекта в Docker Station.
Порт 8000 проброшен наружу и Nginx на хосте Orange Pi 5 Plus проксирует на этот порт, добавляет SSL и так далее. Порт 8000 проброшен наружу, и Nginx на хосте Orange Pi 5 Plus проксирует на этот порт, добавляет SSL и так далее.
### Новая схема и манифест для Docker Station ### Новая схема и манифест для Docker Station
@@ -145,7 +145,7 @@ services:
-l 1080 -l 1080
-b 0.0.0.0 -b 0.0.0.0
# [2] Privoxy — HTTP-прокси для Node.js, форвардит через ss-ru # [2] tun2socks — прозрачный прокси для Audiobookshelf, форвардит через ss-ru
tun2socks: tun2socks:
image: xjasonlyu/tun2socks image: xjasonlyu/tun2socks
container_name: tun2socks container_name: tun2socks
@@ -162,7 +162,7 @@ services:
depends_on: depends_on:
- ss-ru - ss-ru
# [3] Audiobookshelf, использующий Privoxy для доступа к интернету # [3] Audiobookshelf, использующий сетевой стек tun2socks
audiobookshelf: audiobookshelf:
image: advplyr/audiobookshelf:latest image: advplyr/audiobookshelf:latest
container_name: audiobookshelf container_name: audiobookshelf
@@ -182,25 +182,25 @@ services:
Что тут происходит: Что тут происходит:
*Первым стартует** контейнер `ss-ru`. Он ни от кого не зависит. Он подключается к моему Outline-серверу и предоставляет **Первым стартует** контейнер `ss-ru`. Он ни от кого не зависит. Он подключается к моему Outline-серверу и предоставляет
SOCKS5-прокси на порту `1080`. SOCKS5-прокси на порту `1080`.
Где брать параметры для подключения к Outline/VPS? В панели Outline Manager "Add new Key". Она предоставит строку вида: Где брать параметры для подключения к Outline/VPS? В панели Outline Manager "Add new Key". Он выдаст строку вида:
`ss://[зашифрованный-base64-ключ--метод-шифрования:пароль]@[IP-адрес Outline/VPS]:[порт Outline/VPS]/?outline=1`. `ss://[зашифрованный-base64-ключ--метод-шифрования:пароль]@[IP-адрес Outline/VPS]:[порт Outline/VPS]/?outline=1`.
Параметры `[IP-адрес Outline/VPS]` и `[порт Outline/VPS]` нужно взять непосредственно из этой строки. Метод шифрования Параметры `[IP-адрес Outline/VPS]` и `[порт Outline/VPS]` нужно взять непосредственно из этой строки. Метод шифрования
и пароль нужно расшифровать из первой части строки (часть строки между `ss://` и до `@`). Например, командой и пароль нужно расшифровать из первой части строки (часть строки между `ss://` и `@`). Например, командой
в терминале: в терминале:
```shell ```shell
echo "Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpDYVF6OERMRDVHd09meTRvVVk1TmxK" | base64 -d echo "Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpDYVF6OERMRDVHd09meTRvVVk1TmxK" | base64 -d
``` ```
Получим строку вида `chacha20-ietf-poly1305:пароль`. Таким образом `[метод шифрования]` — это `chacha20-ietf-poly1305`, Получим строку вида `chacha20-ietf-poly1305:пароль`. Таким образом, `[метод шифрования]` — это `chacha20-ietf-poly1305`,
а `[пароль Outline/VPS] — это `пароль`. а `[пароль Outline/VPS]` — это `пароль`.
**Вторым стартует** контейнер `tun2socks`. Он зависит от `ss-ru`, так что гарантированно запустится после него. Он **Вторым стартует** контейнер `tun2socks`. Он зависит от `ss-ru`, так что гарантированно запустится после него. Он
использует `ss-ru` как SOCKS5-прокси и создает TUN-интерфейс `tun0` внутри контейнера. Так же он предоставляет использует `ss-ru` как SOCKS5-прокси и создает TUN-интерфейс `tun0` внутри контейнера. Также он предоставляет
HTTP-интерфейс на порту 80 внутри нашего проекта Docker Station (с него будет отвечать Audiobookshelf) который HTTP-интерфейс на порту 80 внутри нашего проекта Docker Station (с него будет отвечать Audiobookshelf), который
проброшен наружу как 8000 (его отпроксирует Nginx на хосте Orange Pi 5 Plus). проброшен наружу как 8000 (его будет проксировать Nginx на хосте Orange Pi 5 Plus).
Контейнер tun2socks использует системный TUN-интерфейс Synology (`/dev/net/tun`). Поэтому контейнеру нужны права Контейнер tun2socks использует системный TUN-интерфейс Synology (`/dev/net/tun`). Поэтому контейнеру нужны права
и доступ к этому устройству. Это достигается через: и доступ к этому устройству. Это достигается через:
@@ -211,11 +211,11 @@ services:
- /dev/net/tun - /dev/net/tun
``` ```
На Synology (да и многих Linux) TUN-интерфейс `/dev/net/tun` обычно закрыт. Нужно будет разрешить доступ к нему: На Synology (да и на многих Linux-системах) TUN-интерфейс `/dev/net/tun` обычно закрыт. Нужно будет разрешить доступ к нему:
```bash ```bash
# Проверяем, что TUN доступен # Проверяем, что TUN доступен
ls /dev/net/tun ls /dev/net/tun
# Если выдаёт "/dev/net/tun: no such device", то нужно создать устройство # Если команда выдаёт "/dev/net/tun: no such device", то нужно загрузить модуль ядра
sudo modprobe tun sudo modprobe tun
# И снова проверить, что устройство появилось # И снова проверить, что устройство появилось
ls /dev/net/tun ls /dev/net/tun
@@ -224,20 +224,20 @@ ls /dev/net/tun
| Заметим | | Заметим |
| ------- | | ------- |
| Я пробовал други решения: (1) `Privoxy` -- Проблемы: axios внутри Audiobookshelf плохо работает с proxy, ломаются редиректы,SSRF фильтр, сами RSS загружаются, но SSRF будет блокировать запросы к iTunes, а, значит, не будут получаться метаданные, а без метаданных и mp3-файлы не скачиваются. (2) `redsocks` -- Проблемы: нестабильный iptables redirect (на Synology это вообще не работает, похоже), падение самого redsocks, сложная настройка NAT внутри Docker. | Я пробовал другие решения: (1) `Privoxy` — Проблемы: axios внутри Audiobookshelf плохо работает с прокси, ломаются редиректы, SSRF-фильтр; сами RSS загружаются, но SSRF будет блокировать запросы к iTunes, а значит, не будут получаться метаданные, а без метаданных и mp3-файлы не скачиваются. (2) `redsocks` — Проблемы: нестабильный iptables redirect (на Synology это вообще не работает, похоже), падение самого redsocks, сложная настройка NAT внутри Docker.
**Третьим стартует** контейнер `audiobookshelf`. В нём почти все по старому. Но теперь он зависит от `tun2socks`, **Третьим стартует** контейнер `audiobookshelf`. В нём почти всё по-старому. Но теперь он зависит от `tun2socks`,
так что гарантированно запустится после него. Кроме того, у него нет проброса портов `8000:80` (они у нас теперь так что гарантированно запустится после него. Кроме того, у него нет проброса портов `8000:80` (они у нас теперь
в контейнере tun2socks). Вместо этого у него `network_mode: "service:tun2socks"`. В целом, `network_mode: в контейнере tun2socks). Вместо этого у него `network_mode: "service:tun2socks"`. В целом, `network_mode:
"service:...` -- это мощная, но специфичная функция Docker, которая 'склеивает' сетевые стеки контейнеров в один, "service:..."` — это мощная, но специфичная функция Docker, которая 'склеивает' сетевые стеки контейнеров в один,
а это значит, что контейнер `audiobookshelf` будет использовать сетевой стек контейнера `tun2socks` и в результате а это значит, что контейнер `audiobookshelf` будет использовать сетевой стек контейнера `tun2socks` и в результате
весь трафик будет идти через TUN-интерфейс. Дальше уже сам `tun2socks` определит что с ним делать. Если трафик пришел снаружи, с порта 8000, то он попадёт в Audiobookshelf, как и раньше, а если же сам Audiobookshelf начнет что-то весь трафик будет идти через TUN-интерфейс. Дальше уже сам `tun2socks` определит, что с ним делать. Если трафик пришел снаружи, с порта 8000, то он попадёт в Audiobookshelf, как и раньше, а если же сам Audiobookshelf начнет что-то
скачивать, то запрос уйдет через TUN-интерфейс, попадет в `tun2socks`, который отфорвардит его через SOCKS5-прокси скачивать, то запрос уйдет через TUN-интерфейс, попадет в `tun2socks`, который перенаправит его через SOCKS5-прокси
`ss-ru` на Outline/VPS (на внешнем хостинге). `ss-ru` на Outline/VPS (на внешнем хостинге).
## Запуск и проверка ## Запуск и проверка
Конечно, первым делом проверить в интерфейсе Docker Station, что проект "зелененький" и все контейнеры тоже Конечно, первым делом нужно проверить в интерфейсе Docker Station, что проект "зелененький" и все контейнеры тоже
"зелененькие". Ну или выполнить: "зелененькие". Ну или выполнить:
```bash ```bash
sudo docker ps sudo docker ps
@@ -251,76 +251,71 @@ CONTAINER ID IMAGE COMMAND CREATED
3bdb3269ed77 shadowsocks/shadowsocks-libev "ss-local -s 90.156.…" 16s ago Up 16s ss-ru 3bdb3269ed77 shadowsocks/shadowsocks-libev "ss-local -s 90.156.…" 16s ago Up 16s ss-ru
``` ```
Для проверки, что тоннель работает и подкасты скачиваются выполним в терминале на Synology: Для проверки того, что тоннель работает и подкасты скачиваются, выполним в терминале на Synology:
```bash ```bash
sudo docker exec -it audiobookshelf sh -c " node -e \"const https=require('https');const fs=require('fs');const file=fs.createWriteStream('/podcasts/test.mp3');https.get('https://aerostats.getmobileup.com/music/1074.mp3',res=>{res.pipe(file);file.on('finish',()=>console.log('Done'))})\"" sudo docker exec -it audiobookshelf sh -c " node -e \"const https=require('https');const fs=require('fs');const file=fs.createWriteStream('/podcasts/test.mp3');https.get('https://aerostats.getmobileup.com/music/1074.mp3',res=>{res.pipe(file);file.on('finish',()=>console.log('Done'))})\""
``` ```
Audiobookshelf работает на Node.js, а внутри контейнера нет ни `curl`. ни `wget`. Так что придется запустить такой Audiobookshelf работает на Node.js, а внутри контейнера нет ни `curl`, ни `wget`. Так что придется запустить такой
заковыристый js-скрипт для проверки скачивания файла. заковыристый js-скрипт для проверки скачивания файла.
В результате должен получим `test.mp3` в папке `/podcasts/` (а она у нас снаружи контейнера В результате мы получим `test.mp3` в папке `/podcasts/` (а она у нас снаружи контейнера
в `/volume1/music/_podcasts`). Это выпуск №1074 подкаста "Аэростат" с альбомом Аквариума "Странные Новости с в `/volume1/music/_podcasts`). Это выпуск №1074 подкаста "Аэростат" с альбомом Аквариума "Странные Новости с
Далёкой Звезды" (2026 год, очень рекомендую послушать). Этот подкаст размещен на DigitalOcean, так что если Далёкой Звезды" (2024 год, очень рекомендую послушать). Этот подкаст размещен на DigitalOcean, так что если
он скачался, значит туннель работает и обход блокировок провайдера сработал. он скачался, значит туннель работает и обход блокировок провайдера сработал.
Проверить что метаданные из iTunes тоже подгружаются, можно проверить только настроив автообновление подкастов Проверить, что метаданные из iTunes тоже подгружаются, можно, только настроив автообновление подкастов
в интерфейсе Audiobookshelf (например через ять минут). К получение метаданных происходит "под капотом" в интерфейсе Audiobookshelf (например, через пять минут). Но получение метаданных происходит "под капотом",
и иначе никак не диагностируется. и иначе это никак не диагностировать.
Должно все работать. Но если не работает, то "курите логи" контейнера `audiobookshelf`: Должно всё работать. Но если не работает, то "курите логи" контейнера `audiobookshelf`:
```bash ```bash
sudo docker logs audiobookshelf --tail 100 sudo docker logs audiobookshelf --tail 100
``` ```
...и Google и ИИ-ассистенты в помощь. Node.js -- это не самая простая среда для отладки. ...и Google и ИИ-ассистенты в помощь. Node.js это не самая простая среда для отладки.
## P.S. Важное замечание о защите Audiobookshelf от SSRF ## P.S. Важное замечание о защите Audiobookshelf от SSRF
Во время настройки, в логах, можно столкнуться с ошибкой вида: `Call to 172.25.0.3 is blocked` или `invalid feed payload`. Во время настройки в логах можно столкнуться с ошибкой вида: `Call to 172.25.0.3 is blocked` или `invalid feed payload`.
Это не ошибка сети и не проблема RSS. Это встроенная защита Audiobookshelf от SSRF атак. Это не ошибка сети и не проблема RSS. Это встроенная защита Audiobookshelf от SSRF-атак.
### Что такое SSRF ### Что такое SSRF
SSRF (Server Side Request Forgery) — это тип атаки, когда сервер заставляют делать запросы во внутреннюю сеть. SSRF (Server Side Request Forgery) — это тип атаки, когда сервер заставляют делать запросы в свою внутреннюю сеть.
Например злоумышленник может подложить RSS-фид c ссылкой на внутренний сервис. Например: `http://127.0.0.1:8080/admin` Например, злоумышленник может подложить RSS-фид со ссылкой на внутренний сервис. Например: `http://127.0.0.1:8080/admin`
или `http://172.25.0.3:5000`. или `http://172.25.0.3:5000`.
Если сервер загрузит такой URL, атакующий потенциально сможет: Если сервер загрузит такой URL, атакующий потенциально сможет:
- читать внутренние сервисы - читать данные внутренних сервисов
- получать токены - получать внутренние токены авторизации
- обращаться к Docker API - обращаться к Docker API
- сканировать внутреннюю сеть - сканировать внутреннюю сеть
Поэтому многие современные приложения блокируют такие запросы. И Audiobookshelf не исключение. Поэтому многие современные приложения блокируют такие запросы. И Audiobookshelf не исключение.
Audiobookshelf использует библиотеку `ssrf-req-filter`. Она проверяет IP адрес, в который резолвится домен, и блокирует некоторые диапазоны: Audiobookshelf использует библиотеку `ssrf-req-filter`. Она проверяет IP-адрес, в который разрешается (резолвится) домен, и блокирует некоторые диапазоны:
- `127.0.0.0/8` - `127.0.0.0/8`
- `10.0.0.0/8` - `10.0.0.0/8`
- `172.16.0.0/12` - `172.16.0.0/12`
- `192.168.0.0/16` - `192.168.0.0/16`
- `169.254.0.0/16` - `169.254.0.0/16`
То есть любые внутренние адреса. Включая адреса Docker сети. То есть любые внутренние адреса, включая адреса Docker-сети.
Когда использовалась схема `Audiobookshelf → HTTP Proxy → Shadowsocks` то HTTP proxy находился в Docker сети. Например: Когда использовалась схема `Audiobookshelf → HTTP Proxy → Shadowsocks`, то HTTP-прокси находился в Docker-сети. Например:
`privoxy:8118` или `redsocks:12345` `privoxy:8118` или `redsocks:12345`.
После DNS-резолва запрос фактически отправлялся на адрес контейнера прокси внутри Docker сети. Например, `172.25.0.3`. И После DNS-разрешения (резолва) запрос фактически отправлялся на адрес контейнера прокси внутри Docker-сети. Например, `172.25.0.3`. И SSRF-фильтр Audiobookshelf это видел и блокировал запрос. Именно поэтому в логах появлялось: `Call to 172.25.0.3 is blocked`.
SSRF-фильтр Audiobookshelf это видел и блокировал запрос. Именно поэтому в логах появлялось: `Call to 172.25.0.3
is blocked`.
### Почему HTTP_PROXY часто ломает Audiobookshelf ### Почему HTTP_PROXY часто ломает Audiobookshelf
Audiobookshelf использует библиотеку axios. А он: Audiobookshelf использует библиотеку axios. А он:
- плохо работает с редиректами через прокси - плохо работает с редиректами через прокси
- иногда резолвит DNS на стороне прокси - иногда разрешает (резолвит) DNS на стороне прокси
- иногда резолвит DNS локально - иногда разрешает (резолвит) DNS локально
В результате: часть запросов проходит; часть падает; RSS может читаться, но mp3 не скачиваются и так далее.
Опытным путем я определил, что наиболее надёжный способ — сетевой туннель (`tun2socks`), при котором приложение не знает о прокси вообще.
В результате: часть запросов проходит, часть падает, RSS может читаться, но mp3 не скачиваются и так далее.
Опытным путем я определил, что наиболее надёжный способ — сетевой туннель (`tun2socks`), при котором приложение не знает о проксировании вообще.