The main bottleneck for SSH X11 forwarding is transferring rendering bitmap data. For example, if your app is sized to full HD, i.e., 1920 pixels (width) by 1080 pixels (height) and using 32-bit color format (ARGB; 4 bytes), X11 forwarding needs to transfer about 8 Mbytes (1920 x 1080 x 4 bytes) for fully updating or displaying your remote X-Window GUI app on your local computer. X11 will try to update only the part where changes happened, but it is still a lot of bytes to transfer over network especially when your network is slow.
SSH supports compression and it certainly improves the responsiveness of X11 forwarding over slow network. But it treats the data stream as simple raw bytes; it does not specifically target rendering bitmap data with better compression methods such as JPEG.
SSH Compression Disadvantages
-
Requires more CPU processing
Effective for slow networks (e.g., under 20 ~ 50 Mbps), but counterproductive on high-speed networks (e.g., local LAN where 1 Gbps is common). For high-speed networks, SSH can transfer raw data faster than your CPU can compress and decompress them; enabling the compression only adds unnecessary delays.
-
Adds packet delays
Your server needs to compress the data before it is wrapped in SSH encrypted packet. Hence, along with the increased CPU usage, your server also needs to additionally manage memories before your compressed data is sent out.
-
No image optimization
The largest part of X11 data stream is rendering bitmap data. But the compression method in SSH does not distinguish such data and treats the entire stream as simple raw bytes. There are plenty of better compression methods for images such as JPEG, but you cannot utilize any of them in SSH X11 forwarding.
In this post, we will show you a different way of running X-Window GUI apps over SSH. Instead of using the compression option in SSH, we will make use of NX command-line tools that utilize JPEG/PNG image compression for remotely running X-Window GUI apps or a desktop environment.
Although you can use the method outlined in this post for any server-and-client configuration, we will focus on running X-Window GUI apps on a Unix-like server (e.g., Ubuntu) and forwarding them to a Windows computer with X410.
| Pros | Cons |
|
Known Issues
|
Required Tools
We will use the following tools for incorporating JPEG/PNG image compression in SSH X11 forwarding. Please note that we will not use the X11 forwarding feature in SSH; we will instead use the regular SSH local port forwarding and let NX tools manage X11 sessions.
| Remote Unix-like Server | Local Windows |
nxproxy nxagent nxdialog Those NX tools are originally released in 2003 and now maintained by ArcticaProject. There are fully packaged and integrated products based on those NX tools such as X2Go, but we will show a minimal setup that only utilizes those three command-line executables along with SSH and X410. nxproxy manages the connections and compression. nxagent connects to nxproxy and provides a virtual or nested X-Window environment for your X-Windows GUI apps or desktop; it tries to minimize X11 round-trip events and notify nxproxy when the selected image compression method should be applied. nxproxy can be used without nxagent, but it will compress the traffic as raw data without specifically targeting rendering bitmap; it will lose major performance benefits. nxdialog is used by nxagent for displaying messages and enquiries. Your Unix-like server should already have those NX tools in their ready-to-install software library. For example, if you are using Ubuntu or Debian, you can simply execute the following command. sudo apt install nxproxy nxagent nxdialog |
nxproxy.exe ssh.exe (Windows built-in SSH client) X410 As of this writing, we were not able to find an installer or package that only includes nxproxy.exe for Windows. You need to install X2Go client for Windows and use nxproxy.exe from its installed folder or manually extract nxproxy.exe directly from X2Go installer using tools like 7-Zip.
Please note that nxproxy.exe requires the following additional DLL files in order to properly run in Windows. cyggcc_s-1.dll cygjpeg-8.dll cygpng16-16.dll cygstdc++-6.dll cygwin1.dll cygXcomp.dll cygz.dll libgcc_s_dw2-1.dll libstdc++-6.dll libwinpthread-1.dll msvcr120.dll UPDATE One of our developers created a Github repository for building and packaging nxproxy.exe for Window (x64 only); it is directly built from the original source tree and has a different set of DLLs than the listed above: https://github.com/x410dev/win-nxproxy |
Workflow
We will first use two Windows Terminals and show how nxproxy and nxagent should be started. We will then try to combine the steps into one Windows batch file.
| Windows Command Prompt #1
Remote Server Prompt
|
Windows Command Prompt #2
Local Windows Command Prompt
|
|||||||||||||
| 1 |
Connect to your server using Windows built-in SSH client with its regular local port forwarding; this port forwarding is used for connecting the two nxproxy running on your server and Windows. ssh.exe -L 20000:localhost:4008 <your-user-id>@<server-address> Command-line Arguments
Once you have a server command prompt, execute nxproxy in client mode in background: nxproxy -C :8 link=adsl,pack=16m-jpeg-0 & Command-line Arguments
|
|||||||||||||
| 2 |
set NX_HOME=%USERPROFILE% You need to set this variable as nxproxy must be able to create various files for its operation. nxproxy creates a subfolder '.nx' under this folder. If you do not want to create a subfolder, you can instead use nxproxy.exe -S localhost:16000
If SSH port forwarding is correctly configured, you should be able to see a session started message on both terminals.
|
|||||||||||||
| 3 |
Start nxagent; nxagent is actually a nested X-Window server where your apps or desktop environment is running on. nxagent -R -display nx/:8 :9 & Command-line Arguments
START YOUR LINUX GUI APP!Execute the following command to let X-Window GUI apps know where they can find an X-Window display server. export DISPLAY=:9 Now you can run your X-Window GUI apps and use them on your local Windows computer. google-chrome
If you take a screenshot of your GUI app on Windows and magnify it in an image editor, you should be able to notice the artifacts of JPEG image compression.
|
Windows Batch Script Version 1
The following shows a simple Windows batch script that incorporates the steps shown above. However, unlike the steps shown above where you can control the start timing of nxproxy and nxagent, this script simply starts nxproxy.exe and then executes nxproxy and nxagent from the server. Hence nxproxy.exe might fail to establish a connection if the SSH tunnel or nxproxy on your server is not ready in time. The next version 2 addresses this timing problem by using a Bash script on your server.
Please create the Windows batch script files in the same folder where nxproxy.exe exists. If you want to create them in a different folder, you should change the script to include the full path for nxproxy.exe, or update your Windows PATH environment variable and make nxproxy.exe executable from any folder without using its full path.
Bash Script for Starting nxproxy/nxagent
The following Bash script simplifies and improves setting up a nxproxy/nxagent session. After creating the Bash script file, it must be made executable using chmod command. For example, executing chmod u+x start_nxproxy.sh makes the script executable for only the user who owns it.
nxagent Command-line Arguments (Line #172)
| -ac |
|
Disables host-based access control; enables access by any host and permits any host to modify the access control list. |
| -keystrokefile |
|
nxagent has its own keyboard shortcuts for changing its states or attributes. For example, in its default settings,
If you somehow end up triggering a shortcut and cannot disable it, do not panic! First, check if the window for nxagent is selected in Windows Taskbar (clicking the nxagent window may not be enough to change the selection). If not selected, use Windows keyboard shortcut, i.e., |
Testing Bash Script
| Windows Command Prompt #1
Remote Server Prompt
|
Windows Command Prompt #2
Local Windows Command Prompt
|
|
| 1 |
Connect to your server using Windows built-in SSH client with its regular local port forwarding; this port forwarding is used for connecting the two nxproxy running on your server and Windows. ssh.exe -L 20000:localhost:4008 <your-user-id>@<server-address> Once you have a server command prompt, execute the script with the following arguments: start_nxproxy.sh :x11_display_number nxproxy_options nxagent_options start_app For example, executing the following command combines the Step 1 and 3 of the workflow shown above: start_nxproxy.sh :9 link=adsl,pack=16m-jpeg-0 -R google-chrome When If you want to start additional X11 Window apps, you can start a terminal emulator like export DISPLAY=:9 |
|
| 2 |
Start nxproxy.exe just like in the steps shown above. set NX_HOME=%USERPROFILE% nxproxy.exe -S localhost:16000 |
Windows Batch Script Version 2
The following Windows Batch script uses start_nxproxy.sh shown above and improves starting a nxproxy/nxagent session from Windows computer. Please note that this batch script assumes start_nxproxy.sh is in ~/bin folder on your server.
Running a Desktop Environment
Set X410 to 'Windowed Apps' mode
nxagent creates its own window for your desktop environment, hence you should not use the 'Floating Desktop' mode in X410.
Start nxagent with
-DoptionYou should also use '-geometry' option to set the initial window size; without this option, nxagent tries to use the full screen size of your Windows desktop.
Start a window manager
For the desktop mode in nxagent, you need to start your own window manager. If you have installed a desktop environment on your server (ex. Xfce), you just need to launch its startup script (ex.
startxfce4) and you do not need to worry about window manager or taskbar. But if you are just using a window manager (ex. openbox) in order to save server resources such as memory and CPU usage, please be aware that window managers for X-Window commonly do not include a taskbar where minimized apps are displayed and can be restored. Please check your window manager and make sure how minimized apps are handled. For example, when you minimize an app while using openbox, it disappears. But you can easily restore it by using the middle-click popup menu in openbox; you can of course install and run a separate taskbar such as tint2.The following command shows an example of starting a desktop with openbox as its window manager using the previous Bash script version 2.
start_nxproxy.sh :9 "link=adsl,pack=16m-jpeg-0" "-D -geometry 1024x768 -name 'My Window Title'" openbox