Manjaro GNOME Headless RDP 配置记录
适用于:
- Manjaro Linux
- GNOME 50
gnome-remote-desktop- Wayland
- NVIDIA vGPU / NVIDIA GPU
- 通过 SSH 以
root身份完成配置 - 目标用户:
da
1. 问题背景
最开始使用 GNOME 自带的 Remote Login:
RDP Client
↓
TCP 3389
↓
gnome-remote-desktop --system
↓
GDM
↓
RDP Server Redirection
↓
用户 Wayland SessionRDP 能成功连接,但部分客户端会出现:
黑屏
无法连接到远程电脑,因为未及时提供凭据
错误代码: 0x1f07服务端日志中能看到:
[RDP] Sending server redirection
ERRINFO_LOGOFF_BY_USER在 Windows .rdp 文件中增加:
use redirection server name:i:1后可以正常连接。
这说明:
- NVIDIA vGPU 并不是主要问题;
- GDM / GNOME Remote Login 已经能成功创建远程 Wayland Session;
- 问题主要来自部分 RDP 客户端对 Server Redirection 的处理兼容性。
为了避免每台客户端都要修改 .rdp 文件,最终改为:
GNOME Headless 单用户 RDP
新的连接路径:
RDP Client
↓
TCP 3389
↓
gnome-remote-desktop-daemon --headless
↓
GNOME Headless Wayland Session不再经过:
GDM
Server Redirection因此不再需要:
use redirection server name:i:12. 最终成功环境
实际成功环境:
gnome-remote-desktop 50.2-1
gnome-shell 50.4
mutter 50.4
pipewire 1.6.8NVIDIA:
NVIDIA RTXA5500-2Q
NVIDIA Driver 580.159.03DRM KMS:
cat /sys/module/nvidia_drm/parameters/modeset输出:
Y设备:
/dev/dri/card1
/dev/dri/renderD128成功后:
gnome-headless-session@da.service状态:
active (running)以及:
gnome-remote-desktop-headless.service状态:
active (running)3389:
LISTEN *:3389进程:
/usr/bin/gnome-shell --mode=user
/usr/lib/gnome-remote-desktop-daemon --headlessGNOME Remote Desktop 日志:
[HWAccel.CUDA] Initialization of CUDA was successful
RDP server started3. 重要说明
必须以 root 执行本文脚本
例如:
sudo -i确认:
whoami应输出:
root但是:
grdctl --headless本身配置的是普通用户da的用户级 GNOME Remote Desktop。
因此不能直接在 root 环境中运行:
grdctl --headless ...否则修改的是 root 自己的配置。
本文脚本会自动使用:
runuser -u da并正确注入:
XDG_RUNTIME_DIR=/run/user/1000
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus从而修改 da 用户的配置。
4. 一键配置脚本
建议保存为:
/root/fix-gnome-headless-rdp.sh完整脚本如下:
#!/usr/bin/env bash
set -Eeuo pipefail
USER_NAME="da"
UID_NUM="$(id -u "$USER_NAME")"
HOME_DIR="$(getent passwd "$USER_NAME" | cut -d: -f6)"
RUNTIME="/run/user/$UID_NUM"
BUS="unix:path=$RUNTIME/bus"
CERT_DIR="$HOME_DIR/.local/share/gnome-remote-desktop"
TLS_KEY="$CERT_DIR/rdp-tls.key"
TLS_CERT="$CERT_DIR/rdp-tls.crt"
if [ "$(id -u)" -ne 0 ]; then
echo "必须使用 root 执行"
exit 1
fi
echo
echo "=========================================="
echo " GNOME Headless RDP 修复"
echo " User: $USER_NAME"
echo " UID : $UID_NUM"
echo "=========================================="
echo
read -r -p "RDP 用户名 [da]: " RDP_USER
RDP_USER="${RDP_USER:-da}"
while true; do
read -r -s -p "请输入 RDP 密码: " RDP_PASS
echo
read -r -s -p "再次输入 RDP 密码: " RDP_PASS2
echo
if [ -n "$RDP_PASS" ] && [ "$RDP_PASS" = "$RDP_PASS2" ]; then
break
fi
echo "密码不一致,请重新输入。"
done
echo
echo "[1] 关闭原来的 GNOME system Remote Login..."
systemctl disable --now gnome-remote-desktop.service 2>/dev/null || true
echo
echo "[2] 清理旧的 GDM RDP 会话..."
while read -r session uid user rest; do
[ "$user" = "$USER_NAME" ] || continue
service="$(loginctl show-session "$session" -p Service --value 2>/dev/null || true)"
type="$(loginctl show-session "$session" -p Type --value 2>/dev/null || true)"
remote="$(loginctl show-session "$session" -p Remote --value 2>/dev/null || true)"
if [ "$service" = "gdm-password" ] &&
[ "$type" = "wayland" ] &&
[ "$remote" = "yes" ]; then
echo "终止旧 RDP 图形会话: $session"
loginctl terminate-session "$session" || true
fi
done < <(loginctl list-sessions --no-legend)
sleep 2
echo
echo "[3] 启用 da 用户 linger 和 user manager..."
loginctl enable-linger "$USER_NAME"
systemctl start "user@$UID_NUM.service"
for x in $(seq 1 20); do
[ -S "$RUNTIME/bus" ] && break
sleep 1
done
if [ ! -S "$RUNTIME/bus" ]; then
echo "错误:用户 D-Bus 没有启动"
systemctl status "user@$UID_NUM.service" --no-pager
exit 1
fi
as_da() {
runuser -u "$USER_NAME" -- env \
HOME="$HOME_DIR" \
USER="$USER_NAME" \
LOGNAME="$USER_NAME" \
XDG_RUNTIME_DIR="$RUNTIME" \
DBUS_SESSION_BUS_ADDRESS="$BUS" \
"$@"
}
echo
echo "[4] 关闭普通 Desktop Sharing..."
as_da systemctl --user disable --now \
gnome-remote-desktop.service 2>/dev/null || true
echo
echo "[5] 检查/创建 TLS 证书..."
install -d \
-o "$USER_NAME" \
-g "$USER_NAME" \
-m 700 \
"$CERT_DIR"
if [ ! -s "$TLS_KEY" ] || [ ! -s "$TLS_CERT" ]; then
echo "重新创建证书..."
rm -f "$TLS_KEY" "$TLS_CERT"
runuser -u "$USER_NAME" -- \
openssl req \
-new \
-newkey rsa:4096 \
-nodes \
-x509 \
-days 3650 \
-subj "/CN=da-manjaro" \
-keyout "$TLS_KEY" \
-out "$TLS_CERT"
fi
chown "$USER_NAME:$USER_NAME" \
"$TLS_KEY" "$TLS_CERT"
chmod 600 "$TLS_KEY"
chmod 644 "$TLS_CERT"
echo
echo "[6] 写入 Headless RDP 配置..."
as_da grdctl --headless rdp disable 2>/dev/null || true
as_da grdctl --headless rdp set-tls-key \
"$TLS_KEY"
as_da grdctl --headless rdp set-tls-cert \
"$TLS_CERT"
as_da grdctl --headless rdp set-auth-methods \
credentials
echo
echo "写入 RDP 用户名/密码..."
# 注意:
# GNOME Remote Desktop 50.x 支持直接使用:
# grdctl --headless rdp set-credentials USERNAME PASSWORD
#
# 不要使用 stdin 管道模拟输入。
# 某些版本中可能导致 grdctl 段错误。
as_da grdctl --headless rdp set-credentials \
"$RDP_USER" "$RDP_PASS"
as_da grdctl --headless rdp disable-view-only
as_da grdctl --headless rdp enable
unset RDP_PASS
unset RDP_PASS2
echo
echo "[7] 启动 GNOME Headless 图形 Session..."
if systemctl cat gnome-headless-session@.service >/dev/null 2>&1; then
echo "发现 gnome-headless-session@.service"
systemctl enable --now \
"gnome-headless-session@$USER_NAME.service"
else
echo "没有发现 gnome-headless-session@.service,跳过。"
fi
sleep 3
echo
echo "[8] 启动 GNOME Remote Desktop Headless..."
as_da systemctl --user daemon-reload
as_da systemctl --user enable --now \
gnome-remote-desktop-headless.service
sleep 2
as_da systemctl --user restart \
gnome-remote-desktop-headless.service
echo
echo "[9] 等待 RDP 端口..."
for x in $(seq 1 20); do
if ss -lnt | grep -qE ':3389[[:space:]]'; then
break
fi
sleep 1
done
echo
echo
echo "============== GRD STATUS =============="
as_da grdctl --headless status || true
echo
echo
echo "============== RDP PORT ================"
if ss -lntp | grep -E ':3389[[:space:]]'; then
echo
echo "✅ 3389 已监听"
else
echo
echo "❌ 3389 尚未监听"
fi
echo
echo
echo "============== PROCESS ================"
ps -ef | grep -E \
'gnome-shell|gnome-remote-desktop-daemon' \
| grep -v grep || true
echo
echo
echo "============== USER SERVICE ================"
as_da systemctl --user status \
gnome-remote-desktop-headless.service \
--no-pager -l || true
echo
echo
echo "============== HEADLESS SESSION ================"
systemctl status \
"gnome-headless-session@$USER_NAME.service" \
--no-pager -l 2>/dev/null || true
echo
echo
echo "============== GRD LOG ================"
as_da journalctl --user \
-u gnome-remote-desktop-headless.service \
-b -n 80 \
--no-pager || true
echo
echo
echo "=========================================="
if ss -lnt | grep -qE ':3389[[:space:]]'; then
echo "✅ GNOME Headless RDP 配置完成"
echo
echo "地址:服务器IP:3389"
echo "用户:$RDP_USER"
echo
echo "现在不经过 GDM Remote Login"
echo "也不需要:"
echo "use redirection server name:i:1"
else
echo "⚠️ 配置已经写入,但 3389 没有启动。"
echo "上面的 GRD LOG / HEADLESS SESSION 会显示具体原因。"
fi
echo "=========================================="5. 使用方法
第一步:进入 root
sudo -i第二步:创建脚本
例如:
nano /root/fix-gnome-headless-rdp.sh粘贴上面的脚本。
保存后:
chmod 700 /root/fix-gnome-headless-rdp.sh第三步:执行
/root/fix-gnome-headless-rdp.sh脚本会询问:
RDP 用户名 [da]:
请输入 RDP 密码:
再次输入 RDP 密码:用户名直接回车即可使用:
da6. 成功标准
执行:
ss -lntp | grep :3389应该能看到:
LISTEN ... *:3389 ...检查 Headless GNOME:
systemctl status gnome-headless-session@da.service应该:
Active: active (running)检查用户 GRD:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
systemctl --user status gnome-remote-desktop-headless.service应该:
Active: active (running)7. 查看 Headless RDP 配置
因为当前管理终端通常是 root SSH,因此不要直接:
grdctl --headless status应该执行:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
grdctl --headless status正常:
Overall:
Unit status: active
RDP:
Status: enabled
Port: 3389
Authentication methods: credentials
TLS certificate: /home/da/.local/share/gnome-remote-desktop/rdp-tls.crt
TLS key: /home/da/.local/share/gnome-remote-desktop/rdp-tls.key
Username: (hidden)
Password: (hidden)8. RDP 客户端连接
直接:
服务器IP:3389用户名:
da密码:
脚本配置的 RDP 密码不需要:
use redirection server name:i:19. 重启后验证
推荐最终执行:
reboot服务器启动后,不要先登录图形桌面,也不需要先 SSH。
直接在客户端测试:
服务器IP:3389如果仍然可以正常进入 GNOME 桌面,说明自动启动已经完整生效。
10. 常用诊断命令
检查 3389
ss -lntp | grep :3389检查进程
ps -ef | grep -E \
'gnome-shell|gnome-remote-desktop-daemon' \
| grep -v grep正常至少应该包含:
gnome-shell --mode=user
gnome-remote-desktop-daemon --headless检查 GNOME Headless Session
systemctl status gnome-headless-session@da.service \
--no-pager -l检查 Headless GRD 服务
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
systemctl --user status \
gnome-remote-desktop-headless.service \
--no-pager -l查看 GRD 日志
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
journalctl --user \
-u gnome-remote-desktop-headless.service \
-b \
--no-pager只看最近 100 行:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
journalctl --user \
-u gnome-remote-desktop-headless.service \
-b -n 100 \
--no-pager11. NVIDIA 检查
DRM KMS
cat /sys/module/nvidia_drm/parameters/modeset正常:
YNVIDIA GPU
nvidia-smi正常情况下可以看到:
gnome-shell
gnome-remote-desktop-daemon占用 GPU。
DRM 设备
ls -l /dev/dri/例如:
card1
renderD12812. MESA-EGL warning 是否需要处理?
实际成功日志中可能出现:
MESA-EGL: warning: pci id for fd ... driver (null)
MESA-EGL: warning: egl: failed to create dri2 screen但是后面如果紧接着:
[HWAccel.CUDA] Initialization of CUDA was successful
RDP server started并且:
ss -lntp | grep :3389能够看到监听,同时客户端 RDP 能正常连接,那么这些 warning 当前可以忽略。
尤其在:
NVIDIA vGPU
NVIDIA 官方/自定义驱动
GNOME Wayland组合下,Mesa 探测 NVIDIA DRM 设备时出现 warning 并不一定意味着 GRD 启动失败。
13. TPM 警告
可能反复看到:
Init TPM credentials failed because No TPM device found,
using GKeyFile as fallback.这不是故障。
在 Proxmox VM 没有配置虚拟 TPM 时:
TPM 不存在
↓
GNOME Remote Desktop 检测失败
↓
自动 fallback 到 GKeyFile因此可以忽略。
14. 常见错误:Cannot autolaunch D-Bus
如果直接在 root SSH 中执行:
systemctl --user ...可能出现:
Failed to connect to user scope bus
$DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined原因:
root SSH shell不是:
da 的 user systemd session必须使用:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
systemctl --user ...15. 常见错误:RDP server certificate is invalid
如果 root 下直接:
grdctl --headless status出现:
RDP server certificate is invalid通常不是 da 配置坏了。
因为此时检查的是:
root 的 headless GRD 配置而不是:
da 的配置正确方式:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
grdctl --headless status16. set-credentials 段错误
曾经使用:
printf '%s\n%s\n' "$RDP_USER" "$RDP_PASS" | \
grdctl --headless rdp set-credentials结果:
段错误 (核心已转储)当前版本建议直接:
grdctl --headless rdp set-credentials USERNAME PASSWORD脚本已经使用:
as_da grdctl --headless rdp set-credentials \
"$RDP_USER" "$RDP_PASS"不要再用 stdin 管道模拟交互输入。
17. 原始 GNOME Remote Login 与 Headless 的区别
原 Remote Login
客户端
↓
3389
↓
gnome-remote-desktop --system
↓
GDM
↓
创建用户 Session
↓
Server Redirection
↓
gnome-remote-desktop --handover优点:
- 支持类似登录管理器的体验;
- 可以先看到 GDM;
- 理论上适合多用户。
缺点:
- 部分 RDP 客户端对 Server Redirection 兼容不好;
- 可能需要:
use redirection server name:i:1Headless 单用户模式
客户端
↓
3389
↓
da 用户 Headless GRD
↓
GNOME Headless Session优点:
- 不经过 GDM;
- 不需要 Server Redirection;
- 不需要每台客户端修改
.rdp; - 适合单用户远程工作站;
- VM 重启后可自动启动;
- Wayland 原生;
- NVIDIA GPU / vGPU 可继续使用。
缺点:
- 固定为指定用户;
- 不提供传统 GDM 登录界面;
- 多用户场景不如 system Remote Login 灵活。
18. 恢复到原来的 GNOME Remote Login
如果未来想撤销 Headless 模式:
先进入 root:
sudo -i关闭 Headless Session:
systemctl disable --now \
gnome-headless-session@da.service关闭用户 Headless GRD:
runuser -u da -- env \
HOME=/home/da \
XDG_RUNTIME_DIR=/run/user/1000 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
systemctl --user disable --now \
gnome-remote-desktop-headless.service然后重新开启 system Remote Login:
systemctl enable --now \
gnome-remote-desktop.service检查:
ss -lntp | grep :3389此时重新回到:
system GRD
↓
GDM
↓
Server Redirection客户端如果再次黑屏,则 .rdp 文件需要:
use redirection server name:i:119. 最终结果
最终成功状态:
GNOME Headless Session ✅
GNOME Remote Desktop ✅
RDP TCP 3389 ✅
TLS ✅
Credentials ✅
GNOME Shell ✅
Wayland ✅
NVIDIA CUDA acceleration ✅
Server Redirection 不再需要
.rdp 手工修改 不再需要最终客户端只需要:
服务器IP:3389即可连接。
记录日期
2026-09-15