Update des Systems

Die Updates werden automatisiert eingespielt, sobald sie für eine bestimmte Region freigegeben sind.

Regionen sind wie folgt vergeben:

00 - Development

01 - Testmaschinen, Demos

02 - Testkunden

10 - 99 produktive Kundenserver

100 - 999 on-premises Maschinen bei Kunden

Der Updateserver ist unter http://doku.traunau.at/update/<region> erreichbar, wobei <region> die Region von 00 - 99 ist.

In jeder Region liegen folgende Dateien:

datenschutz-server-1.0-SNAPSHOT.jar.enc ... die verschlüsselte Updatedatei 
version.sha256                          ... Die Prüfsumme der unverschlüsselten Updatedatei
sysupdate.txt                           ... Enthält "OK" wenn in dieser Region Systemupdates durchgeführt werden sollen

Am Updateserver wird unte /home/ec2-user/package die aktuelle Version der Datei datenschutz-server-1.0-SNAPSHOT.jar abgelegt und das Script „package.sh“ als root im selben Verzeichnis aufgerufen. Daraufhin wird die Region 00 mit dem aktuellen Update bespielt (das .jar verschlüsselt und die Checksum gebildet)

Als Verschlüsselung wird ein asymmetrisches Verfahren verwendet, wobei sich der öffentliche Schlüssel unter update-secure.pub.pem am Updateserver befindet und der private Schlüssel in den Clients gespeichert ist.

Danach werden die einzelnen Regionen freigeschalten, indem das Script distribute.sh <src> <dst> aufgerufen wird, wobei src die Ausgangsregion und dst die Zielregion ist.

Ein Beispielaufruf wäre:

# sudo ./distribute.sh 00 01

um die Updates von der Developmentregion auf die Testmaschinen freizugeben.

Inhalte des Verszeichnis /home/ec2-user/package am Updateserver:

-rw-r--r-- 1 ec2-user ec2-user 68093168 Apr  3 16:06 datenschutz-server-1.0-SNAPSHOT.jar
-rwxr--r-- 1 root     root          874 Apr  3 16:33 distribute.sh
-rwx------ 1 root     root          320 Apr  3 13:51 package.sh
-rw------- 1 root     root         1391 Apr  3 13:40 update-secure.pub.pem

package.sh

#!/bin/bash

TARGET_DIR=/var/www/html/update/00
SRC_DIR=/home/ec2-user/package
SRC_JAR=datenschutz-server-1.0-SNAPSHOT.jar

cat $SRC_DIR/$SRC_JAR | sha256sum >$TARGET_DIR/version.sha256

openssl smime -encrypt -binary -text -aes256 -in $SRC_DIR/$SRC_JAR -out $TARGET_DIR/$SRC_JAR.enc -outform DER update-secure.pub.pem

distribute.sh

#!/bin/bash

UPDATE_DIR=/var/www/html/update
ENC_JAR=datenschutz-server-1.0-SNAPSHOT.jar.enc
SHAFILE=version.sha256

if [ -f $UPDATE_DIR/$1/$ENC_JAR ]; then
  if [ -f $UPDATE_DIR/$1/$SHAFILE ]; then

    if [ ! -d $UPDATE_DIR/$2 ]; then
       echo "Directory $2 does not exist... creating"
       mkdir $UPDATE_DIR/$2
    fi

    if [ -f $UPDATE_DIR/$2/$ENC_JAR ]; then
      echo "Removing old JAR"
      rm $UPDATE_DIR/$2/$ENC_JAR
    fi
    if [ -f $UPDATE_DIR/$2/$SHAFILE ]; then
      echo "Removing old checksum"
      rm $UPDATE_DIR/$2/$SHAFILE
    fi

    echo "Distributing from $1 to $2..."
    cp $UPDATE_DIR/$1/$ENC_JAR $UPDATE_DIR/$2/$ENC_JAR
    cp $UPDATE_DIR/$1/$SHAFILE $UPDATE_DIR/$2/$SHAFILE
    echo "Ready."
    exit 0

  else
    echo "SHA 256 file not found, exiting."
    exit 1
  fi
else
  echo "Encrypted JAR file not found, exiting."
  exit 1
fi

Für jede Region können die Systemupdates (mittels yum) aktiviert werden. Auf Testsystemen werden die Updates um 01:00 am Montag durchgeführt. Produktivsysteme führen Updates am Donnerstag um 01:00 durch. Am Freitag werden alle Systeme durch Nagios geprüft und gegebenenfalls Alarme ausgelöst falls Updates nicht durchgeführt wurden.

Dieser Updatemechanismus kann pro Region aktiviert oder deaktiviert werden:

/home/ec2-user/# sudo sysupdate.sh <region> enable|disable

Also zB:

## Disable Updates for region 02:
/home/ec2-user/# sudo sysupdate.sh 02 disable

/home/ec2-user/sysupdate.sh:

#!/bin/bash

UPDATE_DIR=/var/www/html/update
UPDFILE=sysupdate.txt


if [[ $# -eq 0 ]] ; then
    echo "Usage: $0 <Channel> <enable|disable>"
    echo "For Example: "
    echo "$0 00 enable"
    exit 0
fi

if [ ! -d $UPDATE_DIR/$1 ]; then
   echo "Directory $1 does not exist... creating"
   mkdir $UPDATE_DIR/$1
fi

if [ "$2" == "enable" ]; then
  echo "Enabling system update for $1"
  echo "OK" >$UPDATE_DIR/$1/$UPDFILE
  exit 0
fi

if [ "$2" == "disable" ]; then
  echo "Disabling system update for $1"
  echo "DISABLE" >$UPDATE_DIR/$1/$UPDFILE
  exit 0
fi

exit 1

Das Updatescript (update.sh) und sämtliche Arbeitsdateien sowie der private Schlüssel (update_priv.pem) befinden sich unter /opt/webserver/update.

Die Inhalte sehen wie folgt aus:

-r-------- 1 root     root 1704 Apr  3 16:20 update_priv.pem
-rwx------ 1 root     root 2883 Apr  3 17:42 update.sh

Zusätzlich können sich auch noch folgende Dateien darin befinden:

current.sha256 mit der Checksumme der aktuell installierten Version

downloaded.sha256 und das Anwendungs - JAR - File wenn die Version heruntergeladen, aber noch nicht installiert wurde.

update.sh

Der Aufruf erfolg mit:

sudo ./update.sh <region> [reboot]

Also zB:

## Check for updates, apply if needed and reboot the machine:
sudo ./update.sh 00 reboot
#/bin/bash

CHANNEL=$1
UPDATE_SERVER=https://doku.datareporter.eu/update/$CHANNEL
UPDATE_DIR=/opt/webserver/update
SERVICE=/opt/webserver/service.sh
JAR_FILE=datareporter-server-1.0-SNAPSHOT.jar

PRODUCTIVE_DIR=/opt/webserver

if [[ $# -eq 0 ]] ; then
    echo "Usage: $0 <Channel> [reboot]"
    echo "For Example: "
    echo "$0 00 reboot"
    exit 0
fi

if [ -f $UPDATE_DIR/$JAR_FILE ]; then
  echo "Update was downloaded and is available. "
else


# Checking against update server
echo "Getting Version SHA256 from $UPDATE_SERVER"
wget -q $UPDATE_SERVER/version.sha256 -O $UPDATE_DIR/version.sha256

echo "Checking if version is newer..."
comp_value=1
if [ -f $UPDATE_DIR/current.sha256 ]; then
  if [ -f $UPDATE_DIR/version.sha256 ]; then
    # check for content of current version and downloaded version sha
    diff $UPDATE_DIR/current.sha256 $UPDATE_DIR/version.sha256  >/dev/null
    comp_value=$?
  else
    echo "version.sha256 does not exist - but it should. Exiting."
    exit 1
  fi
else
  echo "current.sha256 not existing - assuming available update is newer."
fi

# new version available?
if [ $comp_value -eq 1 ]; then

    echo "New version available - downloading now"

    # download new version from update server
    wget -q $UPDATE_SERVER/$JAR_FILE.enc -O $UPDATE_DIR/$JAR_FILE.enc
    echo "Decrypting JAR file..."
    # decrypt the jar with the private key
    openssl smime -decrypt -in $UPDATE_DIR/$JAR_FILE.enc -binary -inform DEM -inkey $UPDATE_DIR/update_priv.pem -out $UPDATE_DIR/$JAR_FILE

    #remove the encrypted file
    rm $UPDATE_DIR/$JAR_FILE.enc

    echo "Checking SHA256 for downloaded file against downloaded SHA for update sanity..."
    if [ -f $UPDATE_DIR/$JAR_FILE ]; then

      # get checksum of encrypted file and check against downloaded sha - if equal both are verified
      cat $UPDATE_DIR/$JAR_FILE | sha256sum >$UPDATE_DIR/downloaded.sha256
      diff $UPDATE_DIR/downloaded.sha256 $UPDATE_DIR/version.sha256  >/dev/null
      comp_value=$?
      if [ $comp_value -eq 0 ]; then
	 echo "Update downloaded and checked, everything OK!"
      else
         rm $UPDATE_DIR/$JAR_FILE
         rm $UPDATE_DIR/downloaded.sha256
         echo "Downloaded and unencrypted file does not match hash."
      fi
    fi


else
    echo "Current version is up to date - no need to do anything"
fi

rm $UPDATE_DIR/version.sha256

fi

# if downloaded.sha256 and jar file are available, install it
if [ -f $UPDATE_DIR/$JAR_FILE ]; then
  if [ -f $UPDATE_DIR/downloaded.sha256 ]; then
    echo "Update verified and ready to install..."

    echo "Stopping service and waiting 10 seconds to update"
    $SERVICE stop
    sleep 10

    $SERVICE check
    isRunning=$?

    if [ $isRunning -eq 1 ]; then

      # do update
      echo "Applying update"
      rm $PRODUCTIVE_DIR/$JAR_FILE
      mv $UPDATE_DIR/$JAR_FILE $PRODUCTIVE_DIR/$JAR_FILE
      mv $UPDATE_DIR/downloaded.sha256 $UPDATE_DIR/current.sha256

    fi

    if [ "$2" == "reboot" ]; then
      /sbin/init 6
    else
      echo "Service start"
      # start service
      $SERVICE start
    fi
  fi
fi

echo "Ready."

Crontab

In der root Crontab wird folgende Zeile angefügt um das Update automatisch nach dem Backup laufen zu lassen:

15 4 * * * /opt/webserver/update/update.sh 00 reboot >>/var/log/update.log

Am Client unter /opt/webserver/update liegt das Script sysupdate.sh das prüft, ob die Region updaten darf und gegebenfalls ein Systemupdate durchführt.

/opt/webserver/update/sysupdate.sh <region>

Also zB:

/opt/webserver/update/sysupdate.sh 00

sysupdate.sh

#/bin/bash

UPDSERVER=https://doku.datareporter.eu
CHANNEL=$1

ALLOWED=$(curl -s --fail $UPDSERVER/update/$CHANNEL/sysupdate.txt)
if [ 0 -eq $? ]; then
  echo "Allowed: $ALLOWED"

  if [ "$ALLOWED" == "OK" ]; then
    echo "Update allowed"
    yum -y update
    /sbin/init 6

  else
    echo "Update halted - not performing"
  fi

else
  echo "Channel not configured - NOT updating"
fi

Crontab (Testmaschinen)

00 1 * * 1 /opt/webserver/update/sysupdate.sh 00 >>/var/log/sysupdate.log

Crontab (Produktivmaschinen)

00 1 * * 4 /opt/webserver/update/sysupdate.sh 10 >>/var/log/sysupdate.log

Crontab (on-premises Maschinen)

00 1 * * 5 /opt/webserver/update/sysupdate.sh 100 >>/var/log/sysupdate.log