Published: Mon 18 December 2023
By Mike Neumann
In Podcasting .
tags: icecast podcasting https how-to
The Problem
It's not really a problem. Today most everything on the web has moved from http to https. This is generally a good thing. However, in the case of icecast, all of the services that I could find for pay-as-you-go internet radio services don't offer icecast+https services to customers.
Ok, wait Mike. Why do I need https on icecast?
Normally, this isn't an issue. You can (still) happily click through all of the 'safety' warnings that web browsers show you when you connect to an http web server. You accept the risks and move on. It's only an issue if you're trying to connect to an endpoint service that will refer to your icecast stream point to play your tream THROUGH it's https web site.
What are you really talking about?
The specific example I was wrestling with was that I was on a pay-as-you-go plan (great plan, actually) from internet-radio.com. They offered an http endpoint with no way to upgrade to https. This works well for most podcasts that want to just stream the audio from their show to their listeners using, for example, the Podcasting 2.0 Live Item Tag (LIT). However, now we live in the age of modern podcast applications, Live Item Tag, and "Wallet Switching Technology" to allow listeners to load up their podcast app's wallet with satoshis and stream and/or boost through the live music podcast to the artist/musician that is playing at that specific time in the live show.
How does that happen? Well today, that only happens through Steven Bell's The Split Kit (TSK) . TSK is a remarkable web application that allows podcasters to create a variety of types of "Events"; one of which is great for enabling music to be played during a live podcast, but the main feature is that listeners can go to the Event page published by the podcaster that is hosted by TSK. On that page, you will see album art, and other links, including a link to "Boost" the podcast and/or the song currently playing while you are on that page. The audio feed eminating from that page is the podcast's live feed, effectively 'relayed' through the split kit, and that event web page has all of the machinery within it to get those sats to the right place; something you could never do on a plain ole' icecast server.
TL;DR
So in summary, we need for listeners to live events presented by TSK to be able to hear the live audio stream when they click the 'play' button on the event page hosted by TSK. Most all icecast hosting services still use http. The Split Kit (TSK) needs an incoming https icecast stream to relay through it's own https event page.
Hello to self-hosting icecast
First thing that you need to host icecast is a Virtual Private Server (VPS). I have set up My icecast/internet radio service provider does not, and most importantly, the icecast build available through my standard Ubuntu 22.04 build doesn't support https. Why?
Although I started here Host Your Own Icecast Streaming Server for $3.50/month , which is a nice overview from five years ago on starting from scratch; shiny fresh Vultr VPS onward, I really should have started with his other fine article that he wrote 18 months later, Icecast HTTPS/SSL with Let’s Encrypt: Setup Guide , and referenced back to that first article
BTW, Icecast is maintained and documented here .
Not straightforward...
Let's Do This
Enough ramble. Here's the quick and dirty of what I did. I'll try not to skip too many steps. :)
Set up a fresh VPS
For me, I set up a $5 Ubuntu 22.04 LTS VPS on Linode.com with backup ($7 + tax/month, all in), tightened things up a bit, ran the usual updates, set my hostname ("streams"), and then set my DNS to point to the FQDN "streams.mydomain.com" (well, my real FQDN). I set up both IPv4 and IPv6 DNS records. This is kinda important to do now, because you'll need to have this working properly by the time you get icecast2 installed and certainly in order to set up https using Let's Encrypt.
Once your server is up and idling, and your DNS resolves correctly to your IP address, it's time to install icecast2.
Install icecast2
Two important things:
1. Download an icecast2 for your distro that has https support pre-built into it. The standard distros do NOT support https.
2. install libssl1.1 - icecast2's https support relies on this old version of the SSL library, but these get patched-up fairly well because of old builds of code that rely on them.
I thought about adding the Xiph icecast2 distro to my Ubuntu sources list, but not only is the signing key expired (2024-06-07, without replacement that I can see), but apt-key is strongly depreciated and won't be available at all beyond Ubuntu 22.04. I'm just going to install directly using dpkg and set a calendar reminder to check Xiph every six months or so. Maybe.
Download what you need; openssl1.1 and of course icecast2
Let's get that older version of openssl installed first. Although it's an older version, some valiant developers maintain/patch older ssl implementations for just the occasion we are facing; old software that runtime dependencies to old SSL versions. It's been built recently (November 2023).
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb
dpkg -i ./libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb
Now for Icecast2
https://www.icecast.org/download/
gives the scoop on downloading icecast for your distro.
On Ubuntu, the most recent build is https://download.opensuse.org/repositories/multimedia:/xiph/xUbuntu_18.04/amd64/
(March 2022). Which leads to doing a
wget https://download.opensuse.org/repositories/multimedia:/xiph/xUbuntu_18.04/amd64/icecast2_2.4.4-1_amd64.deb
apt install ./icecast2_2.4.4-1_amd64.deb
apt comes back with "Suggested packages: ices2 speex", which if you continue down that trail of suggested packages, your installation list goes on forever... I just said "Y" to continue and ignored the optional/suggested packages.
This takes you straight in to the configuration dialogs. Don't skip any of these. Heed the advice on Icecast hosting Setup Guide - Install Icecast and fill everything out and make sure you don't loose your passwords. After the dialogs are complete, icecast should start and be running.
Check with systemctl status icecast2
user@streams:~$ systemctl status icecast2
● icecast2.service - LSB: Icecast2 streaming media server
Loaded: loaded ( /etc/init.d/icecast2; generated)
Active: active ( running) since Wed 2023 -11-29 21 :19:10 CST; 1min 32s ago
Docs: man:systemd-sysv-generator( 8 )
Process: 3494 ExecStart = /etc/init.d/icecast2 start ( code = exited, status = 0 /SUCCESS)
Tasks: 4 ( limit: 1013 )
Memory: 6 .4M
CPU: 45ms
CGroup: /system.slice/icecast2.service
└─3499 /usr/bin/icecast2 -b -c /etc/icecast2/icecast.xml
Configure icecast2 to answer on Port 80 - VERY IMPORTANT
Don't argue with The Man (not me, I'm not 'The Man'); the author of this note: https://lists.xiph.org/pipermail/icecast/2015-February/013171.html
. This works and is mandatory. He explained it a bit more here https://stackoverflow.com/questions/63440977/how-to-get-icecast-to-run-on-port-80
Edit two lines in /etc/default/icecast2
:
Edit the following lines in /etc/icecast2/icecast.xml
:
this must be the first entry
<listen-socket>
<port> 80</port>
<listen-socket>
then in the security section:
<changeowner>
<user> icecast2</user>
<group> icecast</group>
</changeowner>
for yp listings, make sure <hostname>
resolves to your Icecast server (not your homepage!) and remove the <!-- -->
around the <directory>
section.
Start Icecast through its init script / systemd:
user@streams:~$ sudo systemctl restart icecast2
user@streams:~$ sudo systemctl status icecast2
● icecast2.service - LSB: Starts the icecast audio streaming server daemon
Loaded: loaded ( /etc/init.d/icecast2; generated)
Active: active ( running) since Tue 2023 -12-19 02 :48:06 UTC; 9s ago
Docs: man:systemd-sysv-generator( 8 )
Process: 3143 ExecStart = /etc/init.d/icecast2 start ( code = exited, status = 0 /SUCCESS)
Tasks: 4 ( limit: 1013 )
Memory: 2 .7M
CPU: 18ms
CGroup: /system.slice/icecast2.service
└─3145 /usr/bin/icecast2 -b -c /etc/icecast2/icecast.xml
Dec 19 02 :48:06 streams icecast2[ 3143 ] : Starting icecast2:
Dec 19 02 :48:06 streams icecast2[ 3144 ] : Starting icecast2
Dec 19 02 :48:06 streams icecast2[ 3144 ] : Detaching from the console
Dec 19 02 :48:06 streams icecast2[ 3143 ] : icecast2.
Dec 19 02 :48:06 streams systemd[ 1 ] : Started LSB: Starts the icecast audio streaming server daemon.
Dec 19 02 :48:06 streams icecast2[ 3145 ] : Starting icecast2
Dec 19 02 :48:06 streams icecast2[ 3145 ] : Detaching from the console
Dec 19 02 :48:06 streams icecast2[ 3145 ] : Changed groupid to 118 .
Dec 19 02 :48:06 streams icecast2[ 3145 ] : Changed supplementary groups based on user: icecast2.
Dec 19 02 :48:06 streams icecast2[ 3145 ] : Changed userid to 114 .
You can now just go to http://streams.yourdomain.com
and you'll see your server running. Clicking on "Admin Home", and entering Username: admin, Password: to see the number of active connections, listeners, etc.
For me, it's up and running on Port 80. Now to enable ssl...
Adding SSL using LetsEncrypt
Now let's enable SSL using LetsEncrypt: https://www.mediarealm.com.au/articles/icecast-https-ssl-setup-lets-encrypt/
apt-get install certbot
sudo certbot certonly --webroot-path="/usr/share/icecast2/web" -d 'streams.yourdomain.com'
Choose option 2, the 'webroot' option.
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/streams.yourdomain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/streams.yourdomain.com/privkey.pem
This certificate expires on 2024 -02-28.
But icecast2 doesn't know how to handle those two files. We need to create a new file that is a concatenation of those two files.
cat /etc/letsencrypt/live/streams.mydomain.com/fullchain.pem /etc/letsencrypt/live/streams.mydomain.com/privkey.pem > /etc/icecast2/bundle.pem
Since we configured icecast to run as icecast2 in the port 80 activation step, above, we can chown
, rather than chmod
the file with a not-so-great read permission for all, because that file contains the private key of our server certificate.
chown icecast2:root /etc/icecast2/bundle.pem
The LetsEncrypt certificate will expire in 90 days, so let's make sure that we can do a renewal.
Enabling LetsEncrypt Certificate Renewal
I wrote a short script since the string given by the OP didn't work well for me. Probably a string error encapsulating a few commands, but regardless, this script seems to do the trick, or more likely, something changed in the certbot implementation/parsing of that file (c.f. a comment on the OP).
Regardless, I wrote this script...
/etc/icecast2/concatforice.sh
and set the permissions mask to 750
and ownershipw to icecast2:root
#!/bin/sh
cat /etc/letsencrypt/live/streams.mydomain.com/fullchain.pem /etc/letsencrypt/live/streams.mydomain.com/privkey.pem > /etc/icecast2/bundle.pem
chown icecast2:root /etc/icecast2/bundle.pem
chmod 640 /etc/icecast2/bundle.pem
systemctl restart icecast2
Now we go to the LetsEncrypt renewal configuration file for the FDQN.
vi /etc/letsencrypt/renewal/streams.mydomain.com.conf
and add this to the [renewalparams]
section:
post_hook = /etc/icecast2/concatforice.sh
Do a test certificate renewal to check that it will/should work correctly:
certbot renew --dry-run
Configure icecast to use SSL
We have our certificate, now we need to configure icecast to use that server certificate that will be maintained by LetsEncrypt for us. Edit icecast.xml
in a text editor: vi /etc/icecast2/icecast.xml
adding
/etc/icecast2/bundle.pem
And add the following section to the document in the root XML node:
<listen-socket>
<port> 443</port>
<ssl> 1</ssl>
</listen-socket>
Remember that the listen-socket section for port 80 must be the first listed. I just added the port 443 section directly below the port 80 section to avoid any confusion.
Now just restart the icecast service: service icecast2 restart
You should be able to now browse to https://streams.mydomain.com and listen to and serve your stream over https.