Setting up a small footprint X Windows/VNC GUI on AWS Red Hat Enterprise Linux 8, Amazon Linux 2 or Ubuntu Server – Concluded

Introduction

This document concludes the research I previously did in setting up the necessarily packages for a graphical connection (VNC) to an AWS EC2 Instance using Linux. The three versions I worked with, Red Hat Enterprise Linux 8, Amazon Linux 2 (a derivative of RHEL), and Ubuntu Server 18.04/16.04, were all able to install XFCE4, a small-footprint X Window desktop. Red Hat and Amazon Linux were able to add a compatible Fedora repository in order to install the required packages, and Ubuntu Server, once the initial setup was run, as well.

I stopped with SUSE Linux Enterprise Server, as I wasn’t able to find a repository for the required packages and other dependencies. Amazon Linux AMI was also not able to install the required packages and dependencies, so I left that one alone as well.

User Data with EC2

The simplest way is to use the “User Data” feature of AWS EC2 instance creation, and to load the file there. This allows a script to be run by root after the EC2 instance has been created.

#!/bin/bash
VER=00.01.00.00
SETUPSCRIPT=vncsetup-$VER.sh
curl -o /tmp/$SETUPSCRIPT http://twoconcertinas.com/$SETUPSCRIPT
chmod +x /tmp/$SETUPSCRIPT
/tmp/$SETUPSCRIPT

This downloads the script, http://twoconcertinas.com/vncsetup-00.01.00.00.sh from my web server, makes it executable, and then runs it as root. The “user data” feature is limited to 16k maximum file size, so this will allow it to import and execute any size script.

VNCSetup Script


This script itself is as follows:
vncsetup-00.01.00.00.sh

#!/bin/bash
#Install and setup files for VNC

#Set this so that \n in echo strings are parsed correctly.
shopt -s xpg_echo

REDHAT_RELEASE="/etc/redhat-release"
AMAZON_RELEASE="/etc/system-release"

#Check for UBUNTU 
UNIX_TYPE=`lsb_release -d 2>/dev/null | awk -F"\t" '{print $2}' | awk -F " " '{print $1}' 2>/dev/null`
#Check for Red Hat type
if [ -f $REDHAT_RELEASE ] 
 then
    grep "Red Hat Enterprise Linux release 8" $REDHAT_RELEASE
    if [ "$?" == "0" ] 
    then 
        UNIX_TYPE="RHEL 8"
    fi
    grep "Red Hat Enterprise Linux Server release 7" $REDHAT_RELEASE
    if [ "$?" == "0" ] 
    then 
        UNIX_TYPE="RHEL 7"
    fi
fi
if [ -f $AMAZON_RELEASE ]
 then
    grep "Amazon Linux release 2" $AMAZON_RELEASE
    if [ "$?" == "0" ] 
    then 
        UNIX_TYPE="Amazon Linux 2"
    fi
fi
echo "Setup for UNIX type: $UNIX_TYPE"

#The VNC Startup file
VNCSERVER="/usr/bin/vncserver"
BACKUP_VNCSERVER="/tmp/vncserver"

PUBLICIP_SCRIPT=/usr/bin/publicip
VNCSTART=/usr/bin/vncstart
VNCEND=/usr/bin/vncend

PUBLICIP=`curl http://169.254.169.254/latest/meta-data/public-ipv4 2>/dev/null`
PUBLICIP_TEXT="PUBLICIP=\`curl http://169.254.169.254/latest/meta-data/public-ipv4 2>/dev/null\`\necho \"Public IP address=\$PUBLICIP\"\necho \"For VNC use: \$PUBLICIP:1\""  


REDHAT_REPO8="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
REDHAT_REPO7="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
REDHAT_UPDATE="sudo yum -y update"
REDHAT_INSTALL="sudo yum install -y"
REDHAT_PACKAGES1="tigervnc-server tigervnc xterm gnome-calculator dconf-editor gvim vim metacity nautilus"
REDHAT_PACKAGES2="exo libwnck3 xfce-polkit xfce4-session xfce4-terminal xfce4-settings xfwm4 xfdesktop xfce4-screenshooter xfce4-notifyd ristretto mousepad desktop-backgrounds desktop-backgrounds-gnome orage links xfce4-*-plugin xfce4-appfinder geany xfce4-dict"

UBUNTU_UPDATE="sudo apt-get update"
UBUNTU_INSTALL="sudo apt-get -y install"
UBUNTU_PACKAGES1="xfce4 xfce4-goodies tightvncserver"
UBUNTU_PACKAGES2="gnome-icon-theme tango-icon-theme links2 geany" 

if [ "$UNIX_TYPE" == "Ubuntu" ]
then
  $UBUNTU_UPDATE
  $UBUNTU_INSTALL $UBUNTU_PACKAGES1
  $UBUNTU_INSTALL $UBUNTU_PACKAGES2
  #The following fixes a problem with xfce4 on Ubuntu where the icons show 
  #as broken, the themes and colors don't update. 
  #Comment XKL_XMODMAP_DISABLE out in vncserver for when xstartup is created
  if [ -e $VNCSERVER ] 
  then
    cp $VNCSERVER $BACKUP_VNCSERVER
    sed 's/export XKL_XMODMAP_DISABLE/#&/' $BACKUP_VNCSERVER > $VNCSERVER
  fi
else
  #Not Ubuntu - so RedHat or Amazon Linux
  if [ "$UNIX_TYPE" == "RHEL 8" ]
  then
    $REDHAT_INSTALL $REDHAT_REPO8
  elif [ "$UNIX_TYPE" == "RHEL 7" ] || [ "$UNIX_TYPE" == "Amazon Linux 2" ]
  then
    $REDHAT_INSTALL $REDHAT_REPO7
  else
    echo "Red Hat Type not provided."
  fi
  $REDHAT_UPDATE
  $REDHAT_INSTALL $REDHAT_PACKAGES1
  $REDHAT_INSTALL $REDHAT_PACKAGES2
  
  #Need to add XFCE to startup in xstartup or there will be no fun.
  HOME="/home/ec2-user"
  defaultXstartup=$HOME/.vnc/xstartup
  echo xstartup=$defaultXstartup
  if [ ! -f $defaultXstartup ]
  then
    mkdir -p $HOME/.vnc
    chmod 755 $HOME/.vnc
    echo "#!/bin/sh\nunset SESSION_MANAGER\nunset DBUS_SESSION_BUS_ADDRESS\n/etc/X11/xinit/xinitrc\nstartxfce4\n" > $defaultXstartup
    chmod +x $defaultXstartup
    chown -R ec2-user:ec2-user $HOME/.vnc 
  else
    grep -q "startxfce4" $defaultXstartup
    if [ "$?" == 1 ]
    then 
      echo "startxfce4\n" >> $defaultXstartup
    fi
  fi
fi

##############################################################################
#Let's create a script, /usr/bin/publicip to display the external IP address
echo "#!/bin/bash" > $PUBLICIP_SCRIPT
echo $PUBLICIP_TEXT >> $PUBLICIP_SCRIPT
chmod +x $PUBLICIP_SCRIPT

#Create /usr/bin/vncstart script to start the vncserver on display :1
echo "#!/bin/bash" > $VNCSTART
echo "vncserver -geometry 1920x1080 :1" >> $VNCSTART
echo $PUBLICIP_TEXT >> $VNCSTART
chmod +x $VNCSTART

#Create /usr/bin/vncend script to stop the vncserver on display :1
echo "#!/bin/bash" > $VNCEND
echo "vncserver -kill :1" >> $VNCEND
chmod +x $VNCEND

echo "VNC Install Finished."

The script works on Red Hat Enterprise Server, Amazon Linux 2, and Ubuntu Server. It determines whether it’s on Ubuntu, or Red Hat/Amazon. After setting up some variables for packages, it starts by running the platform specific “update” command so that all packages and repositories are refreshed. This can take several minutes.

After installing the packages for Ubuntu, the script modifies /usr/bin/vncserver script. When vncserver is first run, it creates the ~/.vnc/xstartup script. This sets and exports the value “XKL_XMODMAP_DISABLE” in xstartup. If this is set to true, the icons and themes won’t display correctly when connecting with VNC. So we nip that in the bud by adding a comment character in front of the line that sets it when vncserver is executed and can’t find xstartup.

On Red Hat and Amazon Linux, the xstartup script is also created. It needs to have the startup for XFCE4 in xstartup, or the desktop won’t function properly on loading. So the script creates xstartup with that command set.

After the packages are installed, three scripts are created in /usr/bin: publicip, vncstart, and vncend. The script publicip is specific to AWS EC2 instances, in that the publicly visible IP address is displayed. This is the IP address used to connect VNC to.

The scripts vncstart and vncend are used to manually start and stop the VNC server (TigerVNC or TightVNC) and displays the IP address to connect to. For a single user Linux system, use the display number :1, which connects to port 5901 with VNC.

The first time vncstart is executed, the password for the VNC server is setup. Be sure and use an appropriately complex password as this can allow anyone to connect. A “view only” password can be used if you wanted to be able to share the desktop with someone else and not allow them access to the desktop.

There are ways to tunnel to VNC using SSH, as well as to automatically start VNC when the server boots. I’ve made the decision not to delve into either of these topics as plenty of material is available on the internet on how to do this.

Conclusion

This has been an interesting project for me. If you are a user that wants the memory heavy Gnome interface, or can create 2GB EC2 instances, then you might not need any of this. If you’re just looking for a quick, low memory footprint method that’ll allow a simple VNC connection, then this is for you. Either way, this can prove that Linux is not just a text based terminal connection but can include so much more.

Please drop me a line if there are any issues or questions that crop up. Packages may change, and I may need to change my scripts.

Links

One way to start the vncserver after the EC2 instance is started, read the following article at AWS.Amazon.com: https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/

Leave a Reply