diff --git a/cert-autorefresh b/cert-autorefresh
new file mode 100755
index 0000000000000000000000000000000000000000..6fd09af5dfa386ecabdb6de0f290dedcd7c375a7
--- /dev/null
+++ b/cert-autorefresh
@@ -0,0 +1,294 @@
+#!/usr/bin/env bash
+
+#
+# constant
+#
+
+apitokenfile=$( basename $0 ).apitoken
+
+#
+# Help
+#
+
+function helpAndExit()
+{
+    echo "Syntax: $0 [options]" >&2
+    echo >&2
+    echo "Options:" >&2
+    echo "  -t, --token [APITOKEN]    API token to use against ra-portal.rwth" >&2
+    echo "                            or be read from ./$apitokenfile">&2
+    echo "  -h, --hostname [HOSTNAME] set hostname, otherwise hostname will be calculated" >&2
+    echo "  -r, --revoke              revoke old cert, if new one was downloaded" >&2
+    echo "  -s, --symlink             create symlinks" >&2
+    echo "  -v, --verbose             increase verbosity level (up to 3)" >&2
+    exit 1
+}
+
+#
+# Get Options
+#
+
+verbose=0
+
+while [ "$#" -gt 0 ]; do
+    case "$1" in
+        -t|--token)
+            apitoken="$2"
+            shift 2
+            ;;
+        -h|--hostname)
+            hostname="$2"
+            shift 2
+            ;;
+        -r|--revoke)
+            revoke=TRUE
+            shift 1
+            ;;
+        -s|--symlinks)
+            symlinks=TRUE
+            shift 1
+            ;;
+        -v|--verbose)
+            ((verbose++))
+            shift 1
+            ;;
+        -?|--help)
+            helpAndExit
+            ;;
+        -*|*)
+            echo "[ERROR   ] Unknown option: $1"
+            echo
+            helpAndExit
+            ;;
+    esac
+done
+
+#
+# Option Check
+#
+
+if [ ! $apitoken ]
+then
+    [ $verbose -ge 1 ] && echo "[INFO    ] reading API Token from ./$apitokenfile"
+    apitoken=$( cat $apitokenfile )
+fi
+
+
+#
+# function ra_portal
+#
+
+function ra_portal()
+{
+    local data=""
+    local mode=$1
+    shift 1
+    local link="https://ra-portal.itc.rwth-aachen.de/api/ssl-certificates/$1"
+    shift 1
+    while [ $# -gt 0 ]
+    do
+        data+=" --data $1"
+        shift 1
+    done
+    local cmd="curl --silent --request $mode --header \"Authorization: Basic ${apitoken}\" ${data} \"${link}\""
+    [ $verbose -ge 3 ] && echo "[COMMAND ] $cmd" >&2
+    curl --silent --request $mode --header "Authorization: Basic ${apitoken}" ${data} "${link}"
+}
+
+#
+# API Token Check
+#
+
+content=$( ra_portal GET api-token-info | jq )
+[ $verbose -ge 2 ] && echo -e "[VERBOSE ] API Token content:\n$content"
+[ $( echo $content | jq -r '.status' ) == 401 ] && echo "[ERROR   ] $( echo $content | jq -r '.error' )" && exit 2
+[ $verbose -ge 1 ] && echo "[INFO    ] API Token '$( echo $content | jq -r '.name' )' valid."
+
+#
+# API Token Expiration Check
+#
+
+let tokenExpirationDays=($( date +%s -d $( echo $content | jq -r '.expires_at' )  )-$( date +%s ))/86400
+[ $tokenExpirationDays -lt 90 ] && echo "[WARNING ] API Token '$( echo $content | jq -r '.name' )' expires in $tokenExpirationDays days." || ( [ $verbose -ge 2 ] && echo "[VERBOSE ] API Token '$( echo $content | jq -r '.name' )' expires in $tokenExpirationDays days." )
+
+#
+# get hostname
+#
+
+if [ -z $hostname ]
+then
+    [ $verbose -ge 1 ] && echo "[INFO    ] hostname not set."
+    hostname=$( hostname )
+fi
+[ $verbose -ge 1 ] && echo "[INFO    ] hostname is '$hostname'."
+
+#
+# get actual cert data
+#
+
+content=$( ra_portal GET list status=current subject_alternative_name=$hostname | jq )
+[ $verbose -ge 2 ] && echo -e "[VERBOSE ] RA-Portal Cert-List:\n$content"
+certListElements=$( echo $content | jq 'length')
+[ $certListElements -eq 0 ] && echo "[ERROR   ] RA-Portal Cert-List empty." && exit 3
+[ $certListElements -gt 2 ] && echo "[ERROR   ] RA-Portal Cert-List contains more than 2 elements." && exit 3
+
+i=0
+while [ $i -lt $certListElements ]
+do
+    referenceNumber=$( echo $content | jq -r ".[$i] | .reference_number" )
+    enrolledAt=$( echo $content | jq -r ".[$i] | .enrolled_at" )
+    expiresAt=$( echo $content | jq -r ".[$i] | .expires_at" )
+    if [ "$expiresAt" = "null" ]
+    then
+        referenceNumberRenew=$referenceNumber
+        enrolledAtRenew=$enrolledAt
+        expiresAtRenew=$expiresAt
+    else
+        # did we found a secondary cert?
+        if [ $expiresAtCert ]
+        then
+            if [ $( date +%s -d $expiresAtCert ) -gt $( date +%s -d $expiresAt ) ]
+            then
+                referenceNumberRenew=$referenceNumberCert
+                enrolledAtRenew=$enrolledAtCert
+                expiresAtRenew=$expiresAtCert
+            else
+                referenceNumberRenew=$referenceNumber
+                enrolledAtRenew=$enrolledAt
+                expiresAtRenew=$expiresAt
+                ((i++))
+                continue
+            fi
+        fi
+        referenceNumberCert=$referenceNumber
+        enrolledAtCert=$enrolledAt
+        expiresAtCert=$expiresAt
+    fi
+    ((i++))
+done
+let expiresInCert=($( date +%s -d $expiresAtCert )-$( date +%s ))/86400
+[ $verbose -ge 1 ] && echo "[INFO    ] RA-Portal Cert Reference Number: $referenceNumberCert"
+
+#
+# renew certificate
+#
+
+if [ $expiresInCert -le 28 ]
+then
+    echo "[WARNING ] '$hostname' cert expires in $expiresInCert days."
+    if [ $referenceNumberRenew ]
+    then
+        echo "[WARNING ] renew '$hostname' already started at $referenceNumberRenew"
+    else
+        content=$( ra_portal POST renew reference_number=$referenceNumberCert | jq )
+        [ $verbose -ge 1 ] && echo -e "[INFO    ] request renew certificate."
+        [ $verbose -ge 2 ] && echo -e "[VERBOSE ] RA-Portal Renew:\n$content"
+        referenceNumberRenew=$( echo $content | jq -r ".reference_number" )
+        enrolledAtRenew="null"
+        expiresAtRenew="null"
+    fi
+else
+    [ $verbose -ge 1 ] && echo -e "[INFO    ] everything looks good."
+    enrolledAtRenew="null"
+    expiresAtRenew="null"
+fi
+
+#
+# send request
+#
+
+if [ $referenceNumberRenew ]
+then
+    if [ "$enrolledAtRenew" = "null" ]
+    then
+        content=$( ra_portal POST enroll reference_number=$referenceNumberRenew | jq )
+        [ $verbose -ge 1 ] && echo -e "[INFO    ] enrolled renew request."
+        [ $verbose -ge 2 ] && echo -e "[VERBOSE ] RA-Portal Enroll:\n$content"
+        expiresAtRenew="null"
+    else
+        if [ "$expiresAtRenew" = "null" ]
+        then
+            echo "[WAITING ] renew '$hostname' already enrolled."
+        else
+            [ $verbose -ge 1 ] && echo "[INFO    ] new certificate '$hostname' ready for download."
+        fi
+    fi
+fi
+
+#
+# file basename
+#
+
+if [ $expiresAtRenew = "null" ]
+then
+    referenceNumber=$referenceNumberCert
+    enrolledAt=$enrolledAtCert
+    expiresAt=$expiresAtCert
+else
+    referenceNumber=$referenceNumberRenew
+    enrolledAt=$enrolledAtRenew
+    expiresAt=$expiresAtRenew
+fi
+
+filebasename="$( echo $enrolledAt | cut -dT -f1 | sed 's/-//g' )-$( echo $expiresAt | cut -dT -f1 | sed 's/-//g' )"
+[ ! -d $filebasename ] && mkdir $filebasename && [ $verbose -ge 1 ] && echo "[INFO    ] created subdir $filebasename"
+filebasename="$filebasename/$hostname.$filebasename"
+[ $verbose -ge 2 ] && echo "[VERBOSE ] filebasename: $filebasename"
+
+#
+# download cert
+#
+
+if [ ! -e $filebasename.cert.pem ]
+then
+    echo "[DOWNLOAD] $filebasename.cert.pem"
+    ra_portal GET download reference_number=$referenceNumber > $filebasename.cert.pem
+else
+    [ $verbose -ge 1 ] && echo "[INFO    ] $filebasename.cert.pem already downloaded"
+fi
+if [ ! -e $filebasename.intermediates.pem ]
+then
+    echo "[DOWNLOAD] $filebasename.intermediates.pem"
+    ra_portal GET download-intermediates-only reference_number=$referenceNumber > $filebasename.intermediates.pem
+    [ $verbose -ge 2 ] && echo "[VERBOSE ] splitting intermediates file"
+    csplit -s -k -f $filebasename.intermediates.pem. -b %d $filebasename.intermediates.pem '/END CERT/+1'
+    [ $verbose -ge 2 ] && echo "[VERBOSE ] getting root hash"
+    rootHash=$( openssl x509 -in $( ls -1 $filebasename.intermediates.pem.* | tail -n1 ) -nocert -issuer_hash )
+    rm $filebasename.intermediates.pem.*
+    [ $verbose -ge 2 ] && echo "[VERBOSE ] symlink root cert"
+    ln -s /etc/ssl/certs/$rootHash.0 $filebasename.root.pem
+    [ $verbose -ge 1 ] && echo "[INFO    ] setting up chain cert+chain cert+intermediates"
+    cat $filebasename.intermediates.pem $filebasename.root.pem > $filebasename.chain.pem
+    cat $filebasename.cert.pem $filebasename.chain.pem > $filebasename.cert+chain.pem
+    cat $filebasename.cert.pem $filebasename.intermediates.pem > $filebasename.cert+intermediates.pem
+else
+    [ $verbose -ge 1 ] && echo "[INFO    ] $filebasename.intermediates.pem already downloaded"
+fi
+
+#
+# create symlinks
+#
+
+if [ $symlinks ]
+then
+    [ $verbose -ge 1 ] && echo "[INFO    ] updating symlinks"
+    for n in cert chain intermediates cert+chain cert+intermediates
+    do
+        [ -L $n.pem ] && unlink $n.pem && [ $verbose -ge 2 ] && echo "[VERBOSE ] unlink $n.pem"
+        ln -s $filebasename.$n.pem $n.pem && [ $verbose -ge 2 ] && echo "[VERBOSE ] symlink $n.pem"
+    done
+fi
+
+#
+# revoke old cert
+#
+
+if [ $revoke ]
+then
+    if [ $referenceNumber != $referenceNumberCert ]
+    then
+        content=$( ra_portal POST revoke reference_number=$referenceNumberCert )
+        [ $verbose -ge 1 ] && echo -e "[INFO    ] old certificate revoked."
+        [ $verbose -ge 2 ] && echo -e "[VERBOSE ] RA-Portal revoke:\n$content"
+    fi
+fi