UserVM Handbook/Windows
This guide details how to set up a UserVM on a host machine running Microsoft Windows.
We do not support CollabVM server on Windows. We strongly recommend that you install a Linux distribution and follow the main UserVM Handbook instead. If you experience problems with this guide, you may receive help in the CollabVM discord, but this is not a guarantee and you may be on your own if it's not a simple fix. |
The Rules
First, the boring part. We ask that all hosts review and follow the UserVM Hosting Rules.
Prerequisites
You'll need:
- A machine with decent specs (8GB of RAM and a modern CPU, probably)
- Microsoft Windows 10 or later. For Linux, see the main UserVM Handbook.
- A decently fast network that allows you to forward a port. We will not accept UserVMs behind services like ngrok. Cloudflare tunnels are fine. You must also have a URL that stays persistent. If your IP is dynamic, you can use services like NOIP or setup a script to auto-update your domain using cloudflare.
- Basic knowledge of how computers and Windows systems work. We aren't going to hold your hand, you need to be comfortable with a command line
- IF YOU DO NOT UNDERSTAND HOW TO FOLLOW THE INSTRUCTIONS IN THIS GUIDE, DO NOT HOST PUBLIC INTERNET CONNECTED VMS ON THE INTERNET THAT ANYONE CAN ACCESS
- A few hours
Compiling the server
Install dependencies
Open Command Prompt as administrator.
First, install the Chocolatey package manager. If you already have it installed, you can skip this step.
powershell -c "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"
Restart CMD to apply the changes to PATH. Now, we'll install the various dependencies CollabVM has:
choco install qemu git nasm cmake nodejs nssm rust-ms visualstudio2019-workload-vctools
refreshenv
Enable corepack:
corepack enable
Prepare the server
We can now get the server ready. First, create a directory for all CollabVM related files. For the purposes of this guide, we use C:\collabvm
. If you use a different directory, be sure to substitute it in all future commands.
mkdir C:\collabvm
Clone the CollabVM server source:
git clone https://github.com/computernewb/collabvm-1.2.ts.git C:\collabvm\collabvm-1.2.ts --depth 1 --recursive
cd C:\collabvm\collabvm-1.2.ts
Install dependencies and build the server:
yarn
yarn build
Set up your VM
Now is a good time to get your VM set up. Currently, the only supported hypervisor is QEMU. We have many guides on this wiki for setting up different OSes in QEMU, check them out here. Here are some ideas to make your VM interesting:
- A funny wallpaper
- Development software (Visual Studio, etc.)
- Some games
- Some harmless malware (for the love of god no GDI rapists)
Windows Hypervisor Support
By default, QEMU uses the TCG software emulator, which is very slow. You can greatly increase the speed of your VM by enabling Windows Hypervisor.
First, enable the Windows Hypervisor:
dism /online /enable-feature /featurename:HypervisorPlatform
Reboot your system to apply changes
Now, you can enable WHPX hypervision by using the -accel whpx
argument somewhere in your QEMU command line. If you're copying your QEMU command from somewhere that expects KVM (which is the Linux equivalent to the Windows Hypervisor), make sure you REPLACE the -accel kvm
with -accel whpx
in the command or it will not run.
Note that there is also a fork of QEMU that uses the Android Emulator Hypervisor Driver, which may be faster than the Windows Hypervisor but is also known to be very buggy.
Multi-threaded TCG
QEMU with the Windows Hypervisor tends to be very unstable and may not work on your system at all. (This is one of the reasons we strongly recommend that you use a Linux host) In this case, you can still achieve some performance by using -accel tcg,thread=multi
, although it still won't be anywhere near native speeds.
Setting up a Virtual Network
QEMU's user-mode networking used by default isn't very customizable and lacks the ability to block certain abuse vectors. For this reason we very strongly recommend setting up a Virtual Network using the CollabNet Guide. Depending on the full situation we may refuse to add VMs that use QEMU user-mode networking.
It's also VERY important that mail ports are BLOCKED on your VM (the CollabNet guide config includes this). If you do not block them, your IP effectively becomes an open relay which will very likely get you suspended by your ISP or hosting provider. We will not add VMs with accessible mail ports
The following is the Windows version of the Host Preparation section of the CollabNet Guide.
IP Forwarding
First, we're going to enable IP forwarding on your host. This will allow traffic from the VMs to be routed to and from the router. The following command will write this to the registry.
reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /d 1 /t REG_DWORD /f
Reboot your system.
Bridge configuration
Next, we'll set up a network bridge with multiple TAP interfaces. You can think of a TAP interface as a virtual Ethernet port connected to your VM, and the network bridge as a virtual Ethernet switch connecting them all together.
First, install OpenVPN, which contains the TAP driver for Windows:
choco install openvpn
refreshenv
Now, create a TAP interface for the router and each of your VMs:
cd "C:\Program Files\OpenVPN\bin"
tapctl create --name ktrouter
tapctl create --name ktvm1
(...)
The last step is to bridge all of our TAP interfaces together. For some reason Microsoft decided you can't do this from the command line, so go ahead and open the Network Connections control panel:
ncpa.cpl
You should see a list of network adapters. Hold down the Ctrl key and click each of the TAP interfaces we created (ktrouter
, ktvm1
) to select them. Now, right click one of them and select Bridge Connections
to create the bridge
Now, simply right click the new Network Bridge
and rename it something friendly, like collabnet
.
If you add new TAPs in the future, simply right click the collabnet
bridge and go to properties, and tick the new TAP in the Adapters
list.
You can now continue from the Router section of the CollabNet Guide, with some obvious adjustments for windows.
Configuration
Now we need to fill out the config file for your VM. Copy config.example.toml to config.toml, and open it in an editor. It is well commented so each value should be self-explanatory. If you have questions, feel free to ask in our Discord server.
QEMU Args
On Windows, if QEMU is installed to the default directory, you'll need to configure your qemuArgs
like this:
qemuArgs = "C:\\Program\ Files\\QEMU\\qemu-system-x86_64.exe [args]"
Example of a production QEMU command:
qemuArgs = "C:\\Program\ Files\\QEMU\\qemu-system-x86_64.exe -M q35,usb=on,acpi=on,hpet=off -cpu host -accel whpx -m 2G -smp cores=2 -device usb-tablet -nic none -hda C:\\collabvm\\images\\vm1.qcow2"
Running your VM
Now that everything is set up, you can bring your VM online. To run the server right from your terminal, run the following command:
yarn serve
Or alternatively, to run it directly:
node cvmts/dist/index.js
Running a local webapp
Before you put your VM on the UserVM roster, you'll probably want to test it out for yourself. For that, we'll throw up a test webapp. Start by cloning the source:
cd C:\collabvm
git clone https://github.com/computernewb/collab-vm-1.2-webapp.git --recursive
cd collab-vm-1.2-webapp
Then, copy config.example.json
to config.json
, and replace ServerAddresses with your server address:
"ServerAddresses": [
"ws://127.0.0.1:6004",
],
Now you can build the webapp, and serve it:
yarn
yarn build
yarn serve
This will run the webapp at 127.0.0.1:1234
, which you can navigate to in your browser. If all went well, your VM should show up. If not, and you don't know why, join our discord and ask for help there!
Setting up a service
We will now set your VM up as a background service using the NSSM runner.
In admin CMD:
nssm install collabvm
This will open the NSSM setup GUI. Configure each page as follows
Application
Path: C:\Program Files\nodejs\node.exe
Startup directory: C:\collabvm\collabvm-1.2.ts
Arguments: C:\collabvm\collabvm-1.2.ts\cvmts\dist\index.js
Details
Startup type: Automatic if you want your VM to start with your computer, Manual if you want to start it manually
Log on
Log on as: Virtual Service Account (very important for security)
I/O
Output (stdout): C:\collabvm\out.log
Error (stderr): C:\collabvm\err.log
Permissions
Give the CollabVM Virtual Service User permissions to the C:\collabvm
directory:
icacls C:\collabvm /grant "NT SERVICE\collabvm:F" /Q /C /T
NOTE: If you encounter permissions errors when running the CollabVM service after adding new VM images, run this command again.
Starting the service
You can now start your VM with:
net start collabvm
And stop it with:
net stop collabvm
Setting up reverse proxying
This is REQUIRED for UserVM as, for technical reasons, only TLS-equipped WebSockets can be accepted
We strongly recommend you proxy your UserVM behind Nginx, to provide additional security and allow things like TLS. It also makes your VM look a lot cleaner, allowing people to access it on your main HTTP(s) port and on a subdirectory, like https://example.com/collab-vm/
rather than http://example.com:6004
. Here's a brief tutorial of how to set that up on the Nginx side.
This assumes you're setting up a Nginx site from scratch. If not, you can skip most of this and just add the relevant config snippets to your configuration.
First, you'll need to acquire a domain. You can also get free subdomains from https://freedns.afraid.org. Make sure your domain or subdomain is pointed to your IP address and ports are open.
Next, install nginx:
choco install nginx
Then, you'll want to save wsproxy_params to your Nginx directory, which enables WebSocket proxying.
cd C:\tools\nginx*
curl https://computernewb.com/~elijah/wsproxy_params -o wsproxy_params
If you use Cloudflare reverse proxying, make SURE to open this file and uncomment the indicated line.
Create a directory to store site configurations:
mkdir sites
Open up conf\nginx.conf
and add the following to the bottom of your http { ... }
block:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include ../sites/*.conf;
Now, create a configuration for your nginx site that includes a proxy statement for your VM.
C:\tools\nginx-[version]\sites\example.com.conf
server {
server_name example.com;
listen 80;
index index.html;
# You can change this to the absolute path of your site's webroot, or leave it if you don't have a site other than CollabVM
root html;
location /collab-vm/vm1 {
include ../wsproxy_params;
proxy_pass http://127.0.0.1:6004/;
}
}
The last step is to set up SSL (if you use Cloudflare reverse proxying you can skip this as Cloudflare will handle SSL for you). Install win-acme:
choco install win-acme
refreshenv
Create a directory for the SSL certs:
mkdir ssl
Grab the certs. Example command:
wacs --host example.com (REPLACE WITH YOUR DOMAIN) --webroot html (REPLACE WITH YOUR WEBROOT IF YOU CHANGED IT) --validation filesystem --source manual --store pemfiles --pemfilespath ssl --accepttos
Install the certs to your nginx conf:
C:\tools\nginx-[version]\sites\example.com.conf
server {
server_name example.com;
listen 80;
listen 443 ssl;
ssl_certificate ../ssl/example.com-chain.pem;
ssl_certificate_key ../ssl/example.com-key.pem;
}
Finally, restart nginx to apply the config
net stop nginx
net start nginx
If all went well, your VM is now available at wss://example.com/collab-vm/vm1
Permanently host the webapp
If you want to host the webapp on your website, you can build it as follows:
cd C:\collabvm\collab-vm-1.2-webapp
yarn build
Then, copy the contents of the dist
directory to your website. For example, if your webroot is at /var/www/example.com
, and you want your webapp at example.com/collab-vm/:
xcopy /S /Y dist C:\path\to\your\webroot\collab-vm\
The webapp should now be accessible at your website.
Logging in as an admin (or mod)
Logging in is very simple. Just join the VM, and double click your username. Enter your admin or mod password into the prompt, and you should be authenticated and able to use staff actions.
Getting your UserVM on the roster
Now you can have your UserVM put on the roster! Join our Discord, and create a post in #support with the uservm roster update
tag, including your VM's WebSocket URL. You can ping me (@elijahr.dev) if you'd like.