Не уверен, насколько это имеет прямое отношение к вопросу ОП, но вот несколько фрагментов из моей конфигурации.
Это основы моего блока для обслуживания потоков клиентов через SSL на порту 443.
В первом блоке местоположения любые запросы с URI, отличным от /ogg, /128, /192 или /320, переписываются, чтобы предотвратить доступ клиентов к каким-либо выходным данным сервера Icecast, кроме самих потоков.
server {
listen 443 ssl http2;
server_name stream.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
rewrite ~*(ogg) https://stream.example.com/ogg last;
rewrite ~*([0-1][0-5]\d) https://stream.example.com/128 last;
rewrite ~*(?|([1][6-9]\d)|([2]\d\d)) https://stream.example.com/192 last;
rewrite ~*([3-9]\d\d) https://stream.example.com/320 break;
return https://stream.example.com/320;
}
location ~ ^/(ogg|128|192|320)$ {
proxy_bind $remote_addr transparent;
set $stream_url http://192.168.100.100:8900/$1;
types { }
default_type audio/mpeg;
proxy_pass_request_headers on;
proxy_set_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_set_header Range bytes=0-;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
tcp_nodelay on;
proxy_pass $stream_url;
}
}
Установка proxy_bind
с флагом transparent
:
позволяет исходящим подключениям к проксируемому серверу исходить с нелокального IP-адреса, например, с реального IP-адреса клиента
Это решает проблемы с локальными IP-адресами в ваших журналах / статистике вместо IP-адресов клиентов, чтобы это работало, вам также необходимо перенастроить таблицы маршрутизации ядра, чтобы захватывать ответы, отправленные с вышестоящего сервера, и перенаправлять их обратно в Nginx.
Для этого требуется root-доступ и разумное понимание сетевой конфигурации Linux, что, я понимаю, есть не у всех. Я также ценю, что не все, кто использует Icecast и может захотеть использовать обратный прокси, прочитают это. Гораздо лучшим решением было бы сделать Icecast более дружественным к Nginx, так что я попробовал.
Я клонировал Icecast с github и просмотрел код. Возможно, я что-то пропустил, но эти строки мне показались актуальными:
./src/logging.c:159: client->con->ip,
./src/admin.c:700: xmlNewTextChild(node, NULL, XMLSTR(mode == OMODE_LEGACY ? "IP" : "ip"), XMLSTR(client->con->ip));
Для серверов, которые не поддерживают протокол PROXY, Nginx по умолчанию передает IP-адрес клиента вверх по течению через заголовок X-Real-IP
. Icecast, похоже, использует значение client->con->ip
для регистрации IP-адресов слушателей. Давайте немного изменим ситуацию. Я добавил это:
const char *realip;
realip = httpp_getvar (client->parser, "x-real-ip");
if (realip == NULL)
realip = client->con->ip;
И изменил предыдущие строки на это:
./src/logging.c:163: realip,
./src/admin.c:700: xmlNewTextChild(node, NULL, XMLSTR(mode == OMODE_LEGACY ? "IP" : "ip"), XMLSTR(realip));
затем я собрал Icecast из исходников согласно документации. Директива proxy_set_header X-Real-IP $remote_addr;
в моей конфигурации Nginx передает IP-адрес клиента, если у вас есть дополнительные восходящие серверы, также обрабатывающие запрос, вам нужно будет добавить некоторые директивы set_real_ip_from
, определяющие каждый IP-адрес, real_ip_recursive on;
и использовать $proxy_add_x_forwarded_for;
, который будет захватывать IP-адрес каждого сервера, который обрабатывает запрос.
Запустил мою новую сборку Icecast, и она работает отлично. Если установлен заголовок X-Real-IP
, Icecast регистрирует его как IP-адрес слушателя, а если нет, то регистрирует IP-адрес запроса клиента, поэтому он должен работать для обратного прокси-сервера и обычных настроек. Кажется слишком простым, может быть, я что-то пропустил @TBR?
Хорошо, теперь у вас должны быть работающие потоки слушателей, обслуживаемые через SSL, с правильной статистикой/журналами. Вы сделали трудную часть. Теперь давайте передадим им что-нибудь!
Поскольку в Nginx добавлен модуль потока, обработка входящих подключений становится простой, независимо от того, используют ли они PUT/SOURCE.
Если вы укажете сервер в директиве потока, Nginx просто туннелирует входящий поток на вышестоящий сервер без проверки или изменения пакетов. Урок 101 по настройке потоков Nginx — это все, что вам нужно:
stream {
server {
listen pub.lic.ip:port;
proxy_pass ice.cast.ip:port;
}
}
Я предполагаю, что одна проблема, с которой могут столкнуться ничего не подозревающие люди с SOURCE-соединениями в Nginx, заключается в указании неправильного порта в их конфигурации Nginx. Не расстраивайтесь, Shoutcast v1 просто странный. Пункт, который нужно помнить:
- Вместо порта, который вы указываете в кодировщике клиента, он фактически попытается подключиться к порту +1.
Поэтому, если вы использовали порт 8000 для входящих подключений, либо установите порт на 7999 в клиентских кодировщиках, использующих протокол Shoutcast v1, либо настройте директивы потока Nginx с двумя блоками, один для порта 8000 и один для порта 8001.
Ваша установка Nginx должна быть собрана с модулем потока, он не является частью стандартной сборки. Не уверены? Бежать:
nginx -V 2>&1 | grep -qF -- --with-stream && echo ":)" || echo ":("
Если вы видите смайлик, вы можете идти. Если нет, вам нужно собрать Nginx и включить его. Во многих репозиториях есть пакет nginx-extras
, который включает модуль потока.
Почти готово, все, что нам нужно сейчас, это доступ к страницам администратора. Я обслуживаю их из https://example.com/icecast/
, но Icecast генерирует все URI в ссылках на страницы администратора, используя корневой путь, не включая icecast/
, поэтому они не будут работать. Давайте исправим это, используя модуль подфильтра Nginx, чтобы добавить icecast/
к ссылкам на возвращаемых страницах:
location /icecast/ {
sub_filter_types text/xhtml text/xml text/css;
sub_filter 'href="/' 'href="/icecast/';
sub_filter 'url(/' 'url(/icecast/';
sub_filter_once off;
sub_filter_last_modified on;
proxy_set_header Accept-Encoding "";
proxy_pass http://ice.cast.ip:port/;
}
Косая черта в конце proxy_pass http://ice.cast.ip:port/;
жизненно важна для того, чтобы это работало.
Если директива proxy_pass указана так же, как server:port, то полный исходный URI запроса клиента будет добавлен и передан вышестоящему серверу. Если к proxy_pass добавлен какой-либо URI (даже просто /
), то Nginx заменит часть URI клиентского запроса, которая соответствует блоку местоположения (в данном случае /icecast/
), на URI, добавленный к proxy_pass. Таким образом, добавив косую черту, запрос к https://example.com/icecast/admin/
будет проксирован на http://ice.cast.ip:port/admin/
.
Наконец, я не хочу, чтобы мои страницы администратора были доступны для всего мира, только мой IP и локальная сеть, поэтому я также включаю их в расположение выше:
allow 127.0.0.1;
allow 192.168.1.0/24;
allow my.ip.add.ress;
deny all;
Вот и все.
sudo nginx -s reload
Веселиться.
person
miknik
schedule
11.09.2018