MistServer
Overview
MistServer is a full-featured, broadcast-grade open source streaming media server. A publisher such as OBS Studio, ffmpeg or a hardware encoder pushes a live feed over RTMP, and MistServer republishes it in real time as HLS, MPEG DASH, WebRTC, progressive HTTP, MP4 and RTMP for low-latency playback in browsers and native players. Everything is driven from the MistController web management interface, backed by a JSON API for automation.
This SecureAnyCloud image installs the official prebuilt MistServer (verified at 3.11.1) into /usr/bin, running as the unprivileged mistserver service. It is secure by default: there is no default login, and every VM generates its own credentials on first boot.
What you get:
- MistServer (verified at 3.11.1), the official prebuilt build, running as an unprivileged system user
- The MistController web management interface and JSON API on
127.0.0.1:4242, bound to loopback and served over HTTPS on port 443 by nginx - RTMP ingest on port 1935, and a multi-protocol HTTP output (HLS, MPEG DASH, progressive TS, MP4, FLV) on port 8080
mistserver-firstboot.service, which generates three independent secrets on each VM's first boot: a MistServer administrator password for the management interface and API, an HTTP Basic credential that protects the network-facing management surface, and a passphrase that every RTMP publisher must supply to push a stream- A per-VM admin password, an HTTPS Basic credential and an RTMP push passphrase in a root-only
0600file. MistController refuses to start unless a per-VM administrator account exists, so an instance can never come up in the insecure open mode, and no two VMs share a credential. Nothing is baked into the image. - HTTPS by default: the MistController interface on
127.0.0.1:4242is reachable only through the nginx reverse proxy on port 443, which terminates TLS with a self-signed certificate regenerated per VM. An unauthenticated request to the management surface returns401until the administrator credential is supplied. - ffmpeg and the
mist-selftestend-to-end verification helper.mist-selftestpublishes a short test pattern over the passphrase-protected RTMP endpoint, pulls it back over the HTTP output as MPEG transport stream and HLS, authenticates the management API, and confirms that the authentication rules behave as expected. - Ubuntu 24.04 LTS base, patched at build time
- 24/7 SecureAnyCloud support, 24h response SLA
Prerequisites
- An active Azure subscription, an SSH key pair, and a VNet with a subnet.
- Recommended VM size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and a handful of streams, or Standard_D2s_v5 or larger for production workloads with many concurrent viewers.
- Sustained throughput scales with the number of concurrent publishers and viewers and with the bitrate of each stream. Live streams are relayed in real time, so plan for outbound network bandwidth rather than disk.
Deploy from the Azure Portal
In the Azure Marketplace, search for MistServer on Ubuntu 24.04 and choose your VM size. Attach a network security group (NSG) that allows:
- TCP 22 (SSH) from your management network
- TCP 443 (HTTPS management interface) from your administrators
- TCP 1935 (RTMP ingest) from your publishers
- TCP 8080 (HLS / DASH / HTTP playback) from the networks and players that consume the stream
Deploy from the Azure CLI
Create the VM from the Azure CLI:
RG="mistserver-prod"; LOCATION="eastus"; VM_NAME="mist-01" IMAGE_URN="sac1647283583153:mistserver-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name mist-vnet --address-prefix 10.90.0.0/16 --subnet-name mist-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name mist-nsg az network nsg rule create -g "$RG" --nsg-name mist-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name mist-nsg --name allow-https --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name mist-nsg --name allow-rtmp --priority 120 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 1935 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name mist-nsg --name allow-play --priority 130 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 8080 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:mistserver-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name mist-vnet --subnet mist-subnet --nsg mist-nsg --public-ip-sku StandardConnect over SSH
Connect to the VM over SSH:
ssh azureuser@<vm-ip>Verify the service is running
MistServer runs as mistserver.service, with nginx terminating TLS in front of the loopback-bound management interface. RTMP ingest listens on port 1935 and the multi-protocol HTTP output on port 8080. An unauthenticated HTTPS health endpoint is provided for load balancer probes. Check the services and ports:
systemctl is-active mistserver nginx ss -tln | grep -E '127.0.0.1:4242 |:1935 |:8080 ' curl -ks https://127.0.0.1/healthzThe output shows both services active, the MistController API bound to 127.0.0.1:4242, RTMP on 1935, the HTTP output on 8080, and ok from the health endpoint.
Read your per-VM secrets
This VM's first boot generated its secrets and stored them in a root-only file. The MistServer administrator password is used for both the HTTPS Basic auth prompt and the MistController login, and the RTMP push passphrase protects publishing. Read the file and keep its contents secret. Then confirm that unauthenticated requests to the management interface are rejected:
sudo cat /root/mistserver-credentials.txt echo "unauthenticated https management -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' https://127.0.0.1/)"The file holds MIST_ADMIN_USER, MIST_ADMIN_PASSWORD and MIST_PUSH_PASSPHRASE, and is owned root:root with mode 0600. An unauthenticated call to the management interface returns 401 because it is behind the per-VM credential.
Open the MistController management interface
Browse to https://<vm-ip>/ and accept the self-signed certificate. Your browser first prompts for the HTTPS Basic credential. Enter admin and your MIST_ADMIN_PASSWORD. The MistController interface then presents its own login. Enter the same administrator username and password.
Both layers use the per-VM credential from /root/mistserver-credentials.txt, so the management surface is never reachable anonymously. After you sign in, the Overview page shows the running MistServer version, the enabled ingest and output protocols, and the configured and active stream counts.
Publish a stream and play it back
The image ships with a stream named live that accepts an RTMP push protected by your per-VM passphrase. A publisher supplies the passphrase as the RTMP application segment, so the publish URL is rtmp://<vm-ip>:1935/<passphrase>/live, where <passphrase> is your MIST_PUSH_PASSPHRASE.
Point OBS at the server rtmp://<vm-ip>:1935/<passphrase> with the stream key live, or publish from ffmpeg:
# Publish a file or a live source to the passphrase-protected RTMP endpoint: ffmpeg -re -i input.mp4 -c copy -f flv "rtmp://<vm-ip>:1935/<passphrase>/live"Play the stream back over the HTTP output, either as HLS in a browser or native player or as a progressive MPEG transport stream:
# HLS playlist (browsers, iOS, native players): ffplay "http://<vm-ip>:8080/hls/live/index.m3u8"
# Progressive MPEG-TS: ffplay "http://<vm-ip>:8080/live.ts"The published live stream appears in the MistController Streams panel with its state, viewers and inputs. Left-click a stream to preview it in the browser.
To verify the whole pipeline end to end at any time, run the bundled self-test. It publishes a short test pattern to the passphrase-protected RTMP endpoint and confirms that the management API lists the live stream. It pulls the stream back over the HTTP output as MPEG transport stream and HLS, authenticates the management API, and proves that an unauthenticated management request and a publish with a wrong passphrase are both refused:
sudo mist-selftestThe output is a single OK line. It confirms that the passphrase publish, the MPEG-TS and HLS pull and the authenticated management interface all worked, and that the unauthenticated and wrong-passphrase attempts were refused.
Protocols, runtime and hardening
The Protocols panel in the management interface lists every enabled ingest and output connector. RTMP ingest and the base HTTP output are active on their ports. The HLS, MPEG DASH (CMAF), progressive TS, MP4 and FLV outputs are enabled and served through the HTTP output on port 8080.
On first boot, a one-shot service generates all three per-VM secrets, and only then does MistController start, so the insecure open mode is never reachable. The OS is patched at build time and ships with unattended security upgrades enabled. Check the version, service state and held packages:
MistController -v 2>&1 | head -1 systemctl is-enabled mistserver nginx apt-mark showholdThe output shows MistServer 3.11.1, both services enabled, and apt-mark showhold printing nothing (no held packages). mistserver-firstboot.service is a one-shot unit that runs once on first boot to generate the per-VM secrets and then disables itself.
Use a real certificate for production
The management interface ships with a self-signed certificate that is regenerated per VM. For production, replace it with a certificate from a trusted CA, or front the VM with an Azure Application Gateway that terminates TLS. To install a Let's Encrypt certificate for the management interface with your own domain, run:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>For public playback, note that the HTTP output on port 8080 is plain HTTP. Front it with a CDN or a TLS-terminating reverse proxy so viewers receive HTTPS, and restrict port 8080 in the NSG so that only the proxy or CDN reaches the origin.
Security and operations notes
- Rotate the secrets. The per-VM secrets live in
/etc/mistserver/secrets.env(the machine-readable copy), the MistController account in/etc/mistserver.conf(stored MD5-hashed), and the nginx Basic credential in/etc/nginx/mistserver.htpasswd. All are recorded in/root/mistserver-credentials.txt. To regenerate a fresh set, remove the first-boot sentinel/var/lib/sac/data/mistserver-firstboot.doneand reboot. - Restrict the ports. Expose port 1935 only to trusted publishers, port 8080 to your players or CDN, and port 443 to your administrators. The MistController interface is bound to loopback and is reachable only through the authenticated nginx proxy.
- Use the push passphrase. Every RTMP publisher must supply your
MIST_PUSH_PASSPHRASEas the application segment of the RTMP URL (rtmp://<vm-ip>:1935/<passphrase>/<stream>). A push with a wrong or missing passphrase is refused. - Scale out. For many concurrent viewers, put a CDN or an nginx cache in front of the HLS and DASH endpoints on port 8080, or run several instances behind a load balancer.
Support
Every SecureAnyCloud image includes 24/7 support with a 24-hour response SLA. Email sales@secureanycloud.com with the offer name and your VM details.
MistServer is developed by DDVTech and released into the public domain under the Unlicense. The SecureAnyCloud charge covers packaging, security patching, image maintenance and support.
Deploy on Azure
Launch MistServer on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
MistServer is a full-featured, broadcast-grade open source streaming media server. A publisher such as OBS Studio, ffmpeg or a hardware encoder pushes a live feed over RTMP, and MistServer republishes it in real time as HLS, MPEG DASH, WebRTC, progressive HTTP, MP4 and RTMP for low-latency playback in browsers and native players. Everything is driven from the MistController web management interface, backed by a JSON API for automation.
This SecureAnyCloud image installs the official prebuilt MistServer (verified at 3.11.1) into /usr/bin, running as the unprivileged mistserver service. It is secure by default: there is no default login, and every instance generates its own credentials on first boot.
What you get:
- MistServer (verified at 3.11.1), the official prebuilt build, running as an unprivileged system user
- The MistController web management interface and JSON API on
127.0.0.1:4242, bound to loopback and served over HTTPS on port 443 by nginx - RTMP ingest on port 1935, and a multi-protocol HTTP output (HLS, MPEG DASH, progressive TS, MP4, FLV) on port 8080
mistserver-firstboot.service, which generates three independent secrets on each instance's first boot: a MistServer administrator password for the management interface and API, an HTTP Basic credential that protects the network-facing management surface, and a passphrase that every RTMP publisher must supply to push a stream- A per-instance admin password, an HTTPS Basic credential and an RTMP push passphrase in a root-only
0600file. MistController refuses to start unless a per-instance administrator account exists, so an instance can never come up in the insecure open mode, and no two instances share a credential. Nothing is baked into the image. - HTTPS by default: the MistController interface on
127.0.0.1:4242is reachable only through the nginx reverse proxy on port 443, which terminates TLS with a self-signed certificate regenerated per instance. An unauthenticated request to the management surface returns401until the administrator credential is supplied. - ffmpeg and the
mist-selftestend-to-end verification helper.mist-selftestpublishes a short test pattern over the passphrase-protected RTMP endpoint, pulls it back over the HTTP output as MPEG transport stream and HLS, authenticates the management API, and confirms that the authentication rules behave as expected. - Ubuntu 24.04 LTS base, fully patched
- 24/7 SecureAnyCloud support, 24h response SLA
Connecting to your instance
This listing ships as an Amazon Machine Image. Connect over SSH as the default login user for your operating system variant, using the key pair you selected at launch. For Ubuntu 24.04, the login user is ubuntu.
Prerequisites
- An AWS account, an EC2 key pair in your target region, and a VPC with a public subnet.
- Recommended instance type: m5.large (2 vCPU, 8 GB RAM) for evaluation and a handful of streams, or a larger instance for production workloads with many concurrent viewers.
- Sustained throughput scales with the number of concurrent publishers and viewers and with the bitrate of each stream. Live streams are relayed in real time, so plan for outbound network bandwidth rather than disk.
Launch from the AWS Marketplace
Subscribe to the listing in AWS Marketplace and launch an instance from it. Choose your instance type, key pair and subnet. Attach a security group that opens the ports your deployment needs:
- TCP 22 (SSH) from your management network
- TCP 443 (HTTPS management interface) from your administrators
- TCP 1935 (RTMP ingest) from your publishers
- TCP 8080 (HLS, MPEG DASH, HTTP playback) from the networks and players that consume the stream
- TCP 80 (optional): it only redirects to HTTPS and serves an unauthenticated
/healthzprobe
Launch from the AWS CLI
Replace the AMI ID with the one shown on the listing for your region, and restrict the source ranges to your own networks.
AMI_ID="<ami-id>"
# from the Marketplace listing, for your region KEY_NAME="my-keypair" SUBNET_ID="<subnet-id>" VPC_ID="<vpc-id>"
# Security group: SSH + HTTPS management + RTMP ingest + HLS/HTTP playback
SG_ID=$(aws ec2 create-security-group --group-name mistserver-sg \
--description "MistServer" --vpc-id "$VPC_ID" --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG_ID" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG_ID" --protocol tcp --port 443 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG_ID" --protocol tcp --port 1935 --cidr <your-publisher-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG_ID" --protocol tcp --port 8080 --cidr <your-viewer-cidr>
aws ec2 run-instances --image-id "$AMI_ID" --instance-type m5.large \
--key-name "$KEY_NAME" --subnet-id "$SUBNET_ID" --security-group-ids "$SG_ID" \
--associate-public-ip-addressConnect over SSH
Connect as ubuntu, the login user for the Ubuntu 24.04 variant, with your key pair:
ssh -i my-keypair.pem ubuntu@<public-ip>Verify the service is running
MistServer runs as mistserver.service, with nginx terminating TLS in front of the loopback-bound management interface. RTMP ingest listens on port 1935 and the multi-protocol HTTP output on port 8080. An unauthenticated HTTPS health endpoint is provided for load balancer probes. Check the services and ports:
systemctl is-active mistserver nginx ss -tln | grep -E '127.0.0.1:4242 |:1935 |:8080 ' curl -ks https://127.0.0.1/healthzThe output shows both services active, the MistController API bound to 127.0.0.1:4242, RTMP on 1935, the HTTP output on 8080, and ok from the health endpoint.
Read your per-instance secrets
This instance's first boot generated its secrets and stored them in a root-only file. The MistServer administrator password is used for both the HTTPS Basic auth prompt and the MistController login, and the RTMP push passphrase protects publishing. Read the file and keep its contents secret:
sudo cat /root/mistserver-credentials.txtThe file holds MIST_ADMIN_USER, MIST_ADMIN_PASSWORD and MIST_PUSH_PASSPHRASE, and is owned root:root with mode 0600. You can confirm, without printing any secret, that the management surface refuses unauthenticated requests:
echo "unauthenticated https management -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' https://127.0.0.1/)"An unauthenticated call to the management interface returns 401 because it is behind the per-instance credential.
Open the MistController management interface
Browse to https://<public-ip>/ and accept the self-signed certificate. Your browser first prompts for the HTTPS Basic credential. Enter admin and your MIST_ADMIN_PASSWORD. The MistController interface then presents its own login. Enter the same administrator username and password.
Both layers use the per-instance credential from /root/mistserver-credentials.txt, so the management surface is never reachable anonymously. After you sign in, the Overview page shows the running MistServer version, the enabled ingest and output protocols, and the configured and active stream counts.
Publish a stream and play it back
The image ships with a stream named live that accepts an RTMP push protected by your per-instance passphrase. A publisher supplies the passphrase as the RTMP application segment, so the publish URL is rtmp://<public-ip>:1935/<passphrase>/live, where <passphrase> is your MIST_PUSH_PASSPHRASE.
Point OBS at the server rtmp://<public-ip>:1935/<passphrase> with the stream key live, or publish from ffmpeg:
# Publish a file or a live source to the passphrase-protected RTMP endpoint: ffmpeg -re -i input.mp4 -c copy -f flv "rtmp://<public-ip>:1935/<passphrase>/live"Play the stream back over the HTTP output, either as HLS in a browser or native player or as a progressive MPEG transport stream:
# HLS playlist (browsers, iOS, native players): ffplay "http://<public-ip>:8080/hls/live/index.m3u8"
# Progressive MPEG-TS: ffplay "http://<public-ip>:8080/live.ts"The published live stream appears in the MistController Streams panel with its state, viewers and inputs. Left-click a stream to preview it in the browser.
To verify the whole pipeline end to end at any time, run the bundled self-test. It publishes a short test pattern to the passphrase-protected RTMP endpoint and confirms that the management API lists the live stream. It pulls the stream back over the HTTP output as MPEG transport stream and HLS, authenticates the management API, and proves that an unauthenticated management request and a publish with a wrong passphrase are both refused:
sudo mist-selftestThe output is a single OK line. It confirms that the passphrase publish, the MPEG-TS and HLS pull and the authenticated management interface all worked, and that the unauthenticated and wrong-passphrase attempts were refused.
Protocols, runtime and hardening
The Protocols panel in the management interface lists every enabled ingest and output connector. RTMP ingest and the base HTTP output are active on their ports. The HLS, MPEG DASH (CMAF), progressive TS, MP4 and FLV outputs are enabled and served through the HTTP output on port 8080.
On first boot, a one-shot service generates all three per-instance secrets, and only then does MistController start, so the insecure open mode is never reachable. The OS is fully patched with unattended security upgrades enabled. Check the version, service state and held packages:
MistController -v systemctl is-enabled mistserver nginx apt-mark showholdThe output shows MistServer 3.11.1, both services enabled, and apt-mark showhold printing nothing (no held packages). mistserver-firstboot.service is a one-shot unit that runs once on first boot to generate the per-instance secrets and then disables itself.
Use a real certificate for production
The management interface ships with a self-signed certificate that is regenerated per instance. For production, replace it with a certificate from a trusted CA, or front the instance with an Application Load Balancer that terminates TLS. To install a Let's Encrypt certificate for the management interface with your own domain, run:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comFor public playback, note that the HTTP output on port 8080 is plain HTTP. Front it with a CDN or a TLS-terminating reverse proxy so viewers receive HTTPS, and restrict port 8080 in the security group so that only the proxy or CDN reaches the origin.
Security and operations notes
- Rotate the secrets. The per-instance secrets live in
/etc/mistserver/secrets.env(the machine-readable copy), the MistController account in/etc/mistserver.conf(stored MD5-hashed), and the nginx Basic credential in/etc/nginx/mistserver.htpasswd. All are recorded in/root/mistserver-credentials.txt. To regenerate a fresh set, remove the first-boot sentinel/var/lib/sac/data/mistserver-firstboot.doneand reboot. - Restrict the ports. Expose port 1935 only to trusted publishers, port 8080 to your players or CDN, and port 443 to your administrators. The MistController interface is bound to loopback and is reachable only through the authenticated nginx proxy.
- Use the push passphrase. Every RTMP publisher must supply your
MIST_PUSH_PASSPHRASEas the application segment of the RTMP URL (rtmp://<public-ip>:1935/<passphrase>/<stream>). A push with a wrong or missing passphrase is refused. - Scale out. For many concurrent viewers, put a CDN or an nginx cache in front of the HLS and DASH endpoints on port 8080, or run several instances behind a load balancer.
Support
Every SecureAnyCloud image includes 24/7 support with a 24-hour response SLA. Email sales@secureanycloud.com with the product name and your instance details.
MistServer is developed by DDVTech and released into the public domain under the Unlicense. The SecureAnyCloud charge covers packaging, security patching, image maintenance and support.
Deploy on AWS
Launch MistServer with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com