本文介绍了一种在 Ubuntu 环境下搭建远程桌面服务的方法。

主要环境:

  • 操作系统环境:Ubuntu 24.04 LTS (GNOME 桌面系统)
  • VNC 服务端:TigerVNC
  • VNC 客户端:noVNC

其他环境和工具:

  • 1panel
  • openresty (nginx)
  • supervisor (or systemd)

安装和配置 VNC 服务端

  1. 安装 TigerVNC

在 sourceforge 上下载 TigerVNC 的程序包。

https://sourceforge.net/projects/tigervnc/files/stable/1.13.1/

下载完成后,解压到指定目录。

我这里放在了 /opt/ 目录下。

解压后的目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
wgxls@server:/opt$ tree tigervnc-1.13.0.x86_64/
tigervnc-1.13.0.x86_64/
├── etc
│ ├── pam.d
│ │ └── tigervnc
│ └── tigervnc
│ ├── vncserver-config-defaults
│ ├── vncserver-config-mandatory
│ └── vncserver.users
└── usr
├── bin
│ ├── vncconfig
│ ├── vncpasswd
│ ├── vncviewer
│ ├── x0vncserver
│ └── Xvnc
├── lib
│ └── systemd
│ └── system
│ └── vncserver@.service
├── lib64
│ ├── swrast_dri.so
│ └── xorg
│ └── protocol.txt
├── libexec
│ ├── vncserver
│ └── vncsession-start
├── sbin
│ └── vncsession
└── share
├── applications
│ └── vncviewer.desktop
├── doc
│ └── tigervnc
│ ├── HOWTO.md
│ ├── LICENCE.TXT
│ └── README.rst
├── icons
│ └── hicolor
│ ├── 128x128
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 16x16
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 22x22
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 24x24
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 32x32
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 48x48
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 64x64
│ │ └── apps
│ │ └── tigervnc.png
│ └── scalable
│ └── apps
│ └── tigervnc.svg
├── locale
│ ├── bg
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── cs
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── da
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── de
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── el
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── eo
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── es
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fi
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fur
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── he
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── hu
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── id
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── it
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ka
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ko
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── nl
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── pl
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── pt_BR
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ro
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ru
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sk
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sv
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── tr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── uk
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── vi
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── zh_CN
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ └── zh_TW
│ └── LC_MESSAGES
│ └── tigervnc.mo
├── man
│ ├── man1
│ │ ├── vncconfig.1
│ │ ├── vncpasswd.1
│ │ ├── vncviewer.1
│ │ ├── x0vncserver.1
│ │ └── Xvnc.1
│ └── man8
│ ├── vncserver.8
│ └── vncsession.8
└── metainfo
└── org.tigervnc.vncviewer.metainfo.xml

98 directories, 64 files
  1. 配置 x0vncserver

首先给 VNC 服务生成密码。

1
2
3
4
# 切换到 tigerVNC 的 bin 目录
cd /opt/tigervnc-1.13.0.x86_64/usr/bin
# 执行 vncpasswd 命令
./vncpasswd

这里将会提示输入两次密码,这个密码用于远程登录的认证服务。

然后查看当前的显示器序号。

1
printenv DISPLAY

这里显示的是 :0,表示当前显示器的序号是 0。

然后启动 x0vncserver 服务。

我这里使用的 x0vncserver,可以直接连接到当前桌面环境。

在效果上就和 Windows 的远程桌面服务,向日葵等工具类似。

如果使用 Xvnc,会新开一个桌面环境,远程访问的效果和本地不同。

1
2
3
4
# 切换到 tigerVNC 的 bin 目录
cd /opt/tigervnc-1.13.0.x86_64/usr/bin
# 启动 x0vncserver 服务
./x0vncserver -display :0 -passwordfile ~/.vnc/passwd -NeverShared

简单解释一下这三个参数:

  • -display :0:指定显示器序号。
  • -passwordfile ~/.vnc/passwd:指定密码文件。
  • -NeverShared:表示不共享,只允许一个用户连接。

全部支持的参数信息可以查看帮助文档

⚠️ TigerVNC 的 vncpasswd 命令进行了更新,现在 passwd 文件会生成在 $HOME/.config/tigervnc/passwd,注意更新相关命令。
参考:https://tigervnc.org/doc/vncpasswd.html

  1. 配置桌面环境

根据我的实验,如果使用 Wayland 桌面环境,x0vncserver 连上后就只能看到一个黑屏。
所以首先关闭 Wayland。

同时,为了能让电脑在一开机的时候就能够自动启动 x0vncserver 服务,我们需要开机桌面的自动登录,为了创建一个 X 会话。

1
2
3
4
5
6
7
8
# 编辑 /etc/gdm3/custom.conf 文件
sudo vim /etc/gdm3/custom.conf

# 找到 [daemon] 部分,添加如下内容
WaylandEnable=false

AutomaticLoginEnable=true
AutomaticLogin=<your_username>

修改完之后,重启电脑。

安装和配置 noVNC

  1. 下载 noVNC

我这里在 /opt/ 目录下存放 noVNC 的程序包。

1
2
cd /opt
git clone https://github.com/novnc/noVNC.git
  1. 配置 noVNC
1
2
cd /opt/noVNC
./utils/novnc_proxy --vnc localhost:5900

第一次执行这个命令的时候,会自动下载 websockify。

至此,核心部分的配置已经完成。

配置守护进程和反向代理

因为我的服务器上安装了 1panel,1panel 提供了图形界面去管理 supervisor 守护进程。

所以我这里使用 supervisor 来管理 noVNC 和 x0vncserver 服务。

登录 1panel 后点击 工具箱 -> 守护进程

如果服务器没有安装 supervisor,可以按照提示进行安装。

安装完成 supervisor 后, 在 1panel 的 守护进程 页面,点击初始化,然后点击创建守护进程。

首先添加 x0vncserver 的守护进程, 下图是我的例子,可以根据自己的实际情况进行配置。

启动命令我填写的是:/opt/tigervnc-1.13.0.x86_64/usr/bin/x0vncserver -display :0 -passwordfile /home/wgxls/.vnc/passwd -NeverShared

然后添加 noVNC 的守护进程,如图所示:

最后,添加网站并配置反向代理,这一步是常规操作,这里不再赘述。

我这里的反向代理配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
location ^~ / {
proxy_pass http://127.0.0.1:6080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
add_header X-Cache $upstream_cache_status;
add_header Strict-Transport-Security "max-age=31536000";
}

如果你的网站域名是 example.com,那么你可以通过 https://example.com/vnc.html 访问 noVNC。

设置 Dummy 显示器

如果你需要在没有物理显示器的服务器上使用 x0vncserver,可以设置一个 Dummy 显示器。

  1. 安装 Dummy 驱动
1
sudo apt install xserver-xorg-video-dummy
  1. 创建配置文件
1
sudo vim /etc/X11/xorg.conf.d/10-dummy.conf

在文件中添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Section "Device"
Identifier "DummyDevice"
Driver "dummy"
VideoRam 1024000
EndSection

Section "Screen"
Identifier "DummyScreen"
Device "DummyDevice"
Monitor "DummyMonitor"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "2560x1440_60.0"
EndSubSection
EndSection

Section "Monitor"
Identifier "DummyMonitor"
HorizSync 30-200
VertRefresh 50-1000
Modeline "2560x1440_60.00" 312.25 2560 2752 3024 3488 1440 1443 1448 1493 -hsync +vsync
EndSection
  1. 重启 X 服务器或重启服务器
1
sudo systemctl restart gdm3

然后就可以远程访问了。

This article describes a method to set up a remote desktop service in an Ubuntu environment.

Main environment:

  • OS: Ubuntu 24.04 LTS (GNOME desktop)
  • VNC server: TigerVNC
  • VNC client: noVNC

Other environment and tools:

  • 1panel
  • openresty (nginx)
  • supervisor (or systemd)

Install & configure the VNC server

  1. Install TigerVNC

Download the TigerVNC package from sourceforge.

https://sourceforge.net/projects/tigervnc/files/stable/1.13.1/

After downloading, extract it to a directory of your choice.

I put mine in /opt/.

The extracted directory structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
wgxls@server:/opt$ tree tigervnc-1.13.0.x86_64/
tigervnc-1.13.0.x86_64/
├── etc
│ ├── pam.d
│ │ └── tigervnc
│ └── tigervnc
│ ├── vncserver-config-defaults
│ ├── vncserver-config-mandatory
│ └── vncserver.users
└── usr
├── bin
│ ├── vncconfig
│ ├── vncpasswd
│ ├── vncviewer
│ ├── x0vncserver
│ └── Xvnc
├── lib
│ └── systemd
│ └── system
│ └── vncserver@.service
├── lib64
│ ├── swrast_dri.so
│ └── xorg
│ └── protocol.txt
├── libexec
│ ├── vncserver
│ └── vncsession-start
├── sbin
│ └── vncsession
└── share
├── applications
│ └── vncviewer.desktop
├── doc
│ └── tigervnc
│ ├── HOWTO.md
│ ├── LICENCE.TXT
│ └── README.rst
├── icons
│ └── hicolor
│ ├── 128x128
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 16x16
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 22x22
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 24x24
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 32x32
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 48x48
│ │ └── apps
│ │ └── tigervnc.png
│ ├── 64x64
│ │ └── apps
│ │ └── tigervnc.png
│ └── scalable
│ └── apps
│ └── tigervnc.svg
├── locale
│ ├── bg
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── cs
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── da
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── de
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── el
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── eo
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── es
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fi
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── fur
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── he
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── hu
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── id
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── it
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ka
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ko
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── nl
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── pl
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── pt_BR
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ro
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── ru
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sk
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── sv
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── tr
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── uk
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── vi
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ ├── zh_CN
│ │ └── LC_MESSAGES
│ │ └── tigervnc.mo
│ └── zh_TW
│ └── LC_MESSAGES
│ └── tigervnc.mo
├── man
│ ├── man1
│ │ ├── vncconfig.1
│ │ ├── vncpasswd.1
│ │ ├── vncviewer.1
│ │ ├── x0vncserver.1
│ │ └── Xvnc.1
│ └── man8
│ ├── vncserver.8
│ └── vncsession.8
└── metainfo
└── org.tigervnc.vncviewer.metainfo.xml

98 directories, 64 files
  1. Configure x0vncserver

First, generate a password for the VNC service.

1
2
3
4
# Switch to tigerVNC's bin directory
cd /opt/tigervnc-1.13.0.x86_64/usr/bin
# Run the vncpasswd command
./vncpasswd

It will prompt you to enter the password twice. This password is used for remote login authentication.

Then check the current display number.

1
printenv DISPLAY

This shows :0, meaning the current display number is 0.

Then start the x0vncserver service.

I use x0vncserver here, which connects directly to the current desktop environment.

In terms of effect, it’s similar to Windows Remote Desktop, Sunflower (Xiangrikui), and similar tools.

If you use Xvnc instead, it creates a brand new desktop environment, so the remote experience differs from the local one.

1
2
3
4
# Switch to tigerVNC's bin directory
cd /opt/tigervnc-1.13.0.x86_64/usr/bin
# Start the x0vncserver service
./x0vncserver -display :0 -passwordfile ~/.vnc/passwd -NeverShared

A quick explanation of these three parameters:

  • -display :0: specifies the display number.
  • -passwordfile ~/.vnc/passwd: specifies the password file.
  • -NeverShared: no sharing — only one user can connect at a time.

See the help docs for all supported parameters.

⚠️ TigerVNC’s vncpasswd command was updated; the passwd file is now generated in $HOME/.config/tigervnc/passwd. Update the relevant commands accordingly.
Reference: https://tigervnc.org/doc/vncpasswd.html

  1. Configure the desktop environment

From my experiments, if you use the Wayland desktop environment, x0vncserver only shows a black screen after connecting.
So first, disable Wayland.

Also, to have x0vncserver start automatically at boot, we need auto-login at the desktop level to create an X session.

1
2
3
4
5
6
7
8
# Edit the /etc/gdm3/custom.conf file
sudo vim /etc/gdm3/custom.conf

# Find the [daemon] section and add the following
WaylandEnable=false

AutomaticLoginEnable=true
AutomaticLogin=<your_username>

After the changes, reboot the computer.

Install & configure noVNC

  1. Download noVNC

I put the noVNC package in /opt/.

1
2
cd /opt
git clone https://github.com/novnc/noVNC.git
  1. Configure noVNC
1
2
cd /opt/noVNC
./utils/novnc_proxy --vnc localhost:5900

The first time you run this command, websockify will be downloaded automatically.

At this point, the core configuration is done.

Configure the daemon and reverse proxy

Since my server has 1panel installed, and 1panel provides a GUI to manage supervisor daemons,

I use supervisor to manage the noVNC and x0vncserver services.

After logging into 1panel, click Toolbox -> Daemons.

If supervisor isn’t installed on the server, follow the prompts to install it.

Once supervisor is installed, on the 1panel Daemons page, click initialize, then click create daemon.

First add the x0vncserver daemon. The image below is my example; configure it according to your actual situation.

The start command I filled in: /opt/tigervnc-1.13.0.x86_64/usr/bin/x0vncserver -display :0 -passwordfile /home/wgxls/.vnc/passwd -NeverShared

Then add the noVNC daemon, as shown:

Finally, add a website and configure the reverse proxy — this is a routine operation, so I won’t go into detail here.

My reverse proxy configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
location ^~ / {
proxy_pass http://127.0.0.1:6080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
add_header X-Cache $upstream_cache_status;
add_header Strict-Transport-Security "max-age=31536000";
}

If your site domain is example.com, you can access noVNC via https://example.com/vnc.html.

Set up a Dummy display

If you need to use x0vncserver on a server without a physical monitor, you can set up a Dummy display.

  1. Install the Dummy driver
1
sudo apt install xserver-xorg-video-dummy
  1. Create the config file
1
sudo vim /etc/X11/xorg.conf.d/10-dummy.conf

Add the following to the file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Section "Device"
Identifier "DummyDevice"
Driver "dummy"
VideoRam 1024000
EndSection

Section "Screen"
Identifier "DummyScreen"
Device "DummyDevice"
Monitor "DummyMonitor"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "2560x1440_60.0"
EndSubSection
EndSection

Section "Monitor"
Identifier "DummyMonitor"
HorizSync 30-200
VertRefresh 50-1000
Modeline "2560x1440_60.00" 312.25 2560 2752 3024 3488 1440 1443 1448 1493 -hsync +vsync
EndSection
  1. Restart the X server or reboot the server
1
sudo systemctl restart gdm3

And then you can access it remotely.