icecast и apache на одном и том же порту (mod_proxy, mod_rewrite)

У меня есть сервер Icecast, работающий на порту 8000. Я могу получить доступ к серверу, как LINK1 (см. Ниже) из Интернета. Кроме того, я создал небольшую HTML-страницу с некоторой информацией, в которую также встроен аудиоплеер HTML5. Работает нормально, если доступ осуществляется как http хост точка точка точка com.

<html>
    <head>
        <title>Radio</title>
    </head>
    <body>
        <p>Some text</p>
        <audio controls>
          <source src="LINK1" type="audio/ogg">
        </audio>
    </body>
</html>

Проблема в том, что если порт 8000 заблокирован на компьютере слушателя, они не могут слышать поток. Итак, я попытался использовать mod_proxy и mod_rewrite, но безрезультатно. Если я использую приведенный ниже конфиг, я могу обойти порт 8000, и он нормально работает на порте 80, но точка точка домена http host com показывает только аудиоплеер, а не всю страницу HTML. Я пробовал разные комбинации и гуглил, но просто не могу понять.

Мой вопрос, если это жизнеспособное решение. Наличие Apache на 80 и icecast 8000 через один и тот же порт? Может мне нужны два IP? Какова правильная конфигурация тогда, если я использую два IP-адреса. Вот мой конфиг виртуального хоста Apache.

ProxyRequests Off
ProxyPass / LINK1
ProxyPassReverse / LINK1
#RewriteEngine On
#RewriteRule ^/mount\.ogg$ LINK2 [P]

Имейте в виду, что mount.ogg - это несуществующий файл. Это просто точка для ледового покрова.

==> Публикация ссылок здесь (необходимо не менее 10 репутации) LINK1: http://host.domain.com:8000/mount.ogg LINK2: http://host.domain.com/mount.ogg

Спасибо

4 ответа

Я не хотел выбирать между Icecast, работающим на порте 80, и всеми моими виртуальными хостами Apache, работающими также на порте 80, на моем единственном внешнем IP-адресе.

Я также не хотел открывать порт 8000 на своем брандмауэре, потому что я хотел, чтобы все пользователи могли подключаться к Icecast, даже те, которые находятся за корпоративными брандмауэрами.

Поэтому мне удалось запустить прослушивание Apache 2.2 через порт 80 и прослушивание Icecast 2.4.1 через порт 8000 на одном хосте.

Я добавил новый виртуальный хост radio.domain.com (прослушивающий порт 80), который маршрутизирует трафик Icecast на / с локального сервера Icecast (прослушивает порт 8000):

<VirtualHost *:80>
    ServerName radio.domain.com
    ServerAdmin hostmaster@domain.com
    ProxyPreserveHost On
    ProxyPass / http://localhost:8000/
    ProxyPassReverse / http://localhost:8000/
</VirtualHost>

Затем я смог подключить аудио-клиенты, такие как VLC/Winamp, к точкам монтирования Icecast, используя такие адреса, как http://radio.domain.com/my_stream,

Однако при подключении к виртуальному хосту Icecast http://radio.domain.com/ веб-страница, файлы m3u и xspf, где по-прежнему отображается URL http://radio.domain.com:8000/my_stream с этим надоедливым портом 8000. Тогда люди, загружающие эти файлы, не смогли подключиться к серверу Icecast, потому что пытались подключиться не к тому порту. То же самое происходило с обновлениями YP на dir.xiph.org.

Затем я скачал исходный код Icecast 2.4.1 и изменил его, добавив новый параметр:

<exposed-port>80</exposed-port>

Вы можете найти этот патч на https://damiengarrido.wordpress.com/2015/03/22/icecast-reachable-behind-reverse-proxy/

Я могу вставить патч здесь, если это необходимо.

Мне удалось найти решение (частичное) с использованием двух виртуальных хостов. Для слушателей, которые могут получить доступ к порту 8000, конфигурация остается такой же, как указано выше, за исключением директив прокси. Но на странице HTML для первого виртуального хоста я добавил ссылку, чтобы открыть новое окно, которое указывает на вторые виртуальные хосты, где я использую ProxyReverse. Итак, файл HTML для 1-го виртуального хоста

<audio controls>
    <source src="LINK1" type="audio/ogg">
</audio>
<a href="/"  onclick="window.open('LINK3', 'newwindow','width=300, height=100'); return false;"> No audio?</a>

где LINK3 - это ссылка на 2-й виртуальный хост, например, точка-точка host2 точка com, прямая косая черта

И тогда конфиг для этого 2-го виртуального хоста фактически делает обратный прокси.

ProxyRequests Off
ProxyPass / LINK1
ProxyPassReverse / LINK1

Вероятно, я могу использовать 1-пиксельную рамку и указать там ссылку, но с этим решением я тоже в порядке.

Спасибо

У меня возникла та же проблема при слиянии моей домашней страницы index.php, которая работает на порте 443 в apache2 в Ubuntu 16.04. Я хотел использовать свою собственную веб-страницу и передать "сценарий" музыкального потока (не-ssl) и того, что в данный момент воспроизводится (также не-ssl). То, что происходило, было то, что все работало бы через порт 80, но когда я переключился на порт 443, браузеры (особенно Chrome) блокировали мои "незащищенные сценарии", и звук не возникал.

Итак, после поиска по всему интернету и обнаружения этого, но не как это сделать, я наконец-то понял!

Вот мой набор для тех, кто заинтересован:

  1. Icecast 2.4.3 в Windows, работающий через порт 8080
  2. Ubuntu 16.04 LTS работает на Oracle VirtualBox с почти 20 веб-сайтами
  3. Я использую MediaMonkey 4.1.16 и плагин под названием "edcast" для подключения к Icecast

Apache2 conf файл:

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName radio.domain.com
DocumentRoot /var/www/radio.domain.com

<Directory /var/www/radio.domain.com>
    Options Indexes FollowSymLinks MultiViews
    Order allow,deny
    allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/radio.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/radio.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf

Options -Includes -ExecCGI
RewriteEngine On
RewriteCond %{THE_REQUEST} !HTTP/1.1$
RewriteRule .* - [F]

LimitRequestBody 512000
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
Header always set X-Frame-Options DENY

FileETag None
TraceEnable off
Header set X-XSS-Protection "1; mode=block"
Timeout 60

<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>

ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set Front-End-Https "On"

ProxyPass /stream http://192.168.1.2:8080/stream #IP and port of local computer on same network
ProxyPassReverse /stream http://192.168.1.2:8080/stream #IP and port of local computer on same network
ProxyPass /np.xsl http://192.168.1.2:8080/np.xsl #np.xsl is a file that I call using ajax from my index.php page to get the track currently playing
ProxyPassReverse /np.xsl http://192.168.1.2:8080/np.xsl #np.xsl is a file that I call using ajax from my index.php page to get the track currently playing

</VirtualHost>
</IfModule>

Мой файл np.xsl (в директории Icecast "web"):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" method="text" indent="no" media-type="text/javascript" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/icestats">
parseMusic({
    <xsl:for-each select="source">"<xsl:value-of select="@mount"/>":{
        "server_name":"<xsl:value-of select="server_name"/>",
        "title":"<xsl:if test="artist"><xsl:value-of select="artist" /> - </xsl:if><xsl:value-of select="title" />",
        "bitrate":"<xsl:value-of select="bitrate" />"}
    <xsl:if test="position() != last()"><xsl:text>,</xsl:text>
    </xsl:if>
</xsl:for-each>});
</xsl:template>
</xsl:stylesheet>

Моя страница index.php:

<!DOCTYPE html>
<html>
<head>
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <title id="track-title"></title>
    <style>
        html{width:100%;}
        body{background-color:#bfbfbf; text-align:center; font-family:Helvetica;}
        #wrapper{position:absolute; max-width:550px; left:50%; transform:translate(-50%,0); -ms-transform:translate(-50%,0); -webkit-transform:translate(-50%,0); margin-right:-50%; text-align:center; box-shadow:1px 1px 20px 5px #4d4d4d;}
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    <script>
    function updateTitle() {
    $.ajax({
            type: 'GET',
            url: 'https://radio.domain.com/np.xsl',
            jsonpCallback: 'parseMusic',
            dataType: 'jsonp'
    }).then(function (data) {
            var $track = $('#track-title').text(data['/stream'].title);
            var text = $track.text();
            $track.text(text.replace(" - MediaMonkey",""));
    }).fail(function (e) {
            console.log(e);
    }).always(function () {
            setTimeout(updateTitle, 5000);
    });
    }
    $(updateTitle);
    function updateTitle2() {
    $.ajax({
            type: 'GET',
            url: 'https://radio.domain.com/np.xsl',
            jsonpCallback: 'parseMusic',
            dataType: 'jsonp'
    }).then(function (data) {
            var $track = $('#track-title2').text(data['/stream'].title);
            var text = $track.text();
            $track.text(text.replace(" - MediaMonkey",""));
    }).fail(function (e) {
            console.log(e);
    }).always(function () {
            setTimeout(updateTitle2, 5000);
    });
    }
    $(updateTitle2);
    </script>
</head>
<body>
    <div id="wrapper">
    <h2>Live Radio</h2></br>
    <h4><span id="track-title2"></span></h4></br></br>
    <audio controls src="https://radio.domain.com/stream" type="audio/mp3"></audio><br></br>
    </div>
</body>
</html>

Наконец мой код icecast.xml:

<icecast>
<location>Minneapolips, MN</location>
<admin>info@radio.domain.com</admin>
<hostname>radio.domain.com</hostname>
<limits>
    <clients>50</clients>
    <sources>1</sources>
    <queue-size>524288</queue-size>
    <client-timeout>30</client-timeout>
    <header-timeout>15</header-timeout>
    <source-timeout>10</source-timeout>
    <burst-on-connect>1</burst-on-connect>
    <burst-size>65535</burst-size>
</limits>
<authentication>
    <source-password>hackme</source-password>
    <relay-password>hackme</relay-password>
    <admin-user>admin</admin-user>
    <admin-password>hackmemore</admin-password>
</authentication>
<listen-socket>
    <port>8080</port>
    <shoutcast-mount>/stream</shoutcast-mount>
</listen-socket>
<http-headers>
    <header name="Access-Control-Allow-Origin" value="*" />
</http-headers>
<fileserve>1</fileserve>
<paths>
    <logdir>./log</logdir>
    <webroot>./web</webroot>
    <adminroot>./admin</adminroot>
    <alias source="/" destination="/status.xsl"/>
</paths>

<logging>
    <accesslog>access.log</accesslog>
    <errorlog>error.log</errorlog>
    <loglevel>4</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
    <logsize>10000</logsize> <!-- Max size of a logfile -->
</logging>
</icecast>

И как это выглядит: радио

Предпочтительным способом является прослушивание Icecast напрямую через порт 80, в конце концов, это HTTP-сервер.

Обратное проксирование не рекомендуется по многим причинам.

  • многие долгоживущие соединения, если не настроены правильно, приведут к сбоям apache
  • некоторые устаревшие функции (SOURCE, STATS) недоступны, доступны только через обычный HTTP в 2.4.1 и будущих версиях Icecast
  • код сообщения общедоступного каталога YP не может быть сделан обратным прокси-сервером, это нарушит списки
  • веб-интерфейс и сгенерированные плейлисты, по крайней мере, нелегко получить право

Подводя итог, если вы работаете над производственной установкой и являетесь профессионалом, который точно знает, что они делают, это возможно, но не просто. Если вы просто небрежно думаете: "Ой, давайте просто поменяем прокси-сервер, как и все остальное", тогда вас ждет некоторая боль.

Получите дополнительный IP, заставьте Icecast слушать порт 80 на этом, просто.

Другие вопросы по тегам