Intro
Akhirnya jadi terpaksa menulis, karena tidak ada web yang benar-benar akurat dalam menyajikan artikelnya terkait install icecast menggunakan SSL dari Let’s Encrypt. Rata-rata informasinya setengah-setengah, atau mislead artikelnya, entahlah, apakah emang environtmentnya berbeda atau emang gak mau ngasih ilmunya, biarlah, kita mah bebas aja, jika sekiranya yang saya tulis bisa bermanfaat, اَلْحَمْدُلِلّهِ , tinggal berharap digunakan untuk tujuan baik dan mengharap pahala.
Kenapa sih pakai Icecast? Nah ini. Dulu pernah pakai yang versi Windows dan kok keren yah bisa buat mount point gitu dan sekarang pengen banget install di Linux. Terus, Icecast ada feature mount point? Ini bisa kita pakai misalkan tuk beberapa user, jadi cukup menjalankan satu aplikasi Icecast saja tidak seperti Shoutcast yang hanya bisa menjalankan satu program untuk satu user saja, nah, kalau pakai Shoutcast, misal ada 5 user ya berarti kita nanti menjalankan 5 aplikasi Shoutcast. Terus, Icecast sudah support SSL secara native, jadi tidak perlu lagi berjalan dibelakang proxy pakai Nginx atau stunnel. Dan ini adalah point utama kenapa saya ingin migrasi dari Shoutcast ke Icecast, soalnya bertentangan dengan hati nurani, udah pakai SSL tapi masih harus nulis port pas mau play streaming radio, hehehe.
Cara install Icecast menggunakan SSL dari Let’s Encrypt ini lumayan agak sedikit tricky kalau menurut saya yang tidak paham mengenai ilmu per-Linux-an, maklumlah, kita mah cuma tukang ngoprek. Awalnya menggunakan repository epel-release dari CentOS tapi ketika diterapkan SSL, Icecast-nya tidak mau running. Kemudian coba install menggunakan metode:
git clone --recursive https://gitlab.xiph.org/xiph/icecast-server.git
./autogen.sh
./configure --prefix=/opt/icecast/2.4.4 --with-curl --with-openssl
make
make install
Ternyata mentok di make, jadinya bingung deh. Akhirnya mencoba menggunakan source tarball-nya, dan ternyata berhasil. Nah, berikut langkah-langkahnya yah, yuk ah, kita simak langkah demi langkahnya, uhuy, hehehe.
Buka Port HTTP dan HTTPS
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload
Tapi kalau mau pakai port juga bisa. Oh iya, ada yang kelupaan dan ini adalah hal yang paling crucial untuk menjalankan Icecast menggunakan SSL dari Let’s Encrypt.
CentOS 7: Install Icecast Menggunakan SSL Dari Let’s Encrypt
Anda tidak akan bisa melakukan publish stream ke Icecast server melalui port SSL / 443. Karenanya, anda akan menjalankan Icecast server di 2 port, yang satunya akan digunakan sebagai input stream.
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --permanent --zone=public --add-port=8000/tcp
firewall-cmd --reload
Dalam hal ini, kita akan menggunakan port 8000 sebagai input stream dan port 443 yang akan kita distribusikan ke client. Nah, masalahnya nanti ketika ada user yang langsung sotoy ngetik nama host-nya atau domain yang kita gunakan, biasanya akan mengarah ke port 80, sekarang tugas kita adalah forward port 80 ke port 443, dengan perintah:
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=443
firewall-cmd --runtime-to-permanent
firewall-cmd --list-all
Kalau ingin remove port forwardingnya bisa merujuk ke halaman RedHat Documentation.
Dependency
Langkah awal adalah menginstal dependency terlebih dahulu yang dibutuhkan untuk nantinya meng-compile source tarball Icecast.
yum update
yum groupinstall "Development Tools"
yum install wget curl-devel libtheora-devel libvorbis-devel libxslt-devel speex-devel openssl-devel
Install Icecast Server
Saat saya menulis di blog, release terakhir Icecast adalah versi 2.4.4 yang bisa di download di https://darto.id/icecast244 atau dari xiph.
wget https://downloads.xiph.org/releases/icecast/icecast-2.4.4.tar.gz
tar xf icecast-2.4.4.tar.gz
cd icecast-2.4.4
./configure --prefix=/opt/icecast --with-curl --with-openssl
make
make install
Nah, sudah berhasil tuk install Icecast server di CentOS 7. Tinggal permasalahannya adalah membuat user, group dan folder log, tapi yang jadi masalah adalah karena awalnya saya sudah terlebih dahulu melakukan install Icecast melalui epel-release, kemungkinan sudah dibuatkan pula user dan groupnya. Ya kalau mau mudahnya sih bisa aja begitu.
yum install icecast
yum remove icecast
yum autoremove
Tapi kalau tidak melalui proses install Icecast server terlebih dahulu, mungkin prosesnya seperti ini terkait user dan group untuk Icecast server.
groupadd icecast
useradd -g icecast icecast
Sekarang tinggal membuat folder untuk log Icecast.
mkdir -p /opt/icecast/var/log/icecast
chown -R icecast:icecast /opt/icecast/var
Mime.types
Selanjutnya adalah menyiapkan mime.types yang bisa di download di https://darto.id/mimetypes dan kemudian ditaruh di /etc. Nah, jarang nih yang menyinggung kalau file mime.types ini adalah file yang urgent yang dibutuhkan sebelum Icecast server bisa berjalan, karena kalau tidak ada file mime.types Icecast servernya tidak akan mau running,, akan error terus dan berhenti. Nah, anehnya file mime.types ini kalau di Linux tidak ada tapi kalau kita install Icecast server untuk OS Windows, file mime.types ini ada di folder instalasinya.
wget https://data.darto.id/software/linux/icecast/mime.types -P /etc/
Menyiapkan SSL dari Let’s Encrypt
Sebelumnya pernah mainan Let’s Encrypt waktu coba-coba buat VPN untuk mengkases jaringan kantor, nah, kali ini mainan lagi kita Let’s Encrypt unyuk server streaming. Yuk dimulai aja.
yum install certbot
certbot certonly --standalone --preferred-challenge http -d radio.darto.id
Kemudian masukkan email, dan ketik Y untuk Please read the Terms of Service…, dan ketik N untuk Would you be willing… dan tunggu sampai anda melihat Congratulations! pada IMPORTANT NOTES: dan jika tidak ingin pakai mode interactif mungkin bisa menggunakan command berikut:
certbot certonly --standalone --agree-tos --no-eff-email --email darto@kloningspoon.com --preferred-challenge http -d radio.darto.id
Langkah selanjutnya adalah kita menggabungkan certificate yang sudah kita dapatkan.
cat /etc/letsencrypt/live/radio.darto.id/fullchain.pem /etc/letsencrypt/live/radio.darto.id/privkey.pem > /opt/icecast/share/icecast/icecast.pem
Selanjutnya kita akan membuat agar SSL dari Let’s Encrypt ini otomatis memperbarui ketika sudah expired, karena Let’s Encrypt hanya berlaku untuk 3 bulan saja certificate-nya.
crontab -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 0,12 * * * certbot renew --pre-hook "pidof icecast | xargs kill & rm -f /opt/icecast/share/icecast/icecast.pem" --post-hook "cat /etc/letsencrypt/live/radio.darto.id/fullchain.pem /etc/letsencrypt/live/radio.darto.id/privkey.pem > /opt/icecast/share/icecast/icecast.pem & /opt/icecast/bin/icecast -c /opt/icecast/etc/icecast.xml -b" > /dev/null 2>&1
Konfigurasi Icecast
Sebelum merubah konfigurasi default, ada baiknya kita buat backup dulu.
cp /opt/icecast/etc/icecast.xml /opt/icecast/etc/icecast.xml.original
Atau bisa juga direname file aslinya dan kemudian kita buat baru file konfigurasinya dengan perintah:
mv /opt/icecast/etc/icecast.xml /opt/icecast/etc/icecast.xml.original
vi /opt/icecast/etc/icecast.xml
Dan kemudian copy paste code dibawah ini.
<icecast>
<!-- location and admin are two arbitrary strings that are e.g. visible
on the server info page of the icecast web interface
(server_version.xsl). -->
<location>Indonesia</location>
<admin>darto@kloningspoon.com</admin>
<!-- IMPORTANT!
Especially for inexperienced users:
Start out by ONLY changing all passwords and restarting Icecast.
For detailed setup instructions please refer to the documentation.
It's also available here: http://icecast.org/docs/
-->
<limits>
<clients>100</clients>
<sources>2</sources>
<queue-size>524288</queue-size>
<client-timeout>30</client-timeout>
<header-timeout>15</header-timeout>
<source-timeout>10</source-timeout>
<!-- If enabled, this will provide a burst of data when a client
first connects, thereby significantly reducing the startup
time for listeners that do substantial buffering. However,
it also significantly increases latency between the source
client and listening client. For low-latency setups, you
might want to disable this. -->
<burst-on-connect>1</burst-on-connect>
<!-- same as burst-on-connect, but this allows for being more
specific on how much to burst. Most people won't need to
change from the default 64k. Applies to all mountpoints -->
<burst-size>65535</burst-size>
</limits>
<authentication>
<!-- Sources log in with username 'source' -->
<source-password>hackme</source-password>
<!-- Relays log in with username 'relay' -->
<relay-password>hackme</relay-password>
<!-- Admin logs in with the username given below -->
<admin-user>admin</admin-user>
<admin-password>hackme</admin-password>
</authentication>
<!-- set the mountpoint for a shoutcast source to use, the default if not
specified is /stream but you can change it here if an alternative is
wanted or an extension is required
<shoutcast-mount>/live.nsv</shoutcast-mount>
-->
<!-- Uncomment this if you want directory listings -->
<!--
<directory>
<yp-url-timeout>15</yp-url-timeout>
<yp-url>http://dir.xiph.org/cgi-bin/yp-cgi</yp-url>
</directory>
-->
<!-- This is the hostname other people will use to connect to your server.
It affects mainly the urls generated by Icecast for playlists and yp
listings. You MUST configure it properly for YP listings to work!
-->
<hostname>radio.darto.id</hostname>
<!-- You may have multiple <listen-socket> elements -->
<listen-socket>
<port>443</port>
<ssl>1</ssl>
<!-- <bind-address>127.0.0.1</bind-address> -->
<!-- <shoutcast-mount>/stream</shoutcast-mount> -->
</listen-socket>
<listen-socket>
<port>8000</port>
</listen-socket>
<!--
<listen-socket>
<port>8443</port>
<ssl>1</ssl>
</listen-socket>
-->
<!-- Global header settings
Headers defined here will be returned for every HTTP request to Icecast.
The ACAO header makes Icecast public content/API by default
This will make streams easier embeddable (some HTML5 functionality needs it).
Also it allows direct access to e.g. /status-json.xsl from other sites.
If you don't want this, comment out the following line or read up on CORS.
-->
<http-headers>
<header name="Access-Control-Allow-Origin" value="*" />
</http-headers>
<!-- Relaying
You don't need this if you only have one server.
Please refer to the documentation for a detailed explanation.
-->
<!--<master-server>127.0.0.1</master-server>-->
<!--<master-server-port>8001</master-server-port>-->
<!--<master-update-interval>120</master-update-interval>-->
<!--<master-password>hackme</master-password>-->
<!-- setting this makes all relays on-demand unless overridden, this is
useful for master relays which do not have <relay> definitions here.
The default is 0 -->
<!--<relays-on-demand>1</relays-on-demand>-->
<!--
<relay>
<server>127.0.0.1</server>
<port>8080</port>
<mount>/example.ogg</mount>
<local-mount>/different.ogg</local-mount>
<on-demand>0</on-demand>
<relay-shoutcast-metadata>0</relay-shoutcast-metadata>
</relay>
-->
<!-- Mountpoints
Only define <mount> sections if you want to use advanced options,
like alternative usernames or passwords
-->
<!-- Default settings for all mounts that don't have a specific <mount type="normal">.
-->
<!--
<mount type="default">
<public>0</public>
<intro>/server-wide-intro.ogg</intro>
<max-listener-duration>3600</max-listener-duration>
<authentication type="url">
<option name="mount_add" value="http://auth.example.org/stream_start.php"/>
</authentication>
<http-headers>
<header name="foo" value="bar" />
</http-headers>
</mount>
-->
<!-- Normal mounts -->
<!--
<mount type="normal">
<mount-name>/example-complex.ogg</mount-name>
<username>othersource</username>
<password>hackmemore</password>
<max-listeners>1</max-listeners>
<dump-file>/tmp/dump-example1.ogg</dump-file>
<burst-size>65536</burst-size>
<fallback-mount>/example2.ogg</fallback-mount>
<fallback-override>1</fallback-override>
<fallback-when-full>1</fallback-when-full>
<intro>/example_intro.ogg</intro>
<hidden>1</hidden>
<public>1</public>
<authentication type="htpasswd">
<option name="filename" value="myauth"/>
<option name="allow_duplicate_users" value="0"/>
</authentication>
<http-headers>
<header name="Access-Control-Allow-Origin" value="http://webplayer.example.org" />
<header name="baz" value="quux" />
</http-headers>
<on-connect>/home/icecast/bin/stream-start</on-connect>
<on-disconnect>/home/icecast/bin/stream-stop</on-disconnect>
</mount>
-->
<!--
<mount type="normal">
<mount-name>/auth_example.ogg</mount-name>
<authentication type="url">
<option name="mount_add" value="http://myauthserver.net/notify_mount.php"/>
<option name="mount_remove" value="http://myauthserver.net/notify_mount.php"/>
<option name="listener_add" value="http://myauthserver.net/notify_listener.php"/>
<option name="listener_remove" value="http://myauthserver.net/notify_listener.php"/>
<option name="headers" value="x-pragma,x-token"/>
<option name="header_prefix" value="ClientHeader."/>
</authentication>
</mount>
-->
<mount type="normal">
<mount-name>/live.mp3</mount-name>
<username>darto</username>
<password>kloningspoon.com</password>
<max-listeners>200</max-listeners>
<public>1</public>
<genre>Tutorial</genre>
<intro>/jeda_rodja11_256.mp3</intro>
<stream-name>Live Streaming Radio Darto</stream-name>
<stream-description>We Share Because We Care</stream-description>
<stream-url>https://radio.darto.id/live.mp3</stream-url>
</mount>
<fileserve>1</fileserve>
<paths>
<!-- basedir is only used if chroot is enabled -->
<basedir>/opt/icecast/share/icecast</basedir>
<!-- Note that if <chroot> is turned on below, these paths must both
be relative to the new root, not the original root -->
<logdir>/opt/icecast/var/log/icecast</logdir>
<webroot>/opt/icecast/share/icecast/web</webroot>
<adminroot>/opt/icecast/share/icecast/admin</adminroot>
<!-- <pidfile>/opt/icecast/share/icecast/icecast.pid</pidfile> -->
<!-- Aliases: treat requests for 'source' path as being for 'dest' path
May be made specific to a port or bound address using the "port"
and "bind-address" attributes.
-->
<!--
<alias source="/foo" destination="/bar"/>
-->
<!-- Aliases: can also be used for simple redirections as well,
this example will redirect all requests for http://server:port/ to
the status page
-->
<alias source="/" destination="/status.xsl"/>
<!-- The certificate file needs to contain both public and private part.
Both should be PEM encoded.
-->
<ssl-certificate>/opt/icecast/share/icecast/icecast.pem</ssl-certificate>
</paths>
<logging>
<accesslog>access.log</accesslog>
<errorlog>error.log</errorlog>
<!-- <playlistlog>playlist.log</playlistlog> -->
<loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
<logsize>10000</logsize> <!-- Max size of a logfile -->
<!-- If logarchive is enabled (1), then when logsize is reached
the logfile will be moved to [error|access|playlist].log.DATESTAMP,
otherwise it will be moved to [error|access|playlist].log.old.
Default is non-archive mode (i.e. overwrite)
-->
<!-- <logarchive>1</logarchive> -->
</logging>
<security>
<chroot>0</chroot>
<changeowner>
<user>icecast</user>
<group>icecast</group>
</changeowner>
</security>
</icecast>
Silakan dirubah sesuai kebutuhan yang ingin anda aplikasikan di server anda. Seperti location, admin, source-password, relay-password, admin-password, hostname, port listen-socket yang dijadikan sebagai input stream, dan sesuaikan pada baris mount.
CentOS 7: Install Icecast Menggunakan SSL Dari Let’s Encrypt
location tidak boleh diisi dengan defaultnya, Earth, harus diganti, begitu juga dengan email pada tag admin dan hostname untuk Icecast server.
Kalau 3 tag itu masih default, biasanya Icecast gak mau jalan, langsung stop.
Aplikasi Tambahan
yum install mediainfo sox lame
mediainfo bisa digunakan untuk melihat metadata dari audio atau video, sox dan lame bisa digunakan untuk meng-convert audio. Untuk lebih lengkapnya mungkin bisa dilihat melalui perintah:
yum info mediainfo sox lame
Menjalankan Icecast Server diatas SSL Let’s Encrypt
OK. Install Icecast sudah, menggabungkan certificate sudah, membuat konfigurasi sudah, sekarang tinggal menjalankannya.
Saya sudah mencoba membuat Icecast dijalankan sebagai service tapi gagal, karena ada error
EROR connection/connection_setup_sockets C...t 443 WARNING: Can't change user id unless you are root.
Akhirnya cobanya manual aja, pakai crontab.
crontab -e
*/1 * * * * /opt/icecast/bin/icecast -c /opt/icecast/etc/icecast.xml -b > /dev/null 2>&1
Kalau mau lihat isi crontab bisa menggunakan perintah crontab -l.
OK. Segini aja dulu deh, semoga bermanfaat. Kalau ada pertanyaan silakan hubungi langsung aja yah.
بارك الله فيكم