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
unixuser - Create
noVNCpassword - Create
novnc.pemcertificate - X11 auto login
- Start Websockify to proxy [localhost:9000] on port [6080]
- Creating
x11vncsystem service - Proxying with nginx
- Proxying with lighttpd
Features
- Supports all modern browsers including mobile (
iOS,Android) - Supported
VNCencodings - 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/Qemuemulator.xinit:xinitandstartxare programs which facilitate starting an X server, and loading a base X session.slim:slimaims 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.servicefile change-auth /var/run/slim.authby-auth /var/run/lightdm/root/:0- Without a monitor attached you must setting
hdmi_force_hotplug=1in/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
nginxconfiguration et restart
# Test configuration file for syntax errors by typing
sudo nginx -t
# reload Nginx to make the necessary changes
sudo systemctl reload nginx

noVNC sceenshot
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.