- Rust 78.7%
- XSLT 10.7%
- Shell 4.4%
- Makefile 4.2%
- Python 1%
- Other 1%
icecast now obtains and renews its own TLS certificate on a schedule set in icecast.xml, replacing the external acme.sh + cron arrangement. The <acme> block previously parsed only <domain>/<email>; <challenge>, <dns-provider> and <dns-api-key> were silently discarded, so the configured Cloudflare credential had never done anything. Renewals are zero-downtime. CertStore implements rustls' ResolvesServerCert and setup_tls() builds the ServerConfig with .with_cert_resolver() rather than .with_single_cert(). The TlsAcceptor is cloned into every listener and connection, so replacing it would be invasive; the resolver is consulted per handshake instead, and a renewal only swaps the value inside the store. No restart, no dropped listeners. <ca> (alias <provider>) selects zerossl (default), letsencrypt, letsencrypt-staging, or a full directory URL. ZeroSSL mandates External Account Binding; with no <eab-kid>/<eab-hmac-key> configured, credentials are minted from <email> automatically. Note ExternalAccountKey::new wants the raw HMAC bytes while CAs issue base64 (URL-safe, often unpadded) - passing the encoded string through yields signatures the CA rejects. Account credentials are CA-specific, so each CA gets its own acme-account-<slug>.json. The weekly slot is a check, not an unconditional reissue; an order is only placed inside the <renew-within-days> window. Every failure path leaves the previously loaded certificate in place, so a failed renewal means "retry next window", never "TLS is down". Also in server.rs: <cert-dir> is now authoritative and exclusive in resolve_tls_paths(). It was write-only before, so setting it would renew into one path while continuing to load another, and an unrelated certificate in a hardcoded legacy path could mask it entirely. admin/listclients.xsl is taken from the deployment server, which renders geoip city/region/country. Also lands previously uncommitted working-tree changes to the mp3/ICY framing, file-fallback and lenient HTTP parsing paths. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| admin | ||
| hk | ||
| iceplay | ||
| icesend | ||
| tests | ||
| web | ||
| .gitignore | ||
| build.sh | ||
| COPYING | ||
| LICENSE | ||
| README.md | ||
icecast-hk
Clean-room Rust rewrite of an Icecast2-compatible streaming server.
hk/-- the Rust server (builds theicecastbinary)admin/-- admin + status XSL templates (pointadminroothere)web/-- static web assets (pointwebroothere)icesend/,iceplay/-- optional helper tools (build with./build.sh --tools)
The hk build produces a binary named icecast that accepts the same config files, CLI flags, and XSL templates as upstream Icecast2.
Quick build
On Linux, FreeBSD, or macOS, the build.sh helper checks your toolchain and native dependencies, then builds the server in one step:
./build.sh # release build -> hk/target/release/icecast
./build.sh --tools # also build the icesend / iceplay helper tools
./build.sh --debug # fast unoptimised build
./build.sh --static # fully static musl build (Linux only)
./build.sh --help # all options
It finds libxml2/libxslt through pkg-config (and on macOS adds Homebrew's keg-only pkgconfig directories automatically); if something is missing it prints the exact install command for your platform. The manual instructions below do the same thing by hand.
Windows is not supported. The server relies on Unix-only facilities (signal handling, privilege drop,
chroot, daemonising). Build and run it under WSL2.
Build requirements
Builds on Linux, FreeBSD, and macOS (not Windows — see above).
- Rust 1.75+ (stable)
pkg-configlibxml2development headerslibxsltdevelopment headers
Build on Linux/amd64 (glibc)
Tested on Debian 12, Ubuntu 22.04+, Fedora 38+.
Debian / Ubuntu
sudo apt-get install build-essential pkg-config libxml2-dev libxslt1-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cd hk
cargo build --release
Binary: target/release/icecast
Fedora / RHEL / Rocky
sudo dnf install gcc pkg-config libxml2-devel libxslt-devel
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cd hk
cargo build --release
Arch
sudo pacman -S base-devel pkgconf libxml2 libxslt
cd hk
cargo build --release
Build on Linux/amd64 (musl) -- fully static binary
Useful for Alpine containers or single-binary deployment to any Linux box.
Alpine
apk add build-base pkgconf libxml2-dev libxslt-dev libxml2-static libxslt-static zlib-static xz-static
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cd hk
RUSTFLAGS='-C target-feature=+crt-static' cargo build --release --target x86_64-unknown-linux-musl
Binary: target/x86_64-unknown-linux-musl/release/icecast
Cross-compile musl from glibc host (Debian/Ubuntu)
sudo apt-get install build-essential pkg-config musl-tools libxml2-dev libxslt1-dev
rustup target add x86_64-unknown-linux-musl
cd hk
PKG_CONFIG_ALLOW_CROSS=1 \
RUSTFLAGS='-C target-feature=+crt-static' \
cargo build --release --target x86_64-unknown-linux-musl
Note: cross-compiling musl with dynamically-linked libxml2/libxslt from the host works but produces a binary that still dynamically links those two libraries. For a fully static binary, build natively on Alpine as shown above.
Build on FreeBSD
sudo pkg install rust pkgconf libxml2 libxslt
cd hk
cargo build --release
Build on macOS
Requires the Xcode command-line tools and Homebrew:
brew install rust pkg-config libxml2 libxslt
# libxml2/libxslt are keg-only, so point pkg-config at them:
export PKG_CONFIG_PATH="$(brew --prefix libxml2)/lib/pkgconfig:$(brew --prefix libxslt)/lib/pkgconfig"
cd hk
cargo build --release
(./build.sh exports PKG_CONFIG_PATH for you, so on macOS you can just run that instead.)
Install
sudo cp target/release/icecast /usr/bin/icecast
The binary is a drop-in replacement -- point it at your existing icecast.xml and admin/web directories:
icecast -c /etc/icecast.xml
CLI
icecast -c <config> Start with config file
icecast -b Background (daemonize)
icecast -v Print version
icecast -V Verbose version
Runtime dependencies
The binary links dynamically against libxml2 and libxslt at runtime (unless built static on Alpine). These are the same libraries upstream Icecast requires, so an existing Icecast deployment already has them.
License
This repository is under two licenses:
- ice-hk code (
hk/,icesend/,iceplay/, and the test tooling) — the ice-hk License: use it however you like, subject to a perpetual attribution requirement. The required notice must be reproduced in copies and in derivatives at any fork depth, including program banners and UI/documentation footers. - Web interface (
admin/,web/) — Karl Heyes' Icecast-KH UI, licensed GPL-2.0 (seeCOPYING), until it is replaced by original work.