Add Azure VM to Tailscale
Onboard an Azure VM to your tailnet, enable SSH without public exposure, and serve your HTTP app over HTTPS using Tailscale Serve + MagicDNS.
Overview
This guide walks you through adding an Azure VM to Tailscale, granting private access without public SSH/RDP, and enabling automatic HTTPS for a local service using Tailscale Serve and MagicDNS.
What You’ll Set Up
- Tailscale installed and the VM enrolled in your tailnet
- A shared-vm tag and basic ACL posture (optional but recommended)
- Tailscale SSH enabled (no public inbound needed)
- Device key expiry disabled to avoid surprise logouts
- HTTPS for your local web app on port 80 via
tailscale serve --bg - Tips for MagicDNS, testing, and hardening
Prerequisites
- An Azure VM (Linux) with sudo privileges on the instance
- Tailscale account with admin access to your tailnet
- Ability to view/update Azure NSG rules (for cleanup/hardening)
- (Optional) Tailnet policy access (to define tags/ACLs)
Step 1: Install & Enroll Tailscale on VM
From the Tailscale Admin Console → Machines → Add device → Linux server, generate and copy the install command.
- (Optional): Add the
shared-vmtag for access control and discovery governed by ACLs in Tailscale.1 2
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up --auth-key=tskey-auth-XXXXXXXXXXXXXXXX --hostname=<vm-name>
- Replace the auth key with one generated for your tailnet.
- Use a clear hostname, e.g.
vm-serve. - After enrollment, confirm the node appears under Machines.
Step 2: Enable Tailscale SSH (No Public Inbound)
Enable Tailscale-managed SSH on the VM:
1
sudo tailscale set --ssh
Verify who can SSH in your ACLs (Admin Console → Access controls → SSH rules). This removes the need for public port 22 in your NSG.
Step 3: Disable Device Key Expiry (Service VMs)
For long‑lived service VMs, disable key expiry so they don’t fall off the network:
- In Admin Console → Machines → select your VM → Disable key expiry.
This might be handled automatically by your Admin Console settings.
Step 4: Serve HTTPS for Local Port 80 (Zero Config Web)
On the VM, if your app listens on http://localhost:80, enable HTTPS with one line:
1
sudo tailscale serve --bg http://localhost:80
This automatically:
- Provisions a valid certificate for your MagicDNS host (e.g.,
vm-serve.<tailnet>.ts.net) - Terminates HTTPS (443) and proxies to
http://localhost:80 - Auto‑renews the cert; no
tailscale certor Nginx needed
Verify status:
1
tailscale serve status
Test from any device on your tailnet:
1
https://<vm-hostname>.<tailnet>.ts.net
The service is tailnet‑only. To share externally (internet), look into Tailscale Funnel.
Step 5: MagicDNS & Names
If MagicDNS is enabled, your node gets a stable FQDN such as:
1
vm-serve.<tailnet>.ts.net
Inside the tailnet, short names often resolve too:
1
ping vm-serve
You can rename the OS hostname if desired (
hostnamectl set-hostname <newname>), but the Azure resource name itself cannot be changed directly (you’d recreate the VM to change the resource name).
Step 6: Hardening & Azure Cleanup
- Close public SSH/RDP once Tailscale SSH works (update NSG).
- Ensure only outbound UDP/41641 (Tailscale) is required publicly.
- This ingress rule will guaruntee a direct peer-to-peer connection to improve performance rather than use default NAT traversal to connect.
- Restrict who can access the VM via ACLs (groups/tags).
- Monitor device health from Admin Console → Machines.
- For web apps, keep the origin bound to localhost (not 0.0.0.0) when using Serve.
Troubleshooting
- Can’t enroll / auth errors: Verify auth key scope and that the VM’s clock is correct (NTP).
serveerrors (new CLI): Use new syntaxtailscale serve --bg http://localhost:80. Checktailscale serve status.- Cert/HTTPS not working: Confirm you’re visiting the device’s MagicDNS name and that you’re on a tailnet‑connected device.
- SSH denied: Review ACL SSH rules and confirm
sudo tailscale set --sshran; checkjournalctl -u tailscaledfor hints.
References
- Tailscale Docs – Linux install
- Tailscale Docs – SSH
- Tailscale Docs – Serve
- Tailscale Docs – MagicDNS
- Tailscale Docs – ACLs