一、环境与最终架构
本文适用于:
系统:Armbian 23.02.2 Jammy
基础系统:Ubuntu 22.04 LTS
架构:aarch64 / arm64
内存:4GB
存储:约 15GB eMMC
桌面:MATE
使用用户:root最终架构:
Internet
│
Cloudflare Tunnel
│
▼
自己的域名
│
▼
noVNC :6081
│
▼
TigerVNC :5901
│
▼
DISPLAY=:1
│
MATE Desktop
│
┌───────────────────┼─────────────────┐
│ │ │
XRDP Firefox Clash Verge
:3389 Fcitx5拼音整个系统只维护:
DISPLAY=:1一个真实桌面。
RDP 和浏览器 noVNC 全部看同一个桌面。
二、更换 Ubuntu / Armbian 下载源
1. 确认架构
uname -m
dpkg --print-architecture正常:
aarch64
arm642. 备份源
cp -a /etc/apt/sources.list \
/etc/apt/sources.list.bak.$(date +%Y%m%d-%H%M%S)cp -a /etc/apt/sources.list.d/armbian.list \
/etc/apt/sources.list.d/armbian.list.bak.$(date +%Y%m%d-%H%M%S) \
2>/dev/null || true3. Ubuntu ARM64 使用 USTC
cat > /etc/apt/sources.list <<'EOF'
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse
EOF4. Armbian 使用台湾镜像
cat > /etc/apt/sources.list.d/armbian.list <<'EOF'
deb [signed-by=/usr/share/keyrings/armbian.gpg] http://mirror.twds.com.tw/armbian-apt jammy main jammy-utils jammy-desktop
EOF注意:
该源虽然比之前自动分配的 Netcup 节点好一些,但我们实测 Firefox 大文件仍可能只有几十 KB/s。
所以 Firefox 后面不要从这个 Armbian 源下载安装。
5. 更新
apt clean
rm -rf /var/lib/apt/lists/*
apt updateUSTC 正常情况下应该能达到数 MB/s。
三、安装 MATE / TigerVNC / XRDP / noVNC 基础组件
apt install -y \
git wget curl gpg dbus-x11 \
xrdp \
tigervnc-standalone-server \
tigervnc-tools \
websockify \
mate-desktop-environment-core \
mate-terminal \
mate-system-monitor \
mate-utils \
mate-panel \
mate-applets \
caja \
caja-open-terminal \
mate-polkit \
mate-notification-daemon \
network-manager-gnome \
gnome-keyring \
at-spi2-core \
arc-theme \
papirus-icon-theme \
mate-applet-brisk-menu四、中文环境
apt install -y \
language-pack-zh-hans \
language-pack-gnome-zh-hans \
fonts-noto-cjk \
fonts-wqy-microheilocale-gen zh_CN.UTF-8系统全局保持:
cat > /etc/default/locale <<'EOF'
LANG=en_US.UTF-8
LANGUAGE=en_US:en
EOF不要设置全局:
LC_ALL=zh_CN.UTF-8中文只在 MATE 桌面会话中启用。
五、配置 MATE
dbus-run-session -- gsettings set \
org.mate.session required-components-list \
"['windowmanager']"打开桌面:
dbus-run-session -- gsettings set \
org.mate.background show-desktop-icons true主题:
dbus-run-session -- gsettings set \
org.mate.interface gtk-theme 'Arc'
dbus-run-session -- gsettings set \
org.mate.interface icon-theme 'Papirus'
dbus-run-session -- gsettings set \
org.mate.Marco.general theme 'Arc'六、安装 Fcitx5 中文拼音
apt install -y \
fcitx5 \
fcitx5-chinese-addons \
fcitx5-config-qt \
fcitx5-frontend-gtk3 \
fcitx5-frontend-qt5 \
im-config设置:
im-config -n fcitx5创建目录:
mkdir -p /root/.config/fcitx5
mkdir -p /root/.local/share/fcitx5/pinyin配置:
cat > /root/.config/fcitx5/profile <<'EOF'
[Groups/0]
Name=默认
Default Layout=us
DefaultIM=pinyin
[Groups/0/Items/0]
Name=pinyin
Layout=
[Groups/0/Items/1]
Name=keyboard-us
Layout=
[GroupOrder]
0=默认
EOFShift 切中英文:
cat > /root/.config/fcitx5/config <<'EOF'
[Hotkey]
EnumerateWithTriggerKeys=False
EnumerateSkipFirst=False
[Hotkey/TriggerKeys]
0=Control+space
[Hotkey/AltTriggerKeys]
0=Shift_L
1=Shift_R
[Behavior]
ActiveByDefault=True
EOF七、TigerVNC 常驻桌面
设置密码
mkdir -p /root/.vnc
tigervncpasswd /root/.vnc/passwd
chmod 600 /root/.vnc/passwd配置:
cat > /root/.vnc/config <<'EOF'
geometry=2160x1350
depth=24
localhost
alwaysshared
securitytypes=vncauth
EOF绑定 root:
grep -q '^:1=root$' /etc/tigervnc/vncserver.users \
|| echo ':1=root' >> /etc/tigervnc/vncserver.users八、创建 MATE 桌面启动脚本
cat > /usr/local/bin/mate-vnc-session.sh <<'EOF'
#!/bin/bash
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN:zh:en_US:en
export LC_MESSAGES=zh_CN.UTF-8
export XDG_SESSION_TYPE=x11
export XDG_CURRENT_DESKTOP=MATE
export DESKTOP_SESSION=mate
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
if ! pgrep -x fcitx5 >/dev/null 2>&1; then
fcitx5 -d >/tmp/fcitx5.log 2>&1 &
fi
sleep 1
mate-session &
MATE_PID=$!
sleep 2
if ! pgrep -x mate-panel >/dev/null 2>&1; then
mate-panel >/tmp/mate-panel-vnc.log 2>&1 &
fi
sleep 1
pkill -TERM -x caja 2>/dev/null || true
sleep 1
caja \
--no-default-window \
--force-desktop \
>/tmp/caja-vnc.log 2>&1 &
wait "$MATE_PID"
EOFchmod +x /usr/local/bin/mate-vnc-session.sh
bash -n /usr/local/bin/mate-vnc-session.sh无输出即正常。
九、TigerVNC Session
cat > /root/.vnc/Xtigervnc-session <<'EOF'
#!/bin/bash
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN:zh:en_US:en
export LC_MESSAGES=zh_CN.UTF-8
export XDG_SESSION_TYPE=x11
export XDG_CURRENT_DESKTOP=MATE
export DESKTOP_SESSION=mate
export XDG_RUNTIME_DIR=/run/user/0
mkdir -p "$XDG_RUNTIME_DIR"
chmod 700 "$XDG_RUNTIME_DIR"
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec dbus-run-session -- /usr/local/bin/mate-vnc-session.sh
EOFchmod +x /root/.vnc/Xtigervnc-session十、安装 noVNC
rm -rf /opt/novncgit clone \
--branch v1.3.0 \
--depth 1 \
https://github.com/novnc/noVNC.git \
/opt/novnc删除 Git 元数据:
rm -rf /opt/novnc/.git创建首页:
cat > /opt/novnc/index.html <<'EOF'
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0;url=/vnc.html?path=websockify&resize=scale&autoconnect=true">
<title>Remote Desktop</title>
<script>
location.replace('/vnc.html?path=websockify&resize=scale&autoconnect=true');
</script>
</head>
<body></body>
</html>
EOF服务:
cat > /etc/systemd/system/novnc.service <<'EOF'
[Unit]
Description=noVNC Web Remote Desktop
After=network-online.target tigervncserver@:1.service
Wants=network-online.target tigervncserver@:1.service
[Service]
Type=simple
ExecStart=/usr/bin/websockify --web=/opt/novnc 0.0.0.0:6081 127.0.0.1:5901
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
EOF配置novnc自动复制粘贴:
cat > /opt/novnc/clipboard-sync.js <<'EOF'
import UI from "./app/ui.js";
let lastRemoteText = "";
let lastLocalText = "";
/*
* 获取当前 RFB 实例
*/
function getRFB() {
if (!UI || !UI.rfb) {
return null;
}
return UI.rfb;
}
/*
* 本机浏览器剪贴板 -> 远程 TigerVNC
*/
async function syncLocalToRemote() {
const rfb = getRFB();
if (!rfb) {
return;
}
if (!navigator.clipboard || !navigator.clipboard.readText) {
return;
}
try {
const text = await navigator.clipboard.readText();
if (!text) {
return;
}
/*
* 避免远端刚同步回来的内容又循环发送
*/
if (text === lastRemoteText || text === lastLocalText) {
return;
}
lastLocalText = text;
rfb.clipboardPasteFrom(text);
console.debug("[noVNC Clipboard] Local -> Remote");
} catch (err) {
/*
* Firefox / Safari 或未授权时可能进入这里。
* Ctrl+V 的 paste 事件仍然可以工作。
*/
console.debug(
"[noVNC Clipboard] Cannot read browser clipboard:",
err
);
}
}
/*
* 用户直接 Ctrl+V 时:
* 浏览器剪贴板 -> 远程
*
* 这是兼容性最好的一种方式,
* 不依赖 navigator.clipboard.readText 权限。
*/
window.addEventListener("paste", function (event) {
const rfb = getRFB();
if (!rfb) {
return;
}
let text = "";
if (event.clipboardData) {
text = event.clipboardData.getData("text/plain");
}
if (!text) {
return;
}
lastLocalText = text;
rfb.clipboardPasteFrom(text);
/*
* 防止 Ctrl+V 同时被远程系统再次当作键盘事件,
* 避免重复粘贴。
*/
event.preventDefault();
event.stopPropagation();
console.debug("[noVNC Clipboard] Paste -> Remote");
}, true);
/*
* 远程 TigerVNC -> 本机系统剪贴板
*/
function hookRemoteClipboard() {
const rfb = getRFB();
if (!rfb) {
return;
}
/*
* 防止重复绑定
*/
if (rfb.__autoClipboardHooked) {
return;
}
rfb.__autoClipboardHooked = true;
rfb.addEventListener("clipboard", async function (event) {
if (!event.detail) {
return;
}
const text = event.detail.text;
if (typeof text !== "string") {
return;
}
lastRemoteText = text;
if (!navigator.clipboard ||
!navigator.clipboard.writeText) {
return;
}
try {
await navigator.clipboard.writeText(text);
console.debug(
"[noVNC Clipboard] Remote -> Local"
);
} catch (err) {
/*
* 浏览器拒绝后台写剪贴板时,
* noVNC 原本的 Clipboard 面板仍然可以使用。
*/
console.debug(
"[noVNC Clipboard] Cannot write browser clipboard:",
err
);
}
});
console.info(
"[noVNC Clipboard] Automatic clipboard synchronization enabled"
);
}
/*
* UI.rfb 是连接时才创建,
* 所以定期检测并挂载事件。
*/
setInterval(hookRemoteClipboard, 500);
/*
* 切回 noVNC 窗口时,
* 尝试自动把电脑剪贴板同步给远程。
*/
window.addEventListener("focus", function () {
setTimeout(syncLocalToRemote, 100);
});
/*
* 鼠标重新点击 VNC 区域时也尝试同步
*/
document.addEventListener("pointerdown", function () {
syncLocalToRemote();
}, {
passive: true
});
EOFsed -i '/<\/head>/i \ <script type="module" src="./clipboard-sync.js"></script>' /opt/novnc/vnc.html十一、配置 XRDP 共用 TigerVNC
备份:
cp -a /etc/xrdp/xrdp.ini \
/etc/xrdp/xrdp.ini.bak确认:
find /usr/lib -name libvnc.so然后:
python3 - <<'PY'
from pathlib import Path
import re
p = Path("/etc/xrdp/xrdp.ini")
text = p.read_text()
for section in ("Xorg", "GEA-Desktop"):
pattern = rf'(?ms)^\[{re.escape(section)}\]\s*\n.*?(?=^\[|\Z)'
text = re.sub(pattern, '', text)
text = re.sub(r'(?m)^autorun=.*$', 'autorun=', text)
vnc = """[Xorg]
name=GEA-Desktop
lib=libvnc.so
ip=127.0.0.1
port=5901
username=na
password=ask
code=0
delay_ms=2000
"""
pos = text.find("[Channels]")
if pos >= 0:
text = text[:pos] + vnc + text[pos:]
else:
text += "\n" + vnc
p.write_text(text)
PY检查:
grep -A10 '^\[Xorg\]' /etc/xrdp/xrdp.ini十二、开启远程桌面服务
systemctl daemon-reload
systemctl enable tigervncserver@:1.service
systemctl enable novnc.service
systemctl enable xrdp.service
systemctl enable xrdp-sesman.servicesystemctl restart tigervncserver@:1.service
sleep 4
systemctl restart novnc.service
systemctl restart xrdp.service检查:
ss -lntp | grep -E '3389|5901|6081'应该:
*:3389
127.0.0.1:5901
0.0.0.0:6081十三、安装 Clash Verge Rev —— 完整版
为什么要先装 Clash
当前实际网络测试说明:
USTC Ubuntu 源 几 MB/s
Armbian 大文件 十几~几百 KB/s
GitHub Release 直连 几十 KB/s
GitHub 经 gh-proxy 约 5~6 MB/s因此后面的 Firefox 官方下载需要 Clash 帮忙。
Clash Verge Rev 官方当前 v2.5.2 提供 Linux ARM64 .deb。
1. 下载 Clash Verge Rev ARM64
进入桌面目录:
cd /root/Desktop使用 GitHub 加速:
wget --no-proxy \
-O clash-verge-arm64.deb \
"https://gh-proxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v2.5.2/Clash.Verge_2.5.2_arm64.deb"检查:
ls -lh clash-verge-arm64.deb确认架构:
dpkg-deb -f clash-verge-arm64.deb Architecture必须:
arm64确认软件:
dpkg-deb -f clash-verge-arm64.deb Package
dpkg-deb -f clash-verge-arm64.deb Version2. 安装 Clash
apt install -y ./clash-verge-arm64.debAPT 可能额外安装:
libjavascriptcoregtk
libsoup
libwebkit2gtk这是正常依赖。
3. 查启动命令
command -v clash-verge如果返回:
/usr/bin/clash-verge直接启动:
DISPLAY=:1 clash-verge >/tmp/clash-verge.log 2>&1 &如果找不到:
dpkg -L clash-verge | grep -E '/bin/|\.desktop$'4. Clash Verge 中进行配置
在图形界面:
导入订阅
→ 更新订阅
→ 选择可用节点
→ 启动系统代理建议开始阶段:
先不用 TUN只使用系统代理。
5. 检查 Mihomo 代理端口
ss -lntp | grep -E '7890|7891|7897'之前这台设备实际端口为:
127.0.0.1:7897如果输出:
127.0.0.1:7897后文就全部使用 7897。
6. 测试 Clash
curl -x http://127.0.0.1:7897 \
-I https://packages.mozilla.org/能够快速返回 HTTP 响应说明代理正常。
十四、安装 Firefox —— 使用 Mozilla 官方 ARM64 DEB + Clash
重要
不要再执行:
apt install firefox直接从 Armbian 源下载。
因为现在会得到:
http://mirror.twds.com.tw/armbian-apt
Firefox 149而且下载可能只有:
17 KB/s我们改为 Mozilla 官方 DEB 仓库。
Mozilla 官方推荐 Debian/Ubuntu 使用 packages.mozilla.org APT 仓库安装 Firefox。
1. 创建密钥目录
install -d -m 0755 /etc/apt/keyrings2. 下载 Mozilla 官方密钥
文件很小:
wget -q \
https://packages.mozilla.org/apt/repo-signing-key.gpg \
-O /etc/apt/keyrings/packages.mozilla.org.asc检查:
ls -lh /etc/apt/keyrings/packages.mozilla.org.asc可验证官方指纹:
gpg -n -q \
--import \
--import-options import-show \
/etc/apt/keyrings/packages.mozilla.org.ascMozilla 官方给出的指纹为:
35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A33. 添加 Mozilla 仓库
cat > /etc/apt/sources.list.d/mozilla.list <<'EOF'
deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main
EOF4. 提高 Mozilla 优先级
cat > /etc/apt/preferences.d/mozilla <<'EOF'
Package: *
Pin: origin packages.mozilla.org
Pin-Priority: 1000
EOF5. 关键:明确让 APT 走 Clash
仅在 Clash Verge 里开启“系统代理”:
并不能保证 apt 使用代理所以必须明确指定:
apt \
-o Acquire::http::Proxy="http://127.0.0.1:7897" \
-o Acquire::https::Proxy="http://127.0.0.1:7897" \
update然后:
apt-cache policy firefox应该看到类似:
Candidate: 156.x并且来源:
https://packages.mozilla.org/apt优先级:
10006. 通过 Clash 下载 Firefox
apt \
-o Acquire::http::Proxy="http://127.0.0.1:7897" \
-o Acquire::https::Proxy="http://127.0.0.1:7897" \
install -y firefox这一步 Firefox 的 70~80MB 文件会明确走:
127.0.0.1:7897而不是依赖 Clash 的桌面系统代理设置。
7. 安装中文语言包
apt \
-o Acquire::http::Proxy="http://127.0.0.1:7897" \
-o Acquire::https::Proxy="http://127.0.0.1:7897" \
install -y firefox-l10n-zh-cn如果提示不存在:
apt-cache search firefox-l10n | grep -i zh根据实际名称安装。
Mozilla 官方 DEB 仓库提供 Firefox 的语言包。
8. 验证 Firefox
which firefox
firefox --version查看来源:
apt-cache policy firefox必须优先来自:
packages.mozilla.org9. 启动 Firefox
从 MATE 菜单直接打开。
或者:
DISPLAY=:1 firefox >/tmp/firefox.log 2>&1 &十五、APT 临时与永久使用 Clash
推荐平时使用临时代理。
例如:
apt \
-o Acquire::http::Proxy="http://127.0.0.1:7897" \
-o Acquire::https::Proxy="http://127.0.0.1:7897" \
install 包名如果确定 Clash 会长期运行,也可以:
cat > /etc/apt/apt.conf.d/99clash-proxy <<'EOF'
Acquire::http::Proxy "http://127.0.0.1:7897";
Acquire::https::Proxy "http://127.0.0.1:7897";
EOF以后:
apt update默认走 Clash。
但如果 Clash 关闭:
APT 会连接失败。恢复:
rm -f /etc/apt/apt.conf.d/99clash-proxy所以本文更推荐:
APT 临时指定代理十六、安装 cloudflared —— 使用 GitHub 加速
当前 cloudflared GitHub Release 提供 Linux ARM64 DEB。
你已经实际测试:
GitHub直连:
约 69 KB/s
gh-proxy:
约 5.96 MB/s因此直接采用 GitHub 加速。
1. 下载 cloudflared
cd /root/Desktop推荐固定当前版本 2026.9.1:
wget --no-proxy \
-O cloudflared-arm64.deb \
"https://gh-proxy.com/https://github.com/cloudflare/cloudflared/releases/download/2026.9.1/cloudflared-linux-arm64.deb"2. 校验 SHA256
因为 gh-proxy.com 是第三方代理,不是 Cloudflare/GitHub 官方域名,所以下载后必须校验。
Cloudflare 官方 2026.9.1 ARM64 DEB 的 SHA256 为:
ee3fe95ac038c70dc0bbe4823667a2794422fa30c6068520537dc2fe3d7ce282执行:
echo \
"ee3fe95ac038c70dc0bbe4823667a2794422fa30c6068520537dc2fe3d7ce282 cloudflared-arm64.deb" \
| sha256sum -c -必须:
cloudflared-arm64.deb: OK如果不是:
OK不要安装,直接删除:
rm -f cloudflared-arm64.deb3. 检查架构
dpkg-deb -f cloudflared-arm64.deb Architecture应该:
arm644. 安装
apt install -y ./cloudflared-arm64.deb验证:
cloudflared --version十七、配置 Cloudflare Tunnel
进入 Cloudflare One:
Networks
→ Connectors
→ Cloudflare Tunnel
→ Create Tunnel名字:
agblr-desktopCloudflare 后台会生成类似:
cloudflared service install eyJxxxxxxxxxxxxxxxx直接复制到设备执行。
注意:
不要把 Tunnel Token 发到聊天、论坛或 GitHub。检查服务
systemctl status cloudflared --no-pagersystemctl is-enabled cloudflared应为:
active (running)
enabled十八、Cloudflare 映射 noVNC
Tunnel 中创建 Published Application:
Hostname:
agblr.funService:
HTTPURL:
http://127.0.0.1:6081最终:
https://agblr.fun
│
▼
Cloudflare
│
▼
Cloudflare Tunnel
│
▼
127.0.0.1:6081
│
▼
noVNC
│
▼
TigerVNC :1十九、检查所有服务
systemctl is-enabled tigervncserver@:1.service
systemctl is-enabled novnc.service
systemctl is-enabled xrdp.service
systemctl is-enabled cloudflared 2>/dev/null检查端口
ss -lntp | grep -E '3389|5901|6081|7897'正常:
3389 xrdp
127.0.0.1:5901 Xtigervnc
0.0.0.0:6081 websockify
127.0.0.1:7897 verge-mihomo二十、检查唯一 MATE 桌面
for PID in $(pgrep mate-session); do
DISP=$(tr '\0' '\n' < /proc/$PID/environ 2>/dev/null |
sed -n 's/^DISPLAY=//p' | head -1)
echo "PID=$PID DISPLAY=$DISP"
done只应存在:
DISPLAY=:1二十一、重启最终验证
reboot启动后:
pgrep -a mate-session
pgrep -a mate-panel
pgrep -a caja
pgrep -a fcitx5检查:
ss -lntp | grep -E '3389|5901|6081'然后分别测试:
局域网浏览器:
http://设备IP:6081/
Windows RDP:
设备IP:3389
公网:
https://agblr.fun/三个入口都必须进入:
DISPLAY=:1同一个 MATE 桌面。
二十二、重要下载原则
这台机器当前网络建议:
Ubuntu普通依赖
↓
USTC
GitHub大文件
↓
gh-proxy.com
↓
下载后尽量校验哈希
Firefox
↓
Mozilla官方APT
↓
明确指定 Clash 127.0.0.1:7897
Armbian普通小包
↓
mirror.twds.com.tw不要再让大 Firefox 包直接从:
mirror.twds.com.tw/armbian-apt下载,因为实际已经测到只有:
17.5 KB/s二十三、配置备份
全部正常以后:
mkdir -p /root/GEA-backupcp -a /root/.vnc /root/GEA-backup/
cp -a /root/.config/fcitx5 /root/GEA-backup/
cp -a /usr/local/bin/mate-vnc-session.sh /root/GEA-backup/
cp -a /etc/xrdp/xrdp.ini /root/GEA-backup/
cp -a /etc/systemd/system/novnc.service /root/GEA-backup/
cp -a /etc/apt/sources.list /root/GEA-backup/
cp -a /etc/apt/sources.list.d/armbian.list /root/GEA-backup/如果 Mozilla 已配置:
cp -a /etc/apt/sources.list.d/mozilla.list \
/root/GEA-backup/ 2>/dev/null || true
cp -a /etc/apt/preferences.d/mozilla \
/root/GEA-backup/ 2>/dev/null || true打包:
tar czf /root/GEA-FULL-CONFIG-BACKUP.tar.gz \
-C /root GEA-backup务必再复制到其他电脑/NAS保存。
评论