Icecast 2.4.4
Overview
Icecast, from the Xiph.Org Foundation, is the streaming server behind a great many internet radio stations. A source client such as butt, Mixxx, liquidsoap, ices, ffmpeg or OBS pushes a live audio stream to a mountpoint, and Icecast relays that one stream to many listeners. It speaks Ogg Vorbis, Opus and MP3, and publishes M3U and XSPF playlists that any media player understands. It also has a public status page and a password-protected admin interface for managing mountpoints and listeners.
This guide covers launching and using the Icecast 2.4.4 on Ubuntu 24.04 AMI on Amazon EC2. It is one version of the SecureAnyCloud media servers listing on AWS Marketplace. Select it as the software version when you subscribe and launch.
Upstream Icecast ships the well-known default password hackme and serves everything, admin logins included, over plain HTTP. This image turns that around.
What you get:
- HTTPS from the first boot. nginx serves the status page, the admin interface and the listener streams on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
- Source clients over TLS. Broadcasters connect to port 8443 with TLS switched on, so the source password never crosses the network in clear text. Every Icecast source protocol works unchanged.
- Three passwords unique to your instance. Admin, source and relay passwords are generated on first boot and written to
/root/icecast-credentials.txt. They are independent, so a presenter with the source password has no admin access. Thehackmedefault appears nowhere and never works. - Fail closed. Icecast refuses to start while its configuration still holds an unset template value or the upstream default, and nginx refuses to start until first boot has finished.
- Icecast on loopback. Icecast itself listens only on
127.0.0.1:8000, and nginx is the only service on the network. Requests for host names the instance does not serve are dropped. - Admin interface protected against cross-site requests. Icecast's admin actions are plain links, so requests that a browser marks as coming from another site are refused, and sign-in attempts are rate-limited.
- Hardened defaults. Icecast runs as its own unprivileged user in a systemd sandbox, Icecast and nginx are both blocked from the instance metadata service, and the AMI requires IMDSv2.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
- What is on the image: Icecast 2.4.4 (the stock Ubuntu 24.04
icecast2package, so it inherits Ubuntu's security maintenance), nginx with its stream module, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. - Defaults: default user
ubuntu, architecture x86_64, recommended instance type m5.large.
Prerequisites
Before you deploy this image you need:
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet
- A security group that allows the following inbound traffic:
- TCP 22 (SSH) from your own networks only
- TCP 443 (status page, admin interface and listeners) from wherever your listeners are, usually anywhere
- TCP 80 (redirects to HTTPS) from the same sources as 443
- TCP 8443 (source clients over TLS) from your broadcasters' networks only
Icecast relays rather than re-encodes, so it is light on CPU, and listener count is mostly a bandwidth question. A 128 kbit/s stream to 100 listeners needs about 13 Mbit/s outbound.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Icecast 2.4.4 on Ubuntu 24.04 as the software version, choose your Region, then choose Launch through EC2. Choose m5.large, your key pair and a security group as above.
Alternatively, launch with the AWS CLI. Replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=icecast}]'Connect to your instance
Connect over SSH as the user for your software version:
- Icecast 2.4.4 on Ubuntu 24.04: SSH user ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
First boot generates the certificate and the three passwords, then starts Icecast and nginx. Confirm that the services are running:
systemctl is-active icecast2 nginx icecast-firstboot
sudo test -f /var/lib/sac/data/icecast-firstboot.done && echo FIRSTBOOT_DONEAll three units are active and the first boot marker is present:
active active active FIRSTBOOT_DONEnginx is the only service on public addresses (80, 443 and 8443), and Icecast listens on loopback:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | sed -E 's/pid=[0-9]+,fd=[0-9]+/.../g' | sort0.0.0.0:22 users:(("sshd",...),("systemd",...)) 0.0.0.0:443 users:(("nginx",...),("nginx",...),("nginx",...)) 0.0.0.0:80 users:(("nginx",...),("nginx",...),("nginx",...)) 0.0.0.0:8443 users:(("nginx",...),("nginx",...),("nginx",...)) 127.0.0.1:8000 users:(("icecast2",...)) 127.0.0.53%lo:53 users:(("systemd-resolve",...)) 127.0.0.54:53 users:(("systemd-resolve",...)) [::]:22 users:(("sshd",...),("systemd",...)) [::]:443 users:(("nginx",...),("nginx",...),("nginx",...)) [::]:80 users:(("nginx",...),("nginx",...),("nginx",...)) [::]:8443 users:(("nginx",...),("nginx",...),("nginx",...))Get your URLs and passwords
Read the credentials file:
sudo cat /root/icecast-credentials.txtThe file is readable by root only:
ICECAST_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ ICECAST_ADMIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/admin/ ICECAST_ADMIN_USER=admin ICECAST_ADMIN_PASSWORD=<ICECAST_ADMIN_PASSWORD> ICECAST_SOURCE_HOST=ec2-<public-ip-dashed>.<region>.compute.amazonaws.com ICECAST_SOURCE_PORT=8443 ICECAST_SOURCE_USER=source ICECAST_SOURCE_PASSWORD=<ICECAST_SOURCE_PASSWORD> ICECAST_RELAY_USER=relay ICECAST_RELAY_PASSWORD=<ICECAST_RELAY_PASSWORD>ICECAST_ADMIN_PASSWORDsigns you in to theadmininterface as user admin.ICECAST_SOURCE_PASSWORDis what asourceclient uses, with user source, to start broadcasting.ICECAST_RELAY_PASSWORDis used by another Icecast server pulling a relay from this one.
The URLs use the instance's public DNS name from EC2 instance metadata. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too. To use your own DNS name, see Step 9.
When you need to share the file, for example in a support request, print it with the passwords masked:
sudo sed -E 's/^(ICECAST_[A-Z_]*PASSWORD=).*/\1********/' /root/icecast-credentials.txt | grep -E '^ICECAST_'Check the server from the command line
Port 80 redirects to HTTPS, the health check is open for load balancers, and Icecast reports its version. Check each in turn:
H=$(sudo grep '^ICECAST_URL=' /root/icecast-credentials.txt | sed -E 's#^ICECAST_URL=https://([^/]+)/.*#\1#')
curl -s -o /dev/null -w 'http:// -> %{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'healthz -> HTTP %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/healthz"
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/status-json.xsl" | jq -r '.icestats.server_id'http:// -> 301 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ healthz -> HTTP 200 Icecast 2.4.4The admin interface refuses a request with no password and one with the upstream default, and accepts this instance's admin password. The password is passed to curl on standard input, so it never appears in the process list or your shell history:
sudo bash -c ' F=/root/icecast-credentials.txt P=$(grep "^ICECAST_ADMIN_PASSWORD=" $F | cut -d= -f2-) H=$(grep "^ICECAST_URL=" $F | sed -E "s#^ICECAST_URL=https://([^/]+)/.*#\1#") R="--resolve $H:443:127.0.0.1" curl -sk $R -o /dev/null -w "admin, no password -> HTTP %{http_code}\n" "https://$H/admin/stats" printf "user = \"admin:hackme\"\n" | curl -K - -sk $R -o /dev/null -w "admin:hackme -> HTTP %{http_code}\n" "https://$H/admin/stats" printf "user = \"admin:%s\"\n" "$P" | curl -K - -sk $R -o /dev/null -w "admin, per-instance -> HTTP %{http_code}\n" "https://$H/admin/stats" 'admin, no password -> HTTP 401 admin:hackme -> HTTP 401 admin, per-instance -> HTTP 200Send a test stream
This test pushes one megabyte of test data as an MP3 source over TLS on port 8443, plays it back as a listener on port 443, and shows the listen URL that Icecast advertises. Nothing is left behind:
sudo bash -c ' F=/root/icecast-credentials.txt S=$(grep "^ICECAST_SOURCE_PASSWORD=" $F | cut -d= -f2-) H=$(grep "^ICECAST_URL=" $F | sed -E "s#^ICECAST_URL=https://([^/]+)/.*#\1#") R="--resolve $H:443:127.0.0.1 --resolve $H:8443:127.0.0.1" T=$(mktemp); head -c 1048576 /dev/urandom > $T printf "user = \"source:%s\"\n" "$S" | curl -K - -sk $R -o /dev/null -m 15 --limit-rate 32k -X PUT \
-H "Content-Type: audio/mpeg" -H "Ice-Name: test" -H "Expect:" -T $T "https://$H:8443/test.mp3" & sleep 4 echo "listener received $(curl -sk $R -m 4 "https://$H/test.mp3" | wc -c | awk "{print (\$1 > 1000) ? \"audio\" : \"nothing\"}")" curl -sk $R "https://$H/status-json.xsl" | jq -r ".icestats.source.listenurl" wait; rm -f $T 'listener received audio https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/test.mp3Connect your source client
A source client runs on your machine and pushes audio to a mountpoint. Use the values from Step 4, and switch TLS (or SSL) on:
Server / host : ICECAST_SOURCE_HOST (or your DNS name from Step 9) Port : 8443 with TLS / SSL enabled Mountpoint : /live.mp3 (or /live.ogg, /live.opus) Username : source Password : the ICECAST_SOURCE_PASSWORD value Format : MP3, Ogg Vorbis or Opus- butt (Broadcast Using This Tool): add an Icecast server on port 8443, and tick Use TLS. Accept the certificate when butt asks, or install your own certificate (Step 9).
- liquidsoap:
output.icecast(%mp3, host="<host>", port=8443, password="<source password>", mount="/live.mp3", transport=http.transport.tls(), ...). - ffmpeg, for example to stream a file on a loop:
ffmpeg -re -stream_loop -1 -i music.mp3 -c:a libmp3lame -b:a 128k -f mp3 \
-method PUT -content_type audio/mpeg -chunked_post 0 -send_expect_100 0 -auth_type basic \
-headers $'Ice-Name: My Station\r\n' -tls_verify 0 \
"https://source:<ICECAST_SOURCE_PASSWORD>@<ICECAST_SOURCE_HOST>:8443/live.mp3"A client without TLS support can reach Icecast through an SSH tunnel instead. Run ssh -i <your-key.pem> -L 8000:127.0.0.1:8000 ubuntu@<public-ip>, then point the client at localhost, port 8000.
Once the client connects, the mountpoint appears on the status page. Listeners tune in at https://<your-host>/live.mp3, or open the M3U playlist link in any player.
Use the status page and the admin interface
Open ICECAST_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time (or install your own, Step 9). The public status page lists every active mountpoint with its stream name, description, content type, listener count and current track, with M3U and XSPF playlist links.
Open ICECAST_ADMIN_URL and sign in as admin with the admin password. Admin Home shows the global server statistics, including the configured host and the server version.
Mountpoint List shows each mountpoint with its controls. List Clients shows who is connected. Move Listeners moves an audience to another mountpoint without dropping it. Update Metadata changes the track title that listeners see. Kill Source disconnects the broadcaster.
List Clients shows each connected listener with a Kick action. Because listeners reach Icecast through nginx, the IP column shows 127.0.0.1. The real listener addresses are in /var/log/nginx/access.log, and source connections on port 8443 are logged in /var/log/nginx/icecast-source.log. To block an address, use your security group or an nginx deny rule.
Use your own DNS name and certificate
Point a DNS record at the instance (an Elastic IP keeps the address stable), then tell the instance its name. This command regenerates the self-signed certificate for that name, updates the stream URLs that Icecast advertises and the credentials file, and reloads nginx and Icecast:
sudo icecast-set-hostname radio.your-domain.exampleTo use a certificate from a public CA instead, replace /etc/ssl/icecast/icecast.crt (full chain) and /etc/ssl/icecast/icecast.key (mode 0600) and run sudo systemctl reload nginx. The same certificate serves port 443 and port 8443.
Security checks
The upstream default password is nowhere in the configuration, Icecast listens only on loopback, and it cannot start without the first-boot passwords:
sudo grep -c hackme /etc/icecast2/icecast.xml || echo "0 (the upstream default password is not in the configuration)"
sudo grep -E '<(port|bind-address)>' /etc/icecast2/icecast.xml systemctl show icecast2 -p Requires --value0 0 (the upstream default password is not in the configuration) <port>8000</port> <bind-address>127.0.0.1</bind-address> icecast-firstboot.service -.mount system.slice sysinit.targetIcecast and nginx are blocked from the instance metadata service, so nothing Icecast fetches (relays, URL authentication) can reach your instance's credentials:
systemctl show icecast2 nginx -p IPAddressDeny --value169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32Maintenance
- Configuration. The configuration file is
/etc/icecast2/icecast.xml. Apply changes withsudo systemctl restart icecast2. Common changes are raising<clients>in<limits>for a larger audience, and adding<mount>sections for per-mountpoint limits, fallbacks or authentication. Keep the single listen socket on127.0.0.1:8000, because nginx publishes it and Icecast refuses to start with any other socket layout. - Changing a password. Edit
<source-password>,<relay-password>or<admin-password>(12 or more characters) in/etc/icecast2/icecast.xml, restart Icecast and update/root/icecast-credentials.txt. First boot runs only once, so it never overwrites your changes. - Logs. Icecast logs are in
/var/log/icecast2/, and nginx logs, with the real client addresses, are in/var/log/nginx/. - Backups. Icecast keeps no database and records nothing by default. The configuration file is the only state worth keeping.
- Security updates. Unattended security upgrades are on. Reboot when a new kernel is installed.
Support
SecureAnyCloud provides 24/7/365 expert technical support for this image. Contact sales@secureanycloud.com.
Icecast is developed by the Xiph.Org Foundation and licensed under the GNU General Public License version 2. The corresponding source is available from the Ubuntu archive with apt-get source icecast2. SecureAnyCloud provides this image, which is not affiliated with or endorsed by the Xiph.Org Foundation.
Deploy on AWS
Launch Icecast 2.4.4 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com