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) блокировали мои "незащищенные сценарии", и звук не возникал.
Итак, после поиска по всему интернету и обнаружения этого, но не как это сделать, я наконец-то понял!
Вот мой набор для тех, кто заинтересован:
- Icecast 2.4.3 в Windows, работающий через порт 8080
- Ubuntu 16.04 LTS работает на Oracle VirtualBox с почти 20 веб-сайтами
- Я использую 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 на этом, просто.