Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 13 min read

How to Install MikroTik CHR on a VPS: RouterOS Setup, Security, and WireGuard Configuration

Installing MikroTik Cloud Hosted Router (CHR) on a VPS differs from an ordinary operating system reinstallation. Once you replace Ubuntu or another existing OS with CHR, the original SSH access disappears. At that point,

Installing MikroTik Cloud Hosted Router (CHR) on a VPS differs from an ordinary operating system reinstallation. Once you replace Ubuntu or another existing OS with CHR, the original SSH access disappears. At that point, your hosting provider’s virtual console may be the only way to access the server. Verify console access before writing anything to the system disk. If RouterOS boots with an incorrect network configuration, you will need the console to fix it.

CHR (Cloud Hosted Router) is MikroTik’s RouterOS edition designed for virtual machines. This guide shows how to install CHR on a VPS and connect its private network to a physical MikroTik router through a WireGuard tunnel. Both devices run RouterOS 7. The example uses routed IP networks rather than extending a single Ethernet segment across the Internet.

Disk imports, rescue environments, network interfaces, and routing policies vary between hosting providers. Confirm that your provider supports the required setup before beginning.

1. How to Install MikroTik CHR on a VPS

There are two main installation methods:

  1. Import an official CHR disk image through the hosting provider’s control panel, if custom images are supported.
  2. Write the extracted RAW image directly to the virtual machine’s system disk from a rescue environment.

The second method completely overwrites the target disk. Back up your data and verify the selected disk before running any write command. If the provider offers neither custom-image importing nor a usable rescue environment, these methods will not work.

2. Requirements Before Installing CHR

Virtualization and VPS resources

CHR must run inside a compatible virtual machine. KVM virtualization is suitable; a container that shares the host kernel is not. Look for a provider that offers custom disk-image installation or a CHR template, an out-of-band virtual console, and a way to boot into rescue mode.

For the topology in this guide, a small x86-64 VM with 1 vCPU and 1 GiB RAM is a reasonable starting point. The CHR image itself requires relatively little disk space. Actual throughput will depend on traffic volume, VPN encryption, connection counts, firewall rules, and the resources available to the VM.

If you are selecting a VPS hosting provider for a virtual router, pay particular attention to KVM support, console or rescue access, custom-image compatibility, and the provider’s private-network routing policiesβ€”not just advertised bandwidth.

Prefer a virtio-net adapter to an emulated E1000 interface when both the hypervisor and the guest image support it. Virtio generally reduces CPU overhead and improves virtual networking efficiency, but measure actual performance rather than assuming a particular tunnel speed.

Private-network restrictions

If CHR will act as the gateway for other VMs, ask whether the provider permits forwarding packets from those VMs and whether anti-spoofing or source-address restrictions apply. This tutorial assumes two interfaces on CHR: ether1 faces the Internet, and ether2 connects to a separate private network. A VPS with only one interface needs a different network layout.

Understand CHR licensing

License Maximum transmission speed per interface
Free 1 Mbps
P1 1 Gbps
P10 10 Gbps
P-Unlimited No license-enforced bandwidth limit

MikroTik offers a 60-day trial of paid CHR license tiers. The P-Unlimited tier removes the license-imposed speed limit, but physical network capacity, VPS CPU resources, and the host infrastructure still determine actual throughput.

Paid CHR instances must periodically contact MikroTik’s licensing service. If the renewal deadline is missed, the router continues operating, but software upgrades and package changes are restricted until licensing is restored. Check the official CHR documentation for current terms.

3. Download and Verify the CHR Image

Download a complete CHR disk image from MikroTik’s official CHR download page. A RouterOS .npk package is not suitable for a fresh disk installation; it is used to install or update packages in an existing RouterOS system.

For KVM, a RAW disk image is commonly suitable. Some hosting panels accept QCOW2 images, possibly after conversion. Confirm the required format with the provider.

Version note: As of October 14, 2026, RouterOS 7.23.8 was available in the Stable channel and marked Long-term. Record the precise version and download URL in your installation notes. Commands and menus may differ in newer releases.

Finish downloading the archive before extracting it. If an official MikroTik checksum is published, compare it with the checksum calculated locally. A SHA-256 digest you calculate after downloading also helps detect corruption during transfer to the VPS, but does not independently establish the image’s origin.

If you use a provider-supplied CHR template, check its version, accounts, and default settings. A third-party template may differ from MikroTik’s official image.

4. Install CHR by Importing an Image or Using Rescue Mode

Option A: Import the image in the hosting control panel

Import the disk image into a test VM and place the imported disk first in the boot order, ahead of any existing empty disk. Before the first boot, block unsolicited inbound IPv4 and IPv6 connections using the hosting provider’s external firewall. Start the VM and verify RouterOS access through the virtual console.

Option B: Write the RAW image from rescue mode

Warning: dd overwrites the entire destination disk. Do not execute the write command until you have positively identified the correct device and backed up your data elsewhere.

Boot into a rescue environment running from memory or storage other than the target disk. Identify devices and check mount and swap status:

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL,SERIAL
findmnt
swapon --show

Verify the target disk using size, model, serial number, and mount points. Unmount its partitions, disable any swap on it, and stop processes using it. Replace /dev/REPLACE_DISK with the verified whole-disk device, not a partition such as /dev/vda1.

sudo dd if=./chr-7.23.8.img of=/dev/REPLACE_DISK \
  bs=4M conv=fsync status=progress

Disable rescue mode in the provider panel, boot from the written disk, and check the console. If RouterOS does not start, verify the image format, firmware/boot mode, and virtual disk-controller settings.

5. First Boot: Configure WAN Addressing and DNS

Use the IPv4 address, prefix, default gateway, and DNS settings supplied by your VPS provider, or enable the DHCP client if that is how the platform assigns network settings. Identify the RouterOS interface by comparing its MAC address with the provider panel. Previous Linux interface naming does not carry over to RouterOS.

Some VPS networks provide /32 addresses or gateways outside the configured subnet. These require provider-specific routing; do not randomly change the prefix to /24 to try to reach the gateway. Keep virtual-console access open until you have confirmed connectivity.

6. Secure the First RouterOS Login

A fresh CHR installation normally provides an admin user without a preset password. Sign in through the console and set a strong password immediately when prompted. Create a separate administrator, test login with that account, and then disable the original admin account. Use individual administrator accounts; the RouterOS full group grants broad privileges.

Before changing networking, record the initial state:

/system resource print
/system package print
/system license print
/interface ethernet print detail
/export file=before-network

Retrieve the exported file from RouterOS Files over a secure connection and store it outside the VPS.

Use Safe Mode during remote changes

When configuring RouterOS over a terminal connection, press Ctrl+X to enter Safe Mode. Press Ctrl+X again to retain the changes and exit. If the session unexpectedly disconnects, RouterOS attempts to roll back changes made in Safe Mode. Safe Mode is not a replacement for backups and cannot guarantee recovery from reboots, restorations, or large configuration imports.

Test a new administrative connection from an authorized address before closing the existing session. An established session can remain functional even when a newly added firewall rule blocks new connections.

7. Network Topology and IP Addressing

This example uses two separate LAN subnets connected through WireGuard. The public address ranges shown are reserved for documentation; replace them with addresses assigned to your actual systems.

Segment CHR VPS Physical MikroTik
WAN 203.0.113.10/24, gateway 203.0.113.1 Existing Internet connection
WireGuard 10.77.0.1/30 10.77.0.2/30
Local network ether2: 10.20.0.1/24 LAN: 192.168.50.1/24
Remote route 192.168.50.0/24 via wg-site 10.20.0.0/24 via wg-site

On a newly installed CHR with static addressing:

/ip address add address=203.0.113.10/24 interface=ether1
/ip address add address=10.20.0.1/24 interface=ether2
/ip route add dst-address=0.0.0.0/0 gateway=203.0.113.1
/ip dns set servers=1.1.1.1 allow-remote-requests=no
/ip route print detail

Verify that both connected subnets appear and that the default route is active with a reachable next hop. If the VPS receives its settings through DHCP, use the assigned configuration and do not duplicate its default route.

Test connectivity in order: the gateway, an external IP address, and then a domain name. If the IP responds but the domain does not, investigate DNS. With allow-remote-requests=no, this resolver serves the router itself rather than LAN clients.

8. Protect RouterOS with Firewall Rules

The RouterOS input chain controls traffic destined for the router; the forward chain controls packets routed through it. Permitting SSH or WinBox in input does not automatically allow access to hosts behind ether2.

Initial IPv4 input policy

The following rules assume a fresh CHR without existing filter rules. Replace 198.51.100.20 with the public IP address of your administrator. Rule order is important, so do not blindly append this block to an existing configuration.

/ip firewall filter
add chain=input action=accept connection-state=established,related
add chain=input action=drop connection-state=invalid
add chain=input action=accept protocol=icmp
add chain=input action=accept protocol=tcp dst-port=22,8291 \
  src-address=198.51.100.20/32 in-interface=ether1
add chain=input action=accept protocol=udp dst-port=13231 \
  in-interface=ether1
add chain=input action=drop comment="A08 input deny"

This allows established and related traffic, ICMP, administrative TCP access from the trusted address, and WireGuard on UDP port 13231. The final rule drops other IPv4 input traffic. If the WAN uses DHCP, also permit the required DHCP client replies before the final drop rule.

Disable unneeded management services and independently restrict SSH/WinBox to authorized addresses:

/ip service set telnet,ftp,www,www-ssl,api,api-ssl disabled=yes
/ip service set ssh,winbox address=198.51.100.20/32

IPv6 and Layer 2 management

This guide’s example uses IPv4 only. If the VPS does not need IPv6, disable it. If you need IPv6, configure its own input and forward policies rather than leaving it unrestricted.

/ipv6 settings set disable-ipv6=yes
/tool mac-server set allowed-interface-list=none
/tool mac-server mac-winbox set allowed-interface-list=none
/ip neighbor discovery-settings set discover-interface-list=none

Use the hosting provider’s external firewall as an additional control, allowing only the required management and VPN traffic.

9. Establish a WireGuard Tunnel Between CHR and a Physical MikroTik

WireGuard provides an encrypted Layer 3 tunnel between two separate IP networks. There is no need to bridge both LANs into one Ethernet segment. In this example, the physical router is behind NAT and initiates the connection to CHR’s public IP. Make sure UDP 13231 is permitted along the path, and ensure that the two LAN subnets do not overlap.

Both routers use the interface name wg-site, port 13231, and an initial MTU of 1420.

Create WireGuard on CHR

/interface wireguard add name=wg-site listen-port=13231 mtu=1420
/ip address add address=10.77.0.1/30 interface=wg-site
/interface wireguard print

Create WireGuard on the physical router

/interface wireguard add name=wg-site listen-port=13231 mtu=1420
/ip address add address=10.77.0.2/30 interface=wg-site
/interface wireguard print

RouterOS generates each interface’s key pair. Exchange public keys only; keep private keys on their respective routers.

Add the physical router as a peer on CHR

/interface wireguard peers add interface=wg-site \
  public-key="ROUTER_PUBLIC_KEY" \
  allowed-address=10.77.0.2/32,192.168.50.0/24

Add CHR as a peer on the physical router

/interface wireguard peers add interface=wg-site \
  public-key="CHR_PUBLIC_KEY" \
  allowed-address=10.77.0.1/32,10.20.0.0/24 \
  endpoint-address=203.0.113.10 endpoint-port=13231 \
  persistent-keepalive=25s

Replace both public-key placeholders with the actual values. Set endpoint-address to the public IP assigned to your CHR VPS. The 25-second persistent keepalive helps maintain NAT mappings when ordinary traffic is idle.

In RouterOS, a WireGuard peer’s allowed-address identifies the addresses associated with that peer for encrypted traffic and controls which source addresses are accepted from it. It does not create the necessary RouterOS routes automatically.

10. Add Routes to the Remote LANs

On CHR, route the LAN behind the physical router through WireGuard:

/ip route add dst-address=192.168.50.0/24 gateway=wg-site

On the physical MikroTik, route the private VPS network through WireGuard:

/ip route add dst-address=10.20.0.0/24 gateway=wg-site

These are specific remote-LAN routes; neither changes the existing default Internet route. Ordinary Internet traffic on the physical router continues over its original connection.

11. Allow Traffic Between the Two LANs

For a fresh CHR without previous forward-chain rules, permit the two specific directions of inter-site traffic and drop other forwarding:

/ip firewall filter
add chain=forward action=accept connection-state=established,related
add chain=forward action=drop connection-state=invalid
add chain=forward action=accept in-interface=wg-site out-interface=ether2 \
  src-address=192.168.50.0/24 dst-address=10.20.0.0/24
add chain=forward action=accept in-interface=ether2 out-interface=wg-site \
  src-address=10.20.0.0/24 dst-address=192.168.50.0/24
add chain=forward action=drop comment="A08 forward deny"

On the physical router, add appropriate inter-site permissions before existing drop rules while retaining its current security protections. Review broad masquerade rules; NAT is not normally necessary between these routed private networks, and an overly broad masquerade rule can unintentionally translate tunnel traffic.

Hosts behind CHR must use 10.20.0.1 as their gateway or have an explicit route to 192.168.50.0/24 via that address. Hosts on the physical LAN also need a valid return route to 10.20.0.0/24. Without symmetrical routing, requests may arrive but replies will leave through another gateway.

12. Troubleshoot MTU Problems

If small pings succeed but file transfers stall, consider a path-MTU problem. WireGuard encapsulation adds overhead, and 1420 is a starting MTU rather than a guarantee for every path. Test different packet sizes with the Don't Fragment option where supported. Account for outer headers and the possibility that intermediate firewalls block ICMP messages needed for Path MTU Discovery. Also consider firewall rules, routing, and packet loss before attributing every stalled transfer to MTU.

13. Confirm the Tunnel Works End to End

Test connectivity in stages:

  1. Ping the remote WireGuard tunnel address in each direction.
  2. Ping the remote LAN gateway on each side.
  3. Ping or connect to real hosts behind the routers.
  4. Test actual application traffic between the two networks.

A ping sent by the router itself does not traverse the forward chain, so router-to-router connectivity alone cannot prove that client traffic is allowed.

Save useful diagnostics:

/interface wireguard peers print detail
/ip route print detail where dst-address=192.168.50.0/24
/ip firewall filter print stats
/log print where topics~"wireguard"

Check the latest WireGuard handshake, peer transmit/receive counters, route reachability, firewall counters, and relevant log entries. A recent handshake means the peers communicated successfully, not necessarily that both LANs can exchange traffic.

14. Benchmark WireGuard Throughput

Measure performance using iperf3 between Linux hosts behind the routers. Repeat comparable tests in both directions while monitoring CPU utilization, packet loss, and latency under load. Keep a record of the RouterOS version, CHR license tier, VPS plan, test duration, and number of parallel streams.

Avoid running a traffic generator directly on the router when practical: it consumes CPU cycles that would otherwise be available for packet forwarding and encryption.

If ping works but transfers appear capped at roughly 1 Mbps, check whether CHR is still using the Free license before investigating the encryption stack or virtual network drivers.

15. Back Up RouterOS Before Updates

RouterOS supports two useful backup approaches:

  • Text export: Human-readable and more convenient for reviewing or adapting configurations, but sensitive values are hidden by default. Plan separately for credentials, certificates, SSH keys, and other secrets.
  • Binary backup: Preserves more device-specific configuration, including MAC addresses. Protect it with encryption and restore it on the same device and RouterOS version, or in a sufficiently similar environment.

Store both types outside the CHR virtual machine. Before production updates, verify the restoration procedure in an isolated test VM. Never bring a clone online with the production router’s IP addresses or WireGuard keys: duplicate identities can disrupt routing and tunnel traffic.

Check how your paid CHR license is affected by replacing the VM. After any update or restoration, retest administrative access, routing, and the VPN tunnel.

16. Final Verification Checklist

Before calling the deployment complete, verify that:

  • [ ] The installed CHR image boots from disk without rescue mode.
  • [ ] The provider’s out-of-band virtual console works.
  • [ ] Administrative accounts and passwords are secured.
  • [ ] Unnecessary services and management access are restricted.
  • [ ] WAN addressing, default route, and DNS resolution work.
  • [ ] Firewall rules permit only intended traffic.
  • [ ] WireGuard peers establish a handshake.
  • [ ] Both routers have valid routes to the remote LAN.
  • [ ] Real clients on both networks can communicate.
  • [ ] MTU and throughput have been tested.
  • [ ] The license tier matches performance expectations.
  • [ ] Configuration backups are stored and recoverable.

Finally, reboot the test CHR, confirm that WireGuard reconnects, verify a fresh administrator login, and repeat traffic tests between actual end hosts. A successful installation is one that continues to work after rebootβ€”not simply one that passes the first ping.

Keep the provider console available for future recovery. Unlike SSH and WireGuard, it does not depend on the guest operating system’s routing configuration and can save significant time after a firewall or gateway mistake.

Official References

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.