Raspberry Pi VNC Mirror – simplified

This post describes to setup a VNC Mirror on your Raspberry Pi. You can see any desktop of any machine running VNC on your Raspberry Pi’s connected screen. You may come from these posts: Hardening the Raspberry Pi VNC Mirror and Raspberry Pi – VNC Mirror (Repeater) – Make any computer public anywhere which can be a little bit confusing especially when trying to get both into one project. Here in a few easy and understandable steps

Preparation

Download the latest Raspbian Image from the Raspberry Pi site. Unpack it and write the IMG file with Win32DiskImager (on Windows) or dd (on Linux or MAC) on your SD Card (make sure you have at least 4GB).

First Start

When you first start your Raspberry Pi with a monitor it runs raspi-config. If it doesn’t you can rerun it with

sudo raspi-config

In this menu select

Enable Boot to Desktop/Scratch

then

Desktop Log in as user 'pi'...

but say No to reboot, because we want to know the IP address of the raspberry and work via SSH later on. Type

ifconfig

to get your IP address. You may remember it or write it down. Now you can type

reboot

to restart the Raspberry Pi. (Please do not unplug the Raspberry Pi instead of rebooting because your filesystem may get corrupted)

Installing and configuring

On next start login to SSH via PuTTY (or similair SSH client) and standard credentials (pi/raspberry) Start a root console with

sudo bash

Company / Proxy settings

If you are in a company or using proxies you need to set them for updates and upgrades of packages (you don’t need this in most home environments)

nano /etc/apt/apt.conf

and enter your proxy:

    Acquire::http::Proxy "http://user:password@proxy1.sysstem.at:8080";

Update, Upgrade and Install packages

After the proxy settings are done start the update of the package information and the upgrade your packages

apt-get update && apt-get upgrade -y

Install packages needed for maintaining and for the VNC mirror itself

apt-get install -y x11vnc vim ssvnc unp htop

Store VNC Passwords

Generate a hidden directory for the VNC password file

mkdir /home/pi/.vnc

Generate a VNC password for X11VNC

x11vnc -storepasswd /home/pi/.vnc/x11vncpasswd

Store the VNC password of the remotemachine (the password you have defined on the remote machine)

x11vnc -storepasswd /home/pi/.vnc/remotevncpasswd

set read permission for the password files

chmod +r /home/pi/.vnc/*

Scripts

VNCViewer

open the following file

vim /home/pi/vncviewer

and copy the following content (more about it’s content you can find here)

# Process check script: The script simply checks if a process is running and if it is not found to be running it will execute it.
# The script loops in preset intervals, hence it is possible to monitor a process continuously.

# Variables
Running=1
SleepInterval=10
ProcessInstances=`sudo ps aux | grep [s]svncviewer | wc -l`

#VNC Variables
vnc=ssvncviewer
host=WSWDL02:1
display=0
resolution=1920x1080
passfile=/home/pi/.vnc/remotevncpasswd
para="-display :$display -viewonly -fullscreen -shared -passwd $passfile -scale $resolution -encoding zrle"

function checkstatus() {
        vncpid=$(pidof ssvncviewer)
        sigign=$(sudo cat /proc/${vncpid}/status | grep SigIgn | awk '{print $2}')
}

# Logic
while [ $Running -gt 0 ]
do

        if [ `sudo ps aux | grep [s]svncviewer | wc -l` -gt 0 ]; then
                echo Process already running! Checking the Status.
                checkstatus
                if [ $sigign !=  "0000000000000004" ]; then
                        echo SSVNCViewer has not status 4
                        echo Killing SSVNCViewer
                        kill ${vncpid}
                else
                        echo SSVNCViewer status seems to be ok
                fi
        else
                echo Process not running! Starting process
                # This is the command that should start the process in question
                $vnc $host $para &
        fi

        # How often shall we repeat the check?
        echo Sleeping for $SleepInterval seconds
        sleep $SleepInterval

done

exit 0

Change the permission for this script to execute

chmod +x /home/pi/vncviewer

VNCViewer Daemon

Make a little Daemon for the vncviewer to start and stop it.

vim /etc/init.d/vncviewerd

enter the following

### BEGIN INIT INFO

# Provides: vncviewerd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start or stop Custom VNC Viewer
# Description: Start or stop Custom VNC Viewer
### END INIT INFO
#! /bin/sh
# /etc/init.d/monitor
# Carry out specific functions when asked to by the system

#Start vncviewer
start() {
    echo Starting VNC Viewer
    su pi /home/pi/vncviewer &
}
#Stop vncviewer
stop() {
    echo Stopping VNC Viewer
    pkill -f vncviewer
}

### main logic ###
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        stop
        start
        ;;

    *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit 0

Make the script executable

chmod +x /etc/init.d/vncviewerd

and register it for autostart

update-rc.d vncviewerd defaults

Monitor

Create a script for turning on and off your monitor

vim /etc/init.d/monitor

enter the following

### BEGIN INIT INFO

# Provides: monitor
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start or stop Monitor
# Description: Start or stop Monitor
### END INIT INFO
#! /bin/sh
# /etc/init.d/monitor
# Carry out specific functions when asked to by the system

#Start Monitor
start() {
    echo Starting Monitor
    # Enable HDMI with preferred mode
    /opt/vc/bin/tvservice -p
    # Change console to enable monitor output
    # not very nice but ok
    sudo chvt 6
    sudo chvt 7
}
#Stop Monitor
stop() {
    echo Stopping Monitor
    /opt/vc/bin/tvservice -o
}

### main logic ###
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        stop
        start
        ;;

    *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit 0

Make it executable (but do not add it to autostart!)

chmod +x /etc/init.d/monitor

Miscellaneous Monitor settings

Disable monitor standby

vim /etc/kbd/config

search for POWERDOWN_TIME=30 and set it to 0

POWERDOWN_TIME=0

Restart KBD to activate new settings

sudo /etc/init.d/kbd restart

Disable overscan (it tries shrink the picture a little to fit on older monitors and TVs)

vim /boot/config.txt

remove the sharp (#) from #disable_overscan=1 it should now look like this

disable_overscan=1

Now it’s time to reboot your Raspberry VNC Mirror.

reboot

If you have questions or problems left leave them in the comments!

Hardening the Raspberry Pi VNC Mirror

***Please visit the new simplified installation of the Raspberry Pi VNC Mirror***

 

This is an extension from this post: Raspberry Pi – VNC Mirror (Repeater) – Make any computer public anywhere

Having a RPi as VNC Mirror in production is a nice idea. But from time to time energy shortages make the Raspberry Pi shutdown unexpectedly where it may come to SD card corruption while a read or write process was in progress.

Another thing I experienced is that sometimes the computer you want to mirror loses the network connection or is by itself down for any reason. After this the VNCViewer will hang in a state where it wants the user to click-OK the a message and does not do anything, also if the computer which is to be mirrored comes up again in the meanwhile.

I have found out if the process is running correctly and mirroring the other computer, its Signal Ignore state is 0000000000000004.

First I get the process ID of my ssvncviewer

pidof ssvncviewer

knowing the process ID (in my case 2134), the status of the process can now be viewed

pi@rpi1 ~ $ cat /proc/2134/status
Name:   ssvncviewer
State:  S (sleeping)
Tgid:   2134
Pid:    2134
PPid:   1944
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 20 24 27 29 44 46 60 100 106 999 1000
VmPeak:    16044 kB
VmSize:    16044 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      8904 kB
VmRSS:      8904 kB
VmData:    10792 kB
VmStk:       136 kB
VmExe:       276 kB
VmLib:      3972 kB
VmPTE:        18 kB
VmSwap:        0 kB
Threads:        1
SigQ:   0/3506
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000004
SigCgt: 0000000000004003
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   1
Cpus_allowed_list:      0
voluntary_ctxt_switches:        2071
nonvoluntary_ctxt_switches:     17019

I also tested it while the message “could not connect to …” was present.

In this case the SigIgn had the status 0000000000000006. So all we need to do is to check if SigIgn has the State of 0000000000000004. Otherwise we will simply kill the process. The scripts starts the VNCViewer again in some seconds.

This is the updated script, which is found in /home/pi/.config/autostart/vncview.sh

# Process check script: The script simply checks if a process is running and if it is not found to be running it will execute it.
# The script loops in preset intervals, hence it is possible to monitor a process continuously.

# Variables
Running=1
SleepInterval=20
ProcessInstances=`sudo ps aux | grep [s]svncviewer | wc -l`

#VNC Variables
vnc=ssvncviewer
host=vm1.sysstem.at
display=0
resolution=1920x1080
passfile=/home/pi/.vnc/passwd2
para="-display :$display -viewonly -fullscreen -shared -passwd $passfile -scale $resolution -encoding zrle"

function checkstatus() {
        vncpid=$(pidof ssvncviewer)
        sigign=$(sudo cat /proc/${vncpid}/status | grep SigIgn | awk '{print $2}')
}

# Logic
while [ $Running -gt 0 ]
do

        if [ `sudo ps aux | grep [s]svncviewer | wc -l` -gt 0 ]; then
                echo Process already running! Checking the Status.
                checkstatus
                if [ $sigign !=  "0000000000000004" ]; then
                        echo SSVNCViewer has not status 4
                        echo Killing SSVNCViewer
                        kill ${vncpid}
                else
                        echo SSVNCViewer status seems to be ok
                fi
        else
                echo Process not running! Starting process
                # This is the command that should start the process in question
                $vnc $host $para &
        fi

        # How often shall we repeat the check?
        echo Sleeping for $SleepInterval seconds
        sleep $SleepInterval

done

exit 0

To avoid SD card corruptions just follow the article by micerinos in the Raspberry Pi forum.

I created a script which does all the stuff (except for the apache thing) mentioned in the article, because I am lazy.

sudo bash
echo "RAMTMP=yes">>/etc/default/rcS
echo "proc            /proc           proc    defaults          0       0">/etc/fstab
echo "tmpfs           /var/log        tmpfs   nodev,nosuid,size=30M,mode=1777 0       0">>/etc/fstab
echo "tmpfs           /tmp            tmpfs   nodev,nosuid,size=30M,mode=1777 0       0">>/etc/fstab
echo "/dev/mmcblk0p1  /boot           vfat    defaults,ro,noatime,errors=remount-ro          0       1">>/etc/fstab
echo "/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1">>/etc/fstab
sed -i 's/[ ! -f /etc/adjtime ]/[ ! -L /etc/adjtime ]/;' /etc/init.d/hwclock.sh
echo "BLKID_FILE="/var/local/blkid.tab"">>/etc/environment
rm /etc/mtab
ln -s /proc/self/mounts /etc/mtab
echo "DPkg {">>/etc/apt/apt.conf
echo "    // Auto re-mounting of a readonly /">>/etc/apt/apt.conf
echo "    Pre-Invoke { "mount -o remount,rw /"; };">>/etc/apt/apt.conf
echo "    Post-Invoke { "test ${NO_APT_REMOUNT:-no} = yes || mount -o remount,ro / || true"; };">>/etc/apt/apt.conf
echo "};">>/etc/apt/apt.conf

Hope you’re lazy too! 😉

 

Linux Proxies

When you run Linux which is not directly connected to the internet you normally encounter several problems. Things like that your linux cannot resolv a DNS name or cannot connect to specific source (couldn’t connect to host). This is normally in a corporate network where not every computer is intended to be directly connected with the internet but instead to a proxy.

Here are the most common proxy-settings I use. Just hack it into your command line interface, also called bash or terminal.

  • System Proxy
export http_proxy=http://user:password@hostname:port
export https_proxy=http://user:password@hostname:port
export ftp_proxy=http://user:password@hostname:port
export HTTP_PROXY=$http_proxy
export HTTPS_PROXY=$https_proxy
export FTP_PROXY=$ftp_proxy
The last three lines are for programms which ask the proxies in upper case. I do not know if this is neccesary but it seems to be that the Ubuntu developers think so.
  • WGET Proxy
vim /etc/wgetrc
or
vi /etc/wgetrc

and add these lines

https_proxy = http://user:password@hostname:port
http_proxy = http://user:password@hostname:port
ftp_proxy = http://user:password@hostname:port
You may also need another proxy for your Ubuntu, Debian and other forks.
  • Aptitude (apt-get) Proxy (this file might not exist. Create it and save it)
vim /etc/apt/apt.conf
and add this line
Acquire::http::Proxy "http://user:password@hostname:port";
  • SVN Proxy
vim /etc/subversion/servers
search for this:
[global]
# http-proxy-exceptions = *.exception.com, www.internal-site.org
<strong>http-proxy-host = yourproxy.com http-proxy-port = yourproxyport</strong>
# http-proxy-username = defaultusername
# http-proxy-password = defaultpassword
...snip...

If you receive an error like this:

/etc/subversion/servers:71: Option expected

than you need to remove the space ‘ ‘ character in front of your line. Your proxy line must begin at position 1.

Remember the standard ports

  • HTTP: 80
  • HTTPS: 443
  • FTP: 21
Some proxyproviders also take portnumbers for http like: 8080,3128 and following.

Now you are done. Go internetting with your Linux!