Deployment guide

Neko

Overview

Neko is an open-source virtual browser. A real desktop browser runs inside a container on the VM, and its screen and audio are captured, encoded and streamed to viewers over WebRTC, the same low-latency transport used by video calls. Anyone you give access to simply opens a URL, and can watch and take control of a browser running somewhere else entirely. Nothing is installed on the viewer's machine.

This guide covers the deployment and configuration of Neko on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images.

Because the session is shared rather than personal, several people can watch the same browser at once and pass control between them. A built-in chat and an admin role can lock the room, kick users and take control back. That makes Neko useful in three ways:

  • As a collaborative browsing space
  • As a disposable browser that keeps risky sites off your own machine and inside an isolated container
  • As a way to reach an internal web application from anywhere without publishing that application to the internet

The SecureAnyCloud image ships the free and open-source, Apache-2.0 licensed Neko server. It is run the officially supported way, as the upstream container pinned by image digest. This image uses the Firefox flavor, so the browser being streamed is Mozilla Firefox under the MPL-2.0 license and the whole stack is open source. The container is captured into the VM, so your instance starts without downloading anything.

Upstream ships fixed default passwords baked into the image (a user password and an admin password). On a shared-control remote browser, that would mean anyone who found your instance could drive it, so this image never runs on them. A unique user password and a unique admin password are generated on the first boot of every VM, and the browser is held back from starting until that rotation has happened. The image is backed by 24/7 SecureAnyCloud support.

Neko is a trademark of its respective owner and Firefox is a trademark of the Mozilla Foundation. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by either. It ships the free and open-source software, unmodified.

What you get:

  • Neko v3.1.4 (the Apache-2.0 licensed virtual browser server), pinned by image digest
  • Mozilla Firefox (MPL-2.0) as the streamed browser, inside the official upstream container
  • Docker Engine, with the Neko web interface published to the loopback interface only and fronted by nginx on port 80
  • WebRTC media multiplexed onto a single port, 59000, for both UDP and TCP, rather than a hundred-port ephemeral range
  • neko.service, neko-firstboot.service, neko-postboot.service and nginx.service as systemd units, enabled and active on boot
  • A unique user password and a unique admin password generated per VM on first boot, never baked into the image
  • The desktop preset to 1280x720 at 30 fps, a deliberate choice that a single-node VM can encode in software
  • Ubuntu 24.04 LTS base with the latest security patches applied at build time and unattended security upgrades enabled

Before you start: the network rules Neko needs

This is the one part of deploying Neko that is easy to get wrong, so read it before you launch.

Neko needs two kinds of traffic, and they are not the same:

Port Protocol Carries Required?

80 TCP The web interface and its WebSocket signalling Yes

59000 UDP The WebRTC media stream, the primary path Yes

59000 TCP The WebRTC media stream, fallback for networks that block UDP Strongly recommended

WebRTC media does not travel over HTTP, so it cannot be proxied through port 80. If you open only port 80, you will reach the login page and sign in successfully, and then the screen will simply stay black. That is the single most common Neko deployment problem and it is a firewall issue, not a fault in the image.

Allow inbound 80/tcp, 59000/udp and 59000/tcp in the network security group attached to your VM or its subnet. Step 2 shows how.

Restrict the source to your own address range wherever you can, rather than leaving it open to the internet.

Prerequisites

  • An Azure subscription with permission to create VMs and edit network security groups
  • The Azure CLI installed and signed in, if you are deploying from the command line
  • An SSH key pair for administrative access to the VM
  • A modern browser on the viewing side (any current Firefox, Chrome, Edge or Safari supports WebRTC)

Sizing: what this really needs

Neko runs a full desktop, a browser and a software video encoder on the same machine, so it is CPU-hungry. Upstream publishes its own sizing guidance, and it is worth taking seriously.

Resolution vCPU RAM Experience

1024x576 at 30 fps 2 2 GB Not recommended

1280x720 at 30 fps 4 3 GB Good

1280x720 at 30 fps 6 4 GB Recommended

1280x720 at 30 fps 8 4 GB+ Best

Two practical points on top of that:

  • Use a non-burstable VM size. The recommended size for this image is Standard_D4s_v5 (4 vCPU). B-series VMs are credit-limited. Sustained video encoding exhausts the credits and then throttles hard, and the stream becomes visibly choppy. B-series is fine for trying the image out, but it is not suitable for regular use.
  • Plan for concurrency. The encoding cost is per session, so 4 vCPU buys you one comfortable user at 720p30. A handful of people watching the same session costs much less than the same number of independent sessions, because everyone shares one encoded stream. If you want more, add vCPU or lower the resolution rather than expecting it to scale on the same box.

The image ships preset to 1280x720 at 30 fps, rather than the upstream container's own default of 1920x1080 at 60 fps. The upstream default is far heavier than most single-node VMs can encode in software. An admin can change the resolution at runtime from the session settings.

1

Deploy from the Azure Portal

  • In the Azure Portal, search the Marketplace for Neko on Ubuntu 24.04 LTS by SecureAnyCloud, and select Create.
  • Choose your subscription, resource group and region.
  • Set the VM size to Standard_D4s_v5 or larger (see the sizing table above).
  • Provide an administrator username and SSH public key.
  • On the Networking tab, allow inbound HTTP (80). The media ports are added in Step 2, because the portal's basic networking tab does not offer them.
  • Select Review + create, then Create.
2

Deploy from the Azure CLI

Run these commands on your own machine. Replace the resource group, name and region to suit.

az group create --name neko-rg --location eastus
az vm image terms accept --urn sac1647283583153:neko-ubuntu-24-04:default:latest
az vm create \
  --resource-group neko-rg \
  --name neko-vm \
  --image sac1647283583153:neko-ubuntu-24-04:default:latest \
  --size Standard_D4s_v5 \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open the three ports Neko needs. This step makes the media stream work:

az vm open-port --resource-group neko-rg --name neko-vm --port 80 --priority 1001
az network nsg rule create \
  --resource-group neko-rg \
  --nsg-name neko-vmNSG \
  --name neko-webrtc-media \
  --priority 1002 \
  --direction Inbound --access Allow --protocol '*' \
  --destination-port-ranges 59000 \
  --description "Neko WebRTC media, UDP primary and TCP fallback"

To restrict access to your own network instead of the whole internet, add --source-address-prefixes <your.public.ip>/32 to both rules. This is strongly recommended on a shared-control remote browser.

3

Connect to your VM

Connect over SSH:

ssh azureuser@<vm-ip>
4

Confirm the services are running

Check the systemd units:

systemctl is-active docker.service neko-firstboot.service neko.service neko-postboot.service nginx.service

Every line should read active. A compose healthcheck manages the Neko container itself:

sudo docker ps --format 'table {{.Image}}\t{{.Status}}'

You should see the pinned ghcr.io/m1k1o/neko/firefox:3.1.4 image reported as (healthy).

5

Read the per-instance credentials

Two passwords were generated for this VM alone on its first boot: one for the user role and one for the admin role. They are stored in a root-only file.

sudo cat /root/neko-credentials.txt

The file records these values:

Key Meaning

NEKO_USERNAME The display name for the standard role, SecureAnyCloud

NEKO_USER_PASSWORD The per instance password for the user role

NEKO_ADMINNAME The display name for the admin role, admin

NEKO_ADMIN_PASSWORD The per instance password for the admin role

WEB_URL The address to open in your browser

PUBLIC_IP The address this VM advertises to WebRTC clients

The file is 0600 root:root, so only root can read it. To confirm:

sudo stat -c '%a %U:%G' /root/neko-credentials.txt
6

Verify the security model

Upstream Neko ships with fixed default passwords baked into the container image: a user password of neko and an admin password of admin. This image never runs on them, and you can prove that yourself.

Test both upstream defaults. Both are rejected:

curl -s -o /dev/null -w 'upstream default user password: HTTP %{http_code}\n' \
  -X POST http://127.0.0.1/api/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"neko","password":"neko"}'
curl -s -o /dev/null -w 'upstream default admin password: HTTP %{http_code}\n' \
  -X POST http://127.0.0.1/api/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}'

Both return 401.

Next, send an unauthenticated request to a protected endpoint. It is also rejected:

curl -s -o /dev/null -w 'no token: HTTP %{http_code}\n' http://127.0.0.1/api/whoami

This returns 401.

Your per-instance password, by contrast, authenticates and returns a session token:

curl -s -X POST http://127.0.0.1/api/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"<NEKO_USERNAME>","password":"<NEKO_USER_PASSWORD>"}' \
  | head -c 120

The image also holds the browser back until that rotation has happened. neko.service carries a ConditionPathExists on a bootstrap marker that only the first-boot script creates, after it has written the new passwords. If first boot were ever to fail, the browser would not start at all, rather than starting on the published defaults:

grep ConditionPathExists /etc/systemd/system/neko.service

Finally, Neko's Prometheus metrics endpoint is unauthenticated upstream, and its labels carry live session identifiers. This image blocks it at the front door and keeps it available on the loopback interface for your own monitoring:

curl -s -o /dev/null -w 'metrics from outside: HTTP %{http_code}\n' http://127.0.0.1/metrics

This returns 404.

7

Confirm the media path

The WebRTC media is multiplexed onto a single port for both protocols. Check that it is listening:

ss -lntu | grep 59000

The address the VM advertises to clients is resolved on each VM's own first boot and never baked into the image. To see the value in use, run:

grep PUBLIC_IP /root/neko-credentials.txt 2>/dev/null || sudo grep PUBLIC_IP /root/neko-credentials.txt

The image ships a self-test that exercises the whole path end to end, from authentication through to the capture pipeline and the media transport:

sudo /usr/local/sbin/neko-roundtrip.sh
8

Open the session and sign in

Open http://<PUBLIC_IP>/ in your browser. You are asked for a display name and a password.

Enter any display name you like. The password determines your role:

  • NEKO_USER_PASSWORD signs you in as a user, who can watch the browser and request control
  • NEKO_ADMIN_PASSWORD signs you in as an admin, who can additionally lock the room, kick users and take control back

Once connected, the streamed browser appears. This is a real Firefox running on the VM, not a screenshot or a rendered page.

If the interface loads but the screen stays black, the signaling worked and the media did not. That is almost always the firewall. Check that 59000/udp and 59000/tcp are open inbound (see Step 2).

9

Take control and browse

Control is explicit rather than automatic, so two people cannot fight over the mouse. Click the keyboard or mouse icon in the bottom control bar to request control. As an admin, you can take it outright.

Once you have control, the remote browser responds to your mouse and keyboard exactly as a local one would. Press Ctrl+L to focus the address bar, type a URL and press Enter to navigate.

Everything you do happens inside the container on the VM, not on your own machine. Downloads land in the container, and cookies belong to the container. Closing your tab leaves the browser running for anyone else in the session.

10

Share the session

Anyone who can reach the VM and has a password can join the same session. The side panel shows a chat and the session events, so you can see who connected and who currently holds control.

Give collaborators the user password and keep the admin password to yourself. An admin can lock the room to stop new logins and can take control back from any participant.

11

Adjust session settings

The settings tab adjusts your own view and, for admins, the room itself.

An admin can change the desktop resolution here at runtime. Lowering it is the quickest way to improve smoothness on a smaller VM. Raising it costs CPU.

12

Manage the service

Check the service status:

sudo systemctl status neko.service --no-pager

Restart the browser session. This discards the running browser's state and starts a clean one:

sudo systemctl restart neko.service

View the server logs:

sudo docker logs --tail 40 neko-neko-1
13

Change the passwords

The passwords live in a root-only environment file. To change one, edit the file and restart the service:

sudo sed -i 's/^NEKO_USER_PASSWORD=.*/NEKO_USER_PASSWORD=<new-password>/' /etc/neko/neko.env
sudo systemctl restart neko.service

Keep /root/neko-credentials.txt in step with any change you make, or treat the environment file as authoritative from then on.

14

Use your own domain and HTTPS

For anything beyond a trial, put a real hostname and a certificate in front of the web interface. Install a certificate with Certbot against the nginx site this image already ships, then reload nginx.

Keep two things in mind:

  • HTTPS covers port 80 traffic only. The WebRTC media on port 59000 is not HTTP and is not proxied. It continues to flow directly to the VM, so leave those rules in place.
  • Browsers require a secure context for some features, so serve the interface over HTTPS for any real deployment.
15

Security notes

  • Restrict the source addresses on both network security group rules to your own network. This is a browser other people can drive, so do not leave it open to the internet.
  • Treat the admin password as privileged. An admin can take control at any time and can see everything on the shared screen.
  • Remember the session is shared. Anything you type into the remote browser, including passwords you enter on websites, is visible to everyone watching. Do not sign in to personal accounts in a shared session.
  • Rotate the passwords if someone leaves the group, using Step 13.
  • Keep the OS patched. Unattended security upgrades are enabled on this image by default.
16

Support and Licensing

Neko is free and open-source software under the Apache-2.0 license. The streamed browser is Mozilla Firefox under the MPL-2.0 license. The container also includes standard Debian encoding components, libx264 and the GStreamer "ugly" plugin set. These are licensed under the GPL-2.0-or-later and are used unmodified as distributed by Debian.

This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by the Neko project or the Mozilla Foundation. The Neko and Firefox names are used only to identify the software included.

For help with the image, contact SecureAnyCloud support, which is available 24/7. For questions about Neko itself, see the upstream project at github.com/m1k1o/neko.

Deploy on Azure

Launch Neko 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

Deploy on Azure