Kali on Hyper-V Gen1: black console and an RDP session that dies in zero seconds
Four stacked causes behind a Kali VM with no desktop and an xrdp session that closes instantly — and why the obvious fix for the first one breaks the second.
I run my offensive-security lab as a Kali Linux VM on a Windows Server Hyper-V host. After a rebuild it came up broken in two ways at once:
- the Hyper-V console showed a black screen, or at best a text TTY — no Xfce desktop;
- RDP connected, showed the session for a fraction of a second, and closed. Zero seconds.
Searching either symptom gives you a dozen one-line answers, and each of them fixes part of the problem while quietly breaking something else. It took four separate fixes, in the right order, to get both the console and RDP working and surviving reboots. Here is the chain.
The setup that makes this hard
A Generation 1 Hyper-V VM exposes two video devices to the guest:
- a legacy emulated PCI adapter (
1414:5353, the Microsoft synthetic VGA), and - the
hyperv_drmkernel driver on VMBus, which shows up as/dev/dri/card0.
Most guides assume there is one GPU. With two, Xorg has to be told exactly which one to use, or it picks badly.
Cause 1 — nomodeset disables the driver you need
Somewhere along the way the kernel command line had picked up nomodeset, a common “fix” for
black screens on VMs. On this VM it is the cause: it prevents hyperv_drm from doing kernel
mode-setting, so Xorg has no usable display at all.
# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet" # no nomodeset
sudo update-grub
Cause 2 — legacy X drivers fight KMS
xserver-xorg-video-vesa and xserver-xorg-video-fbdev were installed. With KMS working again,
they still got probed and competed with the modesetting driver. Remove them:
sudo apt-get remove --purge xserver-xorg-video-vesa xserver-xorg-video-fbdev
Cause 3 — Xorg picks the wrong GPU and deletes its own screen
With both devices visible, Xorg tried the legacy PCI framebuffer, failed, and logged the memorable:
Cannot run in framebuffer mode. Please specify busIDs for all framebuffer devices
…then deleted Screen 0. The fix is to pin the modesetting driver to the DRM device explicitly and stop Xorg from auto-adding the other GPU:
# /etc/X11/xorg.conf.d/20-modesetting.conf
Section "ServerFlags"
Option "AutoAddGPU" "off"
EndSection
Section "Device"
Identifier "Card0"
Driver "modesetting"
Option "kmsdev" "/dev/dri/card0"
EndSection
After this the console desktop came back. RDP was now worse.
Cause 4 — xrdp reads the same config directory
This is the step no one-liner mentions. The Xorg instance that xorgxrdp starts for each RDP
session is launched with its own -config file but no -configdir, so it also loads everything
in /etc/X11/xorg.conf.d/. My new file told it to open /dev/dri/card0 — which the console
session already owned. The RDP Xorg failed to start and the session died instantly.
The fix is to scope the config to the physical seat, so only the console’s Xorg matches it and xrdp falls back to its own dummy driver:
Section "ServerFlags"
Option "AutoAddGPU" "off"
EndSection
Section "Device"
Identifier "Card0"
MatchSeat "seat0"
Driver "modesetting"
Option "kmsdev" "/dev/dri/card0"
EndSection
Section "Screen"
Identifier "Screen0"
MatchSeat "seat0"
Device "Card0"
EndSection
Section "ServerLayout"
Identifier "Layout0"
MatchSeat "seat0"
Screen 0 "Screen0"
EndSection
sudo systemctl restart lightdm xrdp xrdp-sesman
Console and RDP both work, and the setup survives reboots.
Takeaways
- Count your GPUs first.
lspci | grep -i vgaandls /dev/dri/tell you in five seconds whether you are in the two-device situation. nomodesetis a diagnostic, not a fix. It turns off the driver most modern VMs need.- Global X config is global. Anything in
xorg.conf.dalso affects xrdp’s Xorg. Scope it withMatchSeatwhen it is meant for the physical console only. - One gotcha that remains: Xfce won’t happily run two sessions for the same user, so don’t stay logged in on the console as the user you connect with over RDP.
I keep the final config plus a one-command restore script with my lab notes, so rebuilding the VM is now a two-minute job instead of an afternoon.