Tips - X11 in an Embedded System - noVNC
noVNC is a VNC Client tool to connect to VNC server via Web Browser. And it can uses to connect on an graphic Embedded System.
Umberto©
- Features
- Browser Requirements
- Server Requirements
- Install some required packages
- Create a dedicated
unix
user - Create
noVNC
password - Create
novnc.pem
certificate - X11 auto login
- Start Websockify to proxy [localhost:9000] on port [6080]
- Creating
x11vnc
system service - Proxying with nginx
- Proxying with lighttpd
Features
- Supports all modern browsers including mobile (
iOS
,Android
) - Supported
VNC
encodings - Supports scaling, clipping and resizing the desktop
- Local cursor rendering
- Clipboard
copy
/paste
Browser Requirements
noVNC
requires a browser with HTML5
support, this means it works on all major browsers. noVNC
uses many modern web technologies so a formal requirement list is not available. However these are the minimum versions we are currently aware of: Chrome 49
, Firefox 44
, Safari 11
, Opera 36
, IE 11
, Edge 12
.
Server Requirements
noVNC
follows the standard VNC
protocol, but unlike other VNC
clients it does require WebSockets support. Many servers include support (e.g. x11vnc
/ libvncserver
, QEMU
, and MobileVNC
), but for the others you need to use a WebSockets to TCP socket proxy.
Install some required packages
Update and upgrade your OS
sudo apt update ; sudo apt upgrade
Install X11
required packages
sudo apt install xserver-xorg-video-qxl xinit slim jwm
Install VNC
required packages
sudo apt install x11vnc novnc
xserver-xorg-video-qxl
: This package provides the driver for QXL video device, i.e. if Linux is running inside a RedHat Enterprise Virtualization (RHEV) environment, or other SPICE-compatibleKVM/Qemu
emulator.xinit
:xinit
andstartx
are programs which facilitate starting an X server, and loading a base X session.slim
:slim
aims to be light, simple and independent from the various desktop environments.jwm
: very small lightweight pure X11 window manager with tray and menus. Low resource Window manager ideal for older PCs. It uses a minimum of external libraries, thus very little memory, includes virtual screens, menubar and root-menu popup.x11vnc
: x11vnc allows one to view remotely and interact with real X displays with any VNC viewer. It has built-in SSL encryption and authentication, UNIX account and password support, server-side scaling, single port HTTPS and VNC.noVNC
: noVNC is a HTML5 VNC (WebSockets, Canvas) with encryption (wss://) support client that runs well in any modern browser including mobile browsers (iOS and Android).
Create a dedicated unix
user
sudo useradd <noVNC_user>
With <noVNC_user>
user dedicated for login to noVNC
Create noVNC
password
Login as a user <noVNC_user>
who runs vnc
. Create a password to connect using vnc viewer from the client system.
x11vnc -storepasswd
Enter VNC password: *********
Verify password: *********
Write password to /home/<noVNC_user>/.vnc/passwd? [y]/n y
Password written to: /home/<noVNC_user>/.vnc/passwd
Create novnc.pem
certificate
openssl req -x509 -nodes -newkey rsa:2048 -keyout novnc.pem -out novnc.pem -days 365
X11 auto login
Edit /etc/slim.conf
sudo vi /etc/slim.conf
In the file, uncomment the line starting with #default_user
(remove the hash) and add the NAME (<noVNC_user>
) of the default user
And put yes
in auto_login
directive
Start Websockify to proxy [localhost:9000] on port [6080]
websockify -D --web=/usr/share/novnc/ --cert=/home/<noVNC_user>/novnc.pem 6080 localhost:9000
WebSocket server settings:
- Listen on :6080
- Flash security policy server
- Web server. Web root: /usr/share/novnc
- SSL/TLS support
- Backgrounding (daemon)
The script os_novnc_websockify.sh
check status and start the web socker if is down.
You can chech it every 15th minute in the crontable sush as :
###############
## novnc ##
###############
*/15 * * * * /<path>/os_novnc_websockify.sh >/dev/null 2>&1
Creating x11vnc
system service
First, it might be a good idea to copy the password file under /etc/
sudo mv ~/.vnc/passwd /etc/x11vnc.passwd
This also ensures the ownership to root and his rw
access, as confirmed by:
sudo ls -la /etc/x11vnc.passwd
-rw------- 1 root root 8 Feb 15 17:02 /etc/x11vnc.passwd
Second, we have to create the service file ourselves:
sudo vi /etc/systemd/system/x11vnc.service
[Unit]
Description=Start x11vnc at startup.
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -auth /var/run/slim.auth -forever -loop -noxdamage -repeat -rfbauth /etc/x11vnc.passwd -rfbport 9000 -shared
[Install]
WantedBy=multi-user.target
Disclaimer: The man page is quite lengthy, and maybe I’ve made some serious, e.g. security mistake. Use on your own risk.
sudo systemctl enable x11vnc.service
sudo systemctl daemon-reload
Note : For
Raspberry pi
:
- In
/etc/systemd/system/x11vnc.service
file change-auth /var/run/slim.auth
by-auth /var/run/lightdm/root/:0
- Without a monitor attached you must setting
hdmi_force_hotplug=1
in/boot/config.txt
. So it always thinks that an HDMI monitor is attached.
and you may simply reboot
the server.
Proxying with nginx
Configure nginx
- Step 1 : Upstream IP + port to the websocketproxy server
Edit your nginx subdomain (or domain) config file in /etc/nginx/sites-enable/
folder. Thereafter, example.com
represents the (sub)domain where noVNC
will live at.
Edit /etc/nginx/sites-enable/example.com
and add the line below at the beginning.
upstream vnc_proxy {
server 127.0.0.1:6080;
}
- Step 2 : A path to /websockify to proxy the websocket connection
server {
listen 80; # consider using 443, see below
server_name example.com;
<other_config>
location /websockify {
proxy_http_version 1.1;
proxy_pass http://vnc_proxy/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# VNC connection timeout
proxy_read_timeout 61s;
# Disable cache
proxy_buffering off;
}
As seen above, it is recommended to set a proxy_read_timeout greater than 60 seconds which is the default value. If not set you can end up in a race-condition which could cause a disconnection after inactivity longer than a minute. To avoid unnecessary caching of the VNC stream proxy_buffering
should be set to off
.
- Step 3 : A path to your base URL, where you want it to show up
<other_config>
location /vncws {
index vnc.html;
alias </path/to/noVNC/>;
try_files $uri $uri/ /vnc.html;
}
<other_config>
With this config, you can point your browser to https://example.com/vncws/vnc.html
to use noVNC
.
- Step 4 : Test new
nginx
configuration et restart
# Test configuration file for syntax errors by typing
sudo nginx -t
# reload Nginx to make the necessary changes
sudo systemctl reload nginx
Proxying with lighttpd
Configure lighttpd
- Step 1 : websocket tunnel to VNC server via noVNC client
If noVNC
files are installed in /usr/share/novnc
, and x11vnc
is running as VNC server with x11vnc
then lighttpd
mod_wstunnel
can be configured with this novnc.conf
file in /etc/lighttpd/conf-enabled/
directory:
# file: "/etc/lighttpd/conf-enabled/novnc.conf"
alias.url = ( "/x11/" => "/usr/share/novnc/" )
server.indexfiles = ("index.html")
server.modules += ( "mod_wstunnel" )
$HTTP["url"] =~ "^/websockify" {
wstunnel.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "9000" ) ) )
# (optional, but recommended settings with noVNC)
wstunnel.frame-type = "binary"
server.stream-request-body = 2
server.stream-response-body = 2
Please take proper precautions to limit access to the VNC server, possibly including requiring proper authentication and limiting access to certain source IPs.
- Step 2 : Test new lighttpd configuration et restart
# Test configuration file for syntax errors by typing
lighttpd -p -f /etc/lighttpd/lighttpd.conf
# reload Nginx to make the necessary changes
sudo systemctl reload lighttpd
With this config, you can point your browser to https://example.com/x11/vnc.html to use noVNC
.