无显示器使用Linux主机(Ubuntu 24.04.2 LTS)实录

前言

五一的时候,主包拥有了自己第一台主机(mini版)。因为觉得有ssh控制就已经很满足了,所以并没有察觉到显示屏的重要性。直到卸载Win10安装Ubuntu后,由于联发科网卡反复出现网络问题(吐槽一嘴,Linux的联发科的驱动真的不太行,建议直接换Intel原生态的网卡),导致不得不需要显示屏才能控制主机(故琢磨一天,总结了几种方案)

视频采集卡 + OBS studio(推荐)

懒人版,需要有一台可以使用HDMI或者DB线的笔记本电脑(?),总之就是一台宿主机

  1. 宿主机安装OBS studio软件,充当主机视频信号载体
  2. 主机接HDMI线连接视频采集卡,视频采集卡接入宿主机
  3. OBS studio新增一个视频窗口,初始化部分应该是可以检测到视频采集卡的,然后就大功告成了
    • 大致方案为,找到,添加视频采集设备,然后按照识别到的视频采集卡设备进行设置,例如我是UGREEN HDMI Capture,其他配置一律默认即可

远程控制软件 + Xorg服务器(不推荐!!!)

可能需要借用一个显示屏配置一下ToDesk()

安装ToDesk

使用ToDesk(总体还行,就是画质太低,连接不流畅)远程控制软件,当然也可以用向日葵(没用过不评价)

sudo apt update
sudo wget https://dl.todesk.com/linux/todesk-v4.7.2.0-amd64.deb
sudo apt install ./todesk-v4.7.2.0-amd64.deb

或者可以直接去https://dl.todesk.com/linux/todesk-v4.7.2.0-amd64.deb 下载安装包在你想要的位置,然后使用apt或者dpkg安装。
出现依赖问题可能可以尝试
sudo apt --fix-broken install
# 或者是
sudo apt install libappindicator3-dev

最后尝试启动Todesk,并配置

  • 方便连接,我们可以取消临时密码,而使用安全密码
  • 为了弥补安全密码的不安全,可以设置白名单,只允许指定设备连接主机
    1751945192925

使用X11桌面

目前大部分远程控制软件仅支持X11桌面协议,而目前Ubuntu发行版默认采用WayLand协议,所以即使在有显示屏的情况下,也无法使用ToDesk连接。所以我们先调整桌面协议

首先可以先确认一下桌面协议

echo $XDG_SESSION_TYPE
# x11 代表X11协议
# wayland代表WayLand协议

然后确认一下你目前使用的display manager,默认采用的是gdm,当然某些同学可能使用的是lightdm(主包使用的默认的gdm,因为懒得再仔细配置lightdm了)
systemctl status display-manager.service
# gdm.service - GNOME Display Manager
# 也可能是lightdm.service - Light Display Manager

我们要求display-manager.service的状态一定为Active,请观察service的Active状态,如果不是active那么可以优先考虑检查默认启用的运行级别
sudo sytemctl get-default
# graphical.target or multi-user.target

如果采用了multi-user.target,那么display manager是不会默认启动的,此时需要设置默认运行级别为图形化界面(graphical.target)
sudo systemctl set-default graphical.target

随后对display-manager的配置进行修改以满足桌面协议要求
对于gdm

  • 如果确实是桌面协议为WayLand,打开/etc/gdm3/custom.conf,修改下面的部分
    [daemon]
    # Uncomment the line below to force the login screen to use Xorg
    # WaylandEnable=false
    取消WayLandEnable=false的注释,此时将使用X11桌面协议启动桌面

对于lightdm:

  • 不知道,尝试了一下,确实启动了Xorg服务器,一切都看似正常,但是ToDesk无法连接

配置X.org服务器

由于X协议将默认启动一个X.org会话用于登录界面,而默认的X.org服务会话只会默认检测显卡驱动与物理屏进行通信。所以我们需要增加一个用于虚拟屏幕的配置,这里采用的是dummy驱动,它将使用RAM的部分内存开启一个只存在于内存中的虚拟屏

首先我们下载与X.org服务器和dummy有关的包

sudo apt update
sudo apt install xserver-xorg-core
sudo apt install xserver-xorg-video-dummy

找到X.org服务器的配置路径,一般管理员为/etc/X11/xorg.conf.d,用户为/usr/share/X11/xorg.conf.d/,这里我配置在用户路径下

新建配置文件,命名要求为number-name.conf,number可以取10~99内的数,用于表示配置的优先级,name可以随意配置满足一定的语义即可,写入如下内容,分辨率可以自行修改,但是自测似乎不能达到特别大,或许是因为虚拟屏的限制,即使分配了足够的内存也无法开启

Section "Monitor"
Identifier "Monitor0"
HorizSync 28.0-80.0
VertRefresh 48.0-75.0
# 1920x1200 59.88 Hz (CVT 2.30MA) hsync: 74.56 kHz; pclk: 193.25 MHz
Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync
# 2360x1640 @ 60.00 Hz (GTF) hsync: 232.50 kHz; pclk: 595.60 MHz
Modeline "2360x1640_60.00" 328.50 2360 2536 2792 3224 1640 1643 1653 1700 -hsync +vsync
EndSection

Section "Device"
Identifier "Card0"
Driver "dummy"
VideoRam 256000
EndSection

Section "Screen"
DefaultDepth 24
Identifier "Screen0"
Device "Card0"
Monitor "Monitor0"
SubSection "Display"
Depth 24
Modes "1920x1200_60.00"
EndSubSection
EndSection

注意

还有一点,如果dummy配置的优先级过高,会直接覆盖物理屏的配置,导致即使有物理屏连接也显示黑屏,此时可以尝试修改dummy配置的优先级参数,或者直接移除dummy配置。但是如果你使用的是一个无头服务器那么直接无脑拉到最高即可!

检验

重启主机或者重启gdm服务

sudo reboot
# or
sudo systemctl restart gdm.service

检测gdm是否正常,观察Active状态
$ sudo systemctl status gdm.service

chi@chi-EliteMini-Series:~/document/blog$ sudo systemctl status gdm.service
● gdm.service - GNOME Display Manager
Loaded: loaded (/usr/lib/systemd/system/gdm.service; static)
Active: active (running) since Fri 2025-05-30 15:56:22 CST; 1h 25min ago
Process: 1388 ExecStartPre=/usr/share/gdm/generate-config (code=exited, status=0/SUCCESS)
Main PID: 1427 (gdm3)
Tasks: 4 (limit: 35578)
Memory: 7.0M (peak: 9.7M)
CPU: 78ms
CGroup: /system.slice/gdm.service
└─1427 /usr/sbin/gdm3

检测Xorg服务器是否正常,你应该看到某个Xorg进程在运行

$ ps aux | grep Xorg | grep -v grep
chi 5334 7.0 0.7 733976 231280 tty2 Sl+ 15:58 6:07 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3

X.org目前的参数配置完全不起作用,因为ToDesk等远程控制软件控制时将重新启动一个X.org进程,但是为了方便后续检验请记录如下参数

  • auth: /run/user/1000/gdm/Xauthority

检测虚拟屏是否设置良好
正常结果类似如下,可以看到dummy驱动了虚拟显示屏可以选择的分辨率

Screen 0: minimum 64 x 64, current 1920 x 1200, maximum 32767 x 32767
DUMMY0 connected primary 1920x1200+0+0 0mm x 0mm
1920x1200_60.00 59.88*+
1920x1200 59.88
1920x1080 59.96
1600x1200 60.00
1680x1050 59.95
1400x1050 59.98
1600x900 59.95
1280x1024 75.02 60.02
1400x900 59.96
1280x960 60.00
1368x768 59.88
1280x800 59.81
1152x864 75.00
1280x720 59.86
1024x768 75.03 70.07 60.00
1024x576 59.90
832x624 74.55
960x540 59.63
800x600 72.19 75.00 60.32 56.25
864x486 59.92
640x480 75.00 72.81 59.94
DUMMY1 disconnected
DUMMY2 disconnected
DUMMY3 disconnected
DUMMY4 disconnected
DUMMY5 disconnected
DUMMY6 disconnected
DUMMY7 disconnected
DUMMY8 disconnected
DUMMY9 disconnected
DUMMY10 disconnected
DUMMY11 disconnected
DUMMY12 disconnected
DUMMY13 disconnected
DUMMY14 disconnected
DUMMY15 disconnected

依次尝试
$ xrandr
# 如果配置时已经接入物理显示屏则可能显示物理显示屏
# 建议重启后使用ssh连接判断,则可能显示下面
Can't open display

$ xrandr --display :0
$ xrandr --display :1
# 由于目前只设置了很少的显示屏,可以尝试判断一下虚拟屏在那个位置
# 如果不再显示Can't open display :0或者:1而是显示如下,可以参考下一步
Authorization required, but no authorization protocol specified

依据X.org服务器进程的参数进行填空

$ sudo env DISPLAY=? XAUTHORITY=/run/user/.../gdm/Xauthority xrandr
# ?代表上次指令运行时出现Authorization问题的显示屏,例如我是:0
# ...代表目录下的uid,120代表gdm用户,1000代表比如chi用户
# 例如我的命令是:sudo env DISPLAY=:0 XAUTHORITY=/run/user/120/gdm/Xauthority xrandr

出现分辨率则设置成功,否则可以发现在/var/log/Xorg.0.log之类的日志

Sunshine + Xorg服务器(一般般)

安装并使用Sunshine

https://github.com/LizardByte/Sunshine
科学上网,有序安装
网上有教程配置Sunshine

提醒:给主机插根网线串流,否则找不到IP的

启动Xorg服务器

同上即可,直接弥补了Sunshine与Moonlight串流需要显示屏的问题

x11VNC + Xorg服务器(推荐,yyds)

使用vnc转发X.org服务器,达到类似远程桌面的功能。不仅连接快,轻量,而且支持自定义的配置也很多,反正比远程控制友好

启动Xorg服务器

同理如上,启动了Xorg即可

安装并配置x11vnc

sudo apt update
sudo apt install x11vnc

按照配置Xorg服务器运行下面指令

$ sudo x11vnc -display ? -xkb -auth /run/user/.../gdm/Xauthority -forever -noxdamage -passwd ??? -rfbport 5901 -bg

  • 此处displayauth需要匹配你的Xorg服务器
  • passwd可以自己设置
  • 我转发到了5901端口,默认转发5900 + 你的display号

若出现无法共享内存bug,即

X11 MIT Shared Memory Attach failed:
Is your DISPLAY=:1 on a remote machine?
Suggestion, use: x11vnc -display :0 ... for local display :0

caught X11 error:
30/05/2025 21:45:45 deleted 60 tile_row polling images.
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 130 (MIT-SHM)
Minor opcode of failed request: 1 (X_ShmAttach)
Serial number of failed request: 55
Current serial number in output stream: 117

  1. 尝试加上-noshm参数,但是视频的传输就不太行了
  2. 不使用sudo权限,因为这个gdm服务进程似乎是gdm用户启动的

则会出现如下类似的输出

The VNC desktop is:      chi-EliteMini-Series:1
PORT=5901

******************************************************************************
Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?

The scheme stores pixel data offscreen on the VNC viewer side for faster
retrieval. It should work with any VNC viewer. Try it by running:

x11vnc -ncache 10 ...

One can also add -ncache_cr for smooth 'copyrect' window motion.
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching

最终检测,x11vnc进程是否存在

$ ps aux | grep x11vnc | grep -v grep
chi 628825 0.0 0.0 53788 14124 ? Ss 21:50 0:00 x11vnc -display :0 -auth /run/user/120/gdm/Xauthority -forever -noxdamage -rfbport 5901 -bg

使用VNC工具连接

这里使用realvnc示例,输入主机IP和端口(5901),使用密码进行登录
1751961311838

可能的错误

可能出现的错误情况:刚开始正常登录进去,然后在登录页面输入账号密码就直接闪退,然后不让登录
1751947686520

原因

# 用户登录前
chi@chi-EliteMini-Series:~$ ps aux | grep Xorg | grep -v grep
gdm 4783 0.5 0.2 572412 88812 tty1 Sl+ 16:09 0:00 /usr/lib/xorg/Xorg vt1 -displayfd 3 -auth /run/user/120/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3

chi@chi-EliteMini-Series:~$ ps aux | grep x11vnc | grep -v grep
root 5518 0.0 0.0 51940 21456 ? Ss 16:09 0:00 x11vnc -display :0 -auth /run/user/120/gdm/Xauthority -forever -noxdamage -rfbport 5901 -bg -noshm

# 用户登录后
chi@chi-EliteMini-Series:~$ ps aux | grep Xorg | grep -v grep
chi 5584 1.3 0.3 586896 96084 tty2 Sl+ 16:11 0:00 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3

chi@chi-EliteMini-Series:~$ ps aux | grep x11vnc | grep -v grep
  • 可以发现两个X.org进程并不是同一个,“新创建”的进程并没有VNC转发

这个问题是由于启动X.org的用户(例如gdm用户)和默认登录的用户(例如chi用户)是不一样的。例如你可能发现最开始的X.org服务进程是由120(gdm)用户开启的,你的vnc转发也是基于gdm用户开启的X.org服务进程进行的。这导致了你登录后GDM为登录用户(例如1000chi用户)开启了一个新的虚拟终端,并在新的虚拟终端运行了一个新的X.org进程,这个X.org进程显然是没有vnc进行转发的,所以出现了登录进去后立刻闪退的情况

解决方案

我们只需要使得最开始启动X.org的用户和默认登录用户一致即可,这样GDM会复用虚拟终端,就不会新建一个X.org服务进程,自然不会闪退了

对gdm的配置(/etc/gdm3/custom.conf)进行修改,让默认登录的用户开启X.org进程

WaylandEnable = false

# Enabling automatic login
AutomaticLoginEnable = true
AutomaticLogin = chi

  • AutomaticLogin:填写你的登录用户名

重启电脑或者gdm服务,再次尝试登录应该就没有问题了

开机服务

当然,这样还是太麻烦了,每次我们都需要使用ssh连接去转发X.org服务进程然后才能使用,我们完全可以写一个开机服务,在图形化页面服务完成后,自动启动x11vnc转发出去

[Unit]
Description=x11vnc server for autologged-in chi user on display :0
After=graphical.target gdm.service graphical-session.target
Requires=gdm.service
PartOf=graphical-session.target

[Service]
Type=simple
User=chi
Group=chi

# 等待用户会话和 X server 准备好
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/x11vnc -remap /home/chi/.x11vnc_remap -display :0 -xkb -auth /run/user/1000/gdm/Xauthority -forever -noxdamage -passwd ??? -rfbport 5901 -o /home/chi/.x11vnc-autologin.log
Restart=on-failure
RestartSec=10s
Environment="DISPLAY=:0"

[Install]
WantedBy=graphical.target

  • -remap参数:用于重新建立某些键的映射,如果没有出现映射错误问题可以不用该参数
  • -display参数:指定转发的屏幕,此处由于gdm会默认开启第一个屏幕,指定为:0即可
  • -xkb:更加现代化的键盘映射,但是看起来没什么用
  • -auth: 用户的登录凭证,按照自己的凭证即可
  • -passwd:输入自己的密码
  • -rfbport:指定转发端口,默认5900 + display_number
  • -o:日志输出

VNC服务器(一般般)

上一个方法是我们自己开一个Xorg,并使用x11vnc传出去,配置起来略显麻烦,如果你不建议更加轻量化(简陋。。。)的图形化页面的话,可以直接使用现代的vnc服务器,通过X.org服务器以及转发。

下载vncserver

sudo apt update
sudo apt install tigervnc-standalone-server tigervnc-common tigervnc-xorg-extension
sudo apt install xterm

下载轻量化的图形化页面

sudo apt update
sudo apt install openbox
# 或者
sudo apt install xfce4 xfce4-goodies
  • 不建议用GNOME这种重量级的,不知道为什么启动失败了,可能是太重了

初始化vncserver

chi@chi-EliteMini-Series:~$ vncserver

You will require a password to access your desktops.

Password: # 输入密码
Verify: # 重复输入密码
Would you like to enter a view-only password (y/n)? y
Password: # 输入密码
Verify: # 重复输入密码

New Xtigervnc server 'chi-EliteMini-Series:1 (chi)' on port 5901 for display :1.
Use xtigervncviewer -SecurityTypes VncAuth -passwd /tmp/tigervnc.LNalSu/passwd :1 to connect to the VNC server.
  • 可以看到vncserver已经建立起来了,并转发到5901端口

配置vncserver

清除当前的vncserver进程

vncserver -kill :1

配置xstartup文件

touch ~/.vnc/xstartup

#!/bin/bash
# [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup

[ -r "$HOME/.Xresources" ] && xrdb "$HOME/.Xresources"

# 设置一个简单的背景颜色
xsetroot -solid grey

# 启动 vncconfig 用于剪贴板等功能 (在后台运行)
vncconfig -iconic &

# 启动一个终端 (在后台运行,这样窗口管理器是最后一个主要进程)
xterm -geometry 100x30+10+10 -ls -title "$VNCDESKTOP Desktop" &

# 启动窗口管理器 (或桌面环境)
# 使用 'exec' 可以让窗口管理器进程替换 xstartup 脚本的进程,

# 启动 Openbox
exec openbox-session
# 如果你想用 XFCE
# exec xfce4-session

正式启动vncserver

# 确保没有正在运行的server
vncserver -kill :1
vncserver :1 -geometry 1920x1080 -depth 24 -localhost no