Icecast 2.4.4 on AWS User Guide
Overview
This guide covers launching and using the Icecast 2.4.4 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg media servers listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
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, publishes M3U and XSPF playlists any media player understands, and has a public status page plus a password protected admin interface for managing mountpoints and listeners.
Upstream Icecast ships the well known default password hackme and serves everything, admin logins included, over plain HTTP. The cloudimg image turns that around:
- 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.hackmeappears nowhere and never works. - Fail closed. Icecast refuses to start while its configuration still holds a placeholder 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; 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 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 icecast2 package, so it inherits Ubuntu's security maintenance), nginx with its stream module, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- 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:
- 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; listener count is mostly a bandwidth question. A 128 kbit/s stream to 100 listeners needs about 13 Mbit/s outbound.
Step 1: 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 and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above.
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}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Icecast 2.4.4 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
First boot generates the certificate and the three passwords, then starts Icecast and nginx:
systemctl is-active icecast2 nginx icecast-firstboot
sudo test -f /var/lib/cloudimg/icecast-firstboot.done && echo FIRSTBOOT_DONE
All three units are active and the first boot marker is present:
active
active
active
FIRSTBOOT_DONE
nginx is the only service on public addresses (80, 443 and 8443); Icecast listens on loopback:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | sed -E 's/pid=[0-9]+,fd=[0-9]+/.../g' | sort
0.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",...))
Step 4: Get your URLs and passwords
sudo cat /root/icecast-credentials.txt
The 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 the admin interface as useradmin.ICECAST_SOURCE_PASSWORDis what a source client uses, with usersource, 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_'
Step 5: 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:
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.4
The admin interface refuses a request with no password and 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 200
Step 6: Send a test stream
This 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 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.mp3
Step 7: Connect 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, 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: ssh -i <your-key.pem> -L 8000:127.0.0.1:8000 ubuntu@<public-ip>, then point the client at localhost, port 8000.
Once connected, the mountpoint appears on the status page and listeners tune in at https://<your-host>/live.mp3, or open the M3U playlist link in any player.
Step 8: 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, Move Listeners to move an audience to another mountpoint without dropping it, Update Metadata to change the track title listeners see, and Kill Source to disconnect 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.

Step 9: 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 regenerates the self signed certificate for that name, updates the stream URLs Icecast advertises and the credentials file, and reloads nginx and Icecast:
sudo icecast-set-hostname radio.your-domain.example
To 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.
Step 10: 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 --value
0
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.target
Icecast 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 --value
169.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/32
Maintenance
- Configuration:
/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: 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 in
/var/log/icecast2/, nginx (with the real client addresses) 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
cloudimg provides 24/7/365 expert technical support for this image. Contact support@cloudimg.co.uk. 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. This image is provided by cloudimg and is not affiliated with or endorsed by the Xiph.Org Foundation.