16 KiB
MeshCentral RMM — Complete Setup Guide
From Zero to Connected (With All Challenges Documented)
What is MeshCentral and Why We Need It
MeshCentral is a free, open-source Remote Monitoring and Management (RMM) tool. It lets you see all your remote machines in one browser dashboard, open root terminals, transfer files, and push scripts to 100 machines simultaneously — without using RustDesk or asking for passwords every time.
The Goal: Install MeshCentral on the central server once. Install the lightweight agent on each client machine once. After that, manage everything from a web browser forever.
Architecture Overview
Client Machine (anywhere in the world)
└── MeshCentral Agent (background service, runs as root)
└── Tailscale (mesh VPN, gives stable 100.x.x.x IP)
│
│ Direct encrypted tunnel (no middleman)
▼
Central Server (your always-on Linux machine / WSL)
└── MeshCentral Server (NodeJS app, port 4430)
└── Tailscale (same mesh VPN, stable 100.x.x.x IP)
Part 1: Setting Up the Central Server (Your Laptop/Desktop)
Prerequisites
- Linux machine or WSL2 on Windows
- NodeJS v20+
- Tailscale account (free at tailscale.com)
Step 1: Install NodeJS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
Verify: node --version should show v20.x.x
Step 2: Install MeshCentral Locally
mkdir ~/meshcentral
cd ~/meshcentral
npm install meshcentral
CRITICAL: Do NOT use
sudo npm install -g meshcentral. Installing globally puts MeshCentral in/usr/lib/which is root-owned. MeshCentral will fail withEACCES: permission denied, mkdir '/usr/lib/meshcentral-data'. Always install locally in your home directory.
Step 3: Install Tailscale on the Central Server
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
CRITICAL — DO NOT PRESS Ctrl+C: When
sudo tailscale upruns, it prints an authentication URL and then WAITS. You MUST open that URL in a browser and log in FIRST. Only after successful login will the terminal printSuccess.and return to the prompt. If you press Ctrl+C before authenticating, Tailscale will be installed but NOT logged in. You will have to runsudo tailscale upagain and get a NEW URL to authenticate.
Open the authentication URL in a browser. Log in with Google/GitHub. After the terminal prints Success., get your stable IP:
tailscale ip -4
# Example output: 100.66.205.2
Save this IP — it is your permanent MeshCentral server address.
Step 4: Configure MeshCentral
cat > ~/meshcentral/meshcentral-data/config.json << 'EOF'
{
"settings": {
"cert": "YOUR_TAILSCALE_IP",
"port": 4430,
"redirport": 4431
},
"domains": {
"": {
"title": "My RMM"
}
}
}
EOF
Replace YOUR_TAILSCALE_IP with your actual Tailscale IP (e.g., 100.66.205.2).
Step 5: Start MeshCentral
cd ~/meshcentral && node node_modules/meshcentral
Expected healthy startup output:
MeshCentral HTTP redirection server running on port 4431.
MeshCentral v1.1.59, Hybrid (LAN + WAN) mode.
MeshCentral HTTPS server running on 100.66.205.2:4430.
Step 6: Access the Dashboard
Open your browser and go to:
https://localhost:4430
Accept the certificate warning (self-signed cert is normal). The first account you create automatically becomes the Site Administrator.
Step 7: Create a Device Group
In the dashboard:
- Click My Devices
- Click Add Device Group
- Name it (e.g.,
Client Machines) - Click OK
Part 2: Connecting a New Client Machine
Repeat these steps for every new machine you want to manage.
Step 1: Install Tailscale on the Client Machine
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Open the authentication URL. Log in with the SAME Tailscale account as the server. This is critical — both must be on the same account to communicate.
Verify connection:
tailscale ip -4
# Should give a 100.x.x.x IP
ping 100.66.205.2 # Should reach the server
Step 2: Get the Agent Install Command
In the MeshCentral browser:
- Go to My Devices
- Click on your Device Group
- Click Add Agent
- Select Linux / BSD
- Copy the generated command
The command will look like:
(wget "https://100.66.205.2:4430/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://100.66.205.2:4430 'YOUR_GROUP_KEY'
Step 3: Run the Agent Install Command on the Client
On the client machine terminal:
cd /tmp && (wget "https://100.66.205.2:4430/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://100.66.205.2:4430 'YOUR_GROUP_KEY'
Expected output:
Downloading agent #6...
Agent downloaded.
...Installing service [DONE]
-> Starting service... [OK]
Step 4: Verify the Agent is Running
sudo systemctl status meshagent
Should show active (running).
Step 5: Confirm in the Dashboard
The machine should appear in MeshCentral within 10 seconds showing "Agent, Powered" with a blue refresh icon.
Part 3: Using MeshCentral to Deploy Scripts
Running a Script on One Machine
- Go to My Devices
- Right-click the machine → Terminal (for interactive use) OR
- Check the checkbox next to the machine
- Click Group Action → Run commands
- Select Linux/BSD/macOS Command Shell
- Select Run as agent (runs as root on Linux)
- Select Commands from file
- Click Choose file → select your
.shscript - Click OK
Running a Script on ALL 100 Machines Simultaneously
- Click Select All at the top
- Click Group Action → Run commands
- Upload your script and click OK
- Watch the output for each machine stream in simultaneously
Part 4: Challenges and Issues Faced (With Solutions)
Issue 1: Permission Denied on First Run
Error:
Error: EACCES: permission denied, mkdir '/usr/lib/meshcentral-data'
Cause: MeshCentral was installed globally with sudo npm install -g, placing it in the root-owned /usr/lib/ directory.
Fix: Install locally without sudo:
mkdir ~/meshcentral && cd ~/meshcentral
npm install meshcentral
node node_modules/meshcentral
Issue 2: Permission Denied When Saving Script in nano
Error: [ Error writing test_install.sh: Permission denied ]
Cause: Terminal was sitting in a restricted system folder (like / or /root).
Fix: Always create files in /tmp which allows all users to write:
cd /tmp
nano test_install.sh
Issue 3: Script Fails with "command not found" After Clipboard Paste
Error: test_install.sh: line 27: Update: command not found
Cause: RustDesk/AnyDesk clipboard dropped the # symbol from comments. Linux interpreted the English word "Update" as a command.
Fix: Remove ALL comments and blank lines from scripts before pasting over remote desktop:
# Comments like this get corrupted when pasted via RustDesk
# Solution: Strip the script to pure commands only
Issue 4: MeshCentral Running in LAN Mode Only
Symptom: MeshCentral startup shows LAN mode — agents from other networks cannot connect.
Cause: No cert was set in config.json. MeshCentral defaults to LAN-only mode.
Fix: Set the cert field in config.json to the server's public hostname or Tailscale IP:
{
"settings": {
"cert": "100.66.205.2",
"port": 4430
}
}
Server will restart in Hybrid (LAN + WAN) mode.
Issue 5: Agent Stuck in SYN-SENT State (Port Mismatch)
Symptom: Agent connects to 104.16.x.x:1025 and hangs forever.
Cause: MeshCentral was running on port 1025. The .msh file embedded port 1025 in the server URL. But Cloudflare Quick Tunnels only listen on port 443. The connection attempt to :1025 on Cloudflare was silently blocked.
Diagnosis:
sudo ss -tp | grep meshagent
# Shows: SYN-SENT ... 104.16.x.x:1025
Fix (with Cloudflare): Use setcap to allow NodeJS to bind to port 443, and enable tlsoffload in config so the agent connects on the standard HTTPS port.
Better Fix: Switch to Tailscale (see Issue 6).
Issue 6: Certificate Hash Mismatch with Cloudflare Tunnel
Error:
Agent bad web cert hash (Agent:9969c2afd9 != Server:a364860c2f)
holding connection (106.51.126.27:43912)
Cause: Cloudflare "terminates TLS" — it acts as a middleman and presents its own TLS certificate to the agent instead of MeshCentral's certificate. The agent's .msh file contains MeshCentral's certificate fingerprint. When the agent sees Cloudflare's certificate instead, the fingerprints don't match and the agent refuses to connect.
Why this cannot be easily fixed with Cloudflare Quick Tunnels: The only way to fix it properly is to use a real Cloudflare account with a named tunnel and an Origin Certificate — so MeshCentral uses the same certificate that Cloudflare presents externally.
The Clean Fix: Use Tailscale Instead
Tailscale does not terminate TLS. It creates a direct encrypted tunnel between machines without intercepting TLS certificates. The agent connects directly to MeshCentral and sees its real certificate — the fingerprint always matches.
Setup:
# On server
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up # Login with Google/GitHub
tailscale ip -4 # Note this IP (e.g., 100.66.205.2)
# On client
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up # DO NOT PRESS Ctrl+C — wait for browser login then Success.
CRITICAL — DO NOT PRESS Ctrl+C during
sudo tailscale up: The command prints a URL and waits. Open the URL in ANY browser (even on your laptop). Log in with the SAME account. The terminal will then printSuccess.on its own. If you press Ctrl+C too early, the machine will show as logged out. Runtailscale statusto check — if it saysLogged out, runsudo tailscale upagain.
Both machines get stable 100.x.x.x IPs. Update MeshCentral config to use the Tailscale IP. Agent connects cleanly.
Issue 7: Windows Browser Cannot Reach WSL Tailscale IP
Symptom: Browser shows ERR_CONNECTION_TIMED_OUT when visiting https://100.66.205.2:4430
Cause: Windows cannot directly route to the Tailscale IP assigned to WSL. The Tailscale IP is only reachable from other Tailscale machines on the network, not from the Windows host itself.
Fix: From your own laptop's Windows browser, always use localhost to access WSL services:
https://localhost:4430 ← Use this from your laptop browser
https://100.x.x.x:4430 ← Use this from OTHER machines on Tailscale
Issue 8: MeshCentral Terminal vs Regular Terminal Permissions
Symptom: Running apt-get install in the regular terminal gives Permission denied.
Cause: The regular terminal runs as the normal user (kawsik). The MeshCentral Terminal runs as root because the agent service itself runs as root.
Rule:
- Regular terminal: needs
sudofor system commands - MeshCentral Terminal: already root, never needs
sudo
Issue 9: Tailscale Shows "Logged Out" After Ctrl+C
Symptom: tailscale status shows Logged out even after running sudo tailscale up.
Cause: The user pressed Ctrl+C while sudo tailscale up was waiting for browser authentication. This cancelled the authentication process before it completed. Tailscale is installed but not authenticated.
Fix: Simply run sudo tailscale up again. A new authentication URL will be printed. Open it in any browser (including your laptop's browser), log in, and wait for Success. to appear in the terminal. Never press Ctrl+C while the URL is shown.
sudo tailscale up
# Opens URL → open it in browser → log in → wait for Success. → done
tailscale status # Should now show Connected
Issue 10: Native Linux Client Cannot Ping WSL Tailscale IP (100% Packet Loss)
Symptom: ping 100.66.205.2 from a native Linux client (like PopOS) gives 100% packet loss. The Tailscale dashboard shows both machines as Connected but they cannot communicate.
Cause: The MeshCentral server's Tailscale is installed inside WSL2, which is behind double NAT — the home router AND Windows' internal NAT. Other WSL machines (like bs13) can reach it through Tailscale relay servers. But native Linux machines sometimes cannot punch through both NAT layers to reach a WSL Tailscale node.
Diagnosis:
tailscale status # Check if machine is actually online
tailscale ping 100.66.205.2 # Tailscale's own connectivity check
Fix Option 1 (Simple): Make sure Tailscale on the client is actually authenticated (run tailscale status — if it says Logged out, re-authenticate with sudo tailscale up).
Fix Option 2 (Production): Install Tailscale on the Windows host instead of WSL, giving it a proper host-level IP without double NAT. All clients can then reach the Windows Tailscale IP directly.
Fix Option 3 (Production): Move MeshCentral to a cloud VPS (Oracle Free Tier, etc.) so it has a real public IP with no NAT issues at all.
Issue 11: RustDesk "Failed to get capturer display info" on COSMIC Desktop (PopOS 24.04)
Symptom: RustDesk connects, password accepted, but immediately shows Failed to get capturer display info.
Cause: PopOS 24.04 uses the COSMIC desktop environment which is Wayland-only. There is no X11 option. RustDesk has limited support for Wayland/COSMIC screen capture.
Root Cause Detail: echo $XDG_SESSION_TYPE returns empty when run over SSH because no display session is attached to the SSH terminal. Running loginctl list-sessions showed session on tty1 — a text console, not a graphical session. The machine was sitting at the COSMIC login screen with no user logged into the GUI.
Identification Commands:
cat /etc/X11/default-display-manager # Shows: /usr/bin/cosmic-greeter
echo $XDG_SESSION_TYPE # Empty = no display in this terminal
loginctl list-sessions # Shows TTY type (tty1 = text, not GUI)
Fix: Enable auto-login for COSMIC so the machine automatically logs into the desktop on boot:
sudo mkdir -p /etc/sddm.conf.d
sudo nano /etc/sddm.conf.d/autologin.conf
Add:
[Autologin]
User=byfar
Session=cosmic
Then reboot. After reboot, COSMIC logs in automatically and RustDesk can capture the screen.
Alternative: Skip RustDesk entirely. Use MeshCentral's built-in Terminal (root shell) and Web-VNC features for remote access instead. These work regardless of display server type.
Part 5: Quick Reference — Adding Machine #N to MeshCentral
This is the exact 3-command sequence to run on any new Linux client machine:
# Step 1: Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# ⚠️ A URL will appear — open it in your laptop browser and log in with the SAME account
# ⚠️ DO NOT press Ctrl+C — wait until the terminal prints Success.
tailscale status # Must show Connected before proceeding
# Step 2: Install MeshCentral Agent
cd /tmp && (wget "https://100.66.205.2:4430/meshagents?script=1" --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://100.66.205.2:4430 'YOUR_GROUP_KEY'
# Step 3: Verify
sudo systemctl status meshagent
The machine will appear in the MeshCentral dashboard within 10 seconds.
If the agent install hangs connecting: Run
tailscale status— if it showsLogged out, the Tailscale session expired. Runsudo tailscale upagain, authenticate in the browser, then retry the agent install.
Part 6: Production Checklist
- Central server is always-on (disable sleep/hibernate)
- MeshCentral starts automatically on server reboot (configure as systemd service)
- Tailscale starts automatically on all machines (enabled by default after install)
- All client machines enrolled in Tailscale with the same account
- MeshCentral agent enabled as systemd service on all clients (
systemctl enable meshagent) - Node Exporter deployed and running on all clients (port 9100)
- All Tailscale IPs added to
prometheus.ymlas scrape targets