Deployment guide

MeshCentral

Overview

MeshCentral is an open-source, self-hosted remote monitoring and management platform. You install a lightweight agent on Windows, Linux and macOS devices, then control desktops, transfer files, open remote terminals, and monitor and patch those devices from a single web console. Everything runs on your own server, with no third-party cloud in the middle.

This SecureAnyCloud image installs Node.js LTS and MeshCentral 1.2.1 natively and runs MeshCentral as a dedicated system service bound to the loopback connector 127.0.0.1:4430. MeshCentral is HTTPS-native, so its console and agent tunnels use secure WebSockets. nginx terminates TLS on port 443 with a per-VM self-signed certificate and reverse proxies to MeshCentral. Port 80 serves an unauthenticated health endpoint and redirects everything else to HTTPS.

What you get:

  • MeshCentral 1.2.1 installed natively on Node.js 22 LTS and run as the meshcentral system service
  • The built-in NeDB database, so no external MongoDB is required
  • nginx terminating TLS on :443 (per-VM self-signed certificate) and reverse proxying to MeshCentral on 127.0.0.1:4430 with the WebSocket upgrade
  • Port 80 serving an unauthenticated /healthz endpoint and redirecting all other traffic to HTTPS
  • Self-signup disabled and a unique site admin password generated on the first boot of every VM, recorded in a root-only file (username admin)
  • A dedicated Azure data disk at /var/lib/meshcentral holding the NeDB database, config.json and TLS certificates
  • meshcentral.service and nginx.service as enabled, active systemd units
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a reasonable starting point for a small fleet. Choose a larger size for more managed devices and concurrent remote sessions.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network, and 80/tcp and 443/tcp for the console and agent connections. The appliance ships a self-signed certificate. For production, put your own domain and a trusted certificate (for example Let's Encrypt) in front of it, as described under Maintenance.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for MeshCentral by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22), HTTP (80) and HTTPS (443).

Review the dedicated data disk on the Disks tab, then select Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:meshcentral-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name meshcentral \
  --image sac1647283583153:meshcentral-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name meshcentral --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name meshcentral --port 443 --priority 1020

First boot takes a few minutes. In the background, the VM generates its own credentials and starts the services. If you connect as soon as the VM shows as running, wait for that setup to finish before you continue.

Run sudo cloud-init status --wait. It prints status: done when the VM is ready. The credentials and services described below exist only after that.

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active meshcentral.service nginx.service

Both services report active. MeshCentral runs as a Node.js service bound to the loopback connector 127.0.0.1:4430. nginx fronts it with TLS on port 443, including the WebSocket upgrade the console requires, plus a port 80 health endpoint and HTTPS redirect.

MeshCentral's database and certificates live on the dedicated Azure data disk mounted at /var/lib/meshcentral.

Step 5 - Retrieve your admin password

Your VM generated a unique MeshCentral site admin password on first boot and wrote it to a root-only file. Read it with sudo:

sudo cat /root/meshcentral-credentials.txt

The file contains MESHCENTRAL_USERNAME (always admin), MESHCENTRAL_PASSWORD and the URL to open. Store the password somewhere safe. The file is mode 0600 and owned by root, so only an administrator can read it.

Step 6 - Confirm the health endpoints

Run these commands to check the unauthenticated health endpoint that nginx serves for load balancers and probes:

curl -s http://localhost/healthz
curl -sk https://localhost/healthz

Both return ok. Port 80 returns HTTP 301 and redirects to HTTPS, and the console at https://<vm>/ returns HTTP 200.

The /healthz endpoint never requires authentication, so it is safe for an Azure Load Balancer health probe.

Step 7 - Verify authentication from the command line

MeshCentral's login is a form post over the TLS edge that establishes a session cookie. The check below signs in with the correct per-VM password and reaches the console, while a wrong password stays on the login page.

The command embeds your unique password, so run it interactively rather than from a script. Substitute the value of MESHCENTRAL_PASSWORD from Step 5 for <MESHCENTRAL_PASSWORD>:

login() { j=$(mktemp); bf=$(mktemp); \
  curl -sk -o /dev/null -c "$j" -b "$j" --data-urlencode action=login \
  --data-urlencode username=admin --data-urlencode "password=$1" https://127.0.0.1/; \
  curl -sk -b "$j" -o "$bf" https://127.0.0.1/; \
  grep -qi logout "$bf" && echo "authenticated (reached console)" || echo "rejected"; \
  rm -f "$j" "$bf"; } login '<MESHCENTRAL_PASSWORD>'

The correct per-VM password prints authenticated (reached console). A wrong password prints rejected.

Loopback checks like this are excluded from MeshCentral's brute-force throttle, so your health checks never lock the account. Connections from real client IP addresses keep full brute-force protection.

Set the server name to your public address

On first boot, the VM writes the address Azure reports into MeshCentral's server name (cert in /var/lib/meshcentral/config.json), the TLS certificate and the credentials file. With a Standard SKU public IP (the Azure default, and the --public-ip-sku Standard in Step 2), the current image records the VM's private address (10.0.0.x).

MeshCentral then rejects the console's connections from your browser at the public IP (Invalid origin in HTTP request). Signing in at the public IP fails with Login failed, check username and password., even with the correct password from Step 5. If you see that message, this is the cause. Check the recorded name:

sudo grep '"cert"' /var/lib/meshcentral/config.json

If it shows a 10. address, set the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:

PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo sed -i "s/\"cert\": \"$PRIV\"/\"cert\": \"$PUBLIC_IP\"/" /var/lib/meshcentral/config.json
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
  -keyout /etc/nginx/sac-meshcentral/server.key -out /etc/nginx/sac-meshcentral/server.crt \
  -subj "/CN=$PUBLIC_IP" -addext "subjectAltName=IP:$PUBLIC_IP,IP:$PRIV"
sudo chmod 0600 /etc/nginx/sac-meshcentral/server.key
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/meshcentral-credentials.txt
sudo systemctl restart meshcentral nginx

Give MeshCentral a minute to load before you sign in. Your admin password does not change.

To use a DNS name instead, set PUBLIC_IP to the name and write DNS:$PUBLIC_IP in place of IP:$PUBLIC_IP. Do this before you add devices, because agents are issued the server name.

Step 8 - Sign in to the console

Browse to https://<vm-public-ip>/. The appliance uses a self-signed certificate, so accept the browser warning. For production, put your own domain and certificate in front, as described under Maintenance.

On the MeshCentral sign-in page, enter the username admin and the password from Step 5.

Step 9 - The device console

After you sign in, you land on the My Devices console. Every device you enrol appears here, grouped into device groups.

From this console you can control the desktop, open a remote terminal, transfer files and see live status for each managed machine.

Step 10 - Add a device

Create a device group, then click Add Agent to get the installer for your platform. MeshCentral generates a small agent for Windows, Linux, macOS and more.

Run the agent on a device. The machine appears in the console within seconds, ready for remote control.

Step 11 - Manage your account

Open My Account from the menu to change your password, enable two-factor authentication and manage account settings.

As the site administrator, you can also open My Server to see server status and manage users.

Step 12 - Confirm data lives on the dedicated disk

MeshCentral stores its data under /var/lib/meshcentral on the dedicated Azure data disk. That data covers the NeDB database (users, device groups, enrolled devices, event and stats history), config.json and the generated TLS certificates. Because it is on its own disk, it survives OS changes and can be resized independently. Confirm the mount:

findmnt /var/lib/meshcentral

The mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM.

Maintenance

  • Password: the site admin password is set on first boot. To change it, sign in and use My Account, or manage users from the My Server area.
  • TLS and your own domain: the appliance ships a per-VM self-signed certificate on port 443. For production, point a DNS name at the VM and install a trusted certificate, for example with certbot and Let's Encrypt. Then set that name as the cert value in /var/lib/meshcentral/config.json and restart meshcentral.service so agents are issued the correct server address.
  • Agents: install the MeshCentral agent on each device you want to manage, using Add Agent in a device group. Agents connect back to the server over port 443.
  • Upgrades: MeshCentral is installed under /opt/meshcentral. To upgrade, run npm install meshcentral@<version> in that directory and restart meshcentral.service. Your data under /var/lib/meshcentral is preserved.
  • Storage: all MeshCentral state lives under /var/lib/meshcentral on the data disk. Back up that volume to protect your users, device groups and history.
  • Self-signup: the image disables new-account self-signup, so only the site admin account exists until you add more users from My Server.
  • Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.

Support

SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.

Deploy on Azure

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