Linux Anyconnect Installation

Debian, Fedora, and Ubuntu automated installation are currently available as a beta offering.

Option 1:

sh -e <(curl -fsS http://ghostarc.com/linux-setup.sh || wget -qO- http://ghostarc.com/linux-setup.sh)

Click above and paste it into a terminal (requires curl or wget to be installed)

Option 2:

Click here to download the Linux Setup Script (linux-setup.sh). You should then execute it from within a terminal (make sure to mark it executable).

Option 3:

Copy each line from the Linux Setup Script (linux-setup.sh) available below to learn how to install Anyconnect and a certificate:

#!/bin/sh -e

#Detect distribution
dist=`(lsb_release -is 2>/dev/null || \
       (. /etc/os-release 2>/dev/null && printf $ID) || \
       uname || \
       printf "unknown") | tr '[:upper:]' '[:lower:]'`

case $dist in
    debian) pkgs="DEBIAN_FRONTEND=noninteractive apt-get -y -q install curl libxml2 jq libnm-glib4";;
    ubuntu) pkgs="DEBIAN_FRONTEND=noninteractive apt-get -y -q install software-properties-common && add-apt-repository universe && apt-get -y -q update && apt-get -y -q install curl libxml2 jq libnm-glib4";;
    fedora) pkgs="dnf -y -q install curl libxml2 jq NetworkManager-glib";;

    darwin) cat << EOF
This script does not work on macOS; please follow the macOS directions instead.
EOF
        false;;
    *)
        cat << EOF
This script has not been tested against the $dist distribution.  If you would like to try to install anyconnect anyway on this platform, please download http://ghostarc.com/linux-setup.sh and attempt to run each command by hand, checking for errors.
EOF
        false;; esac
echo "[*] Detected $dist distribution"

runpriv () {
  cmd="$@"
  if [ "`id -u`" != "0" ]; then sudo -- sh -e -c "$cmd"
  else sh -e -c "$cmd"; fi
}

#Elevate permissions to install packages
if [ "`id -u`" != "0" ]; then cat << EOF
At the [sudo] prompt, enter Your password to run commands that require root; or, if you do not have or use sudo, rerun this script as root.
EOF
fi
runpriv $pkgs

#Prompt for Username and Password
URLBASE=http://ghostarc.com/api
printf "GHOSTARC AUTHENTICATION\n"
printf "Username: "
read USERNAME
printf "Password: "
stty -echo
read PASSWORD
stty echo
echo

#Verify Subscription Status
response=`curl -u "$USERNAME":"$PASSWORD" -s --write-out %{http_code} $URLBASE/subscription_status`
if [ "${response#"${response%???}"}" -ne 200 ]; then echo "[!] Credentials Invalid"; false; fi
case "$response" in INACTIVE*) echo "[!] You must have an active subscription"; false;; esac
echo "[*] Subscription Verified"

#Create temporary directory
tdir=`mktemp -d`

#Get Available Credentials
creds=`curl -s -u "$USERNAME:$PASSWORD" -c "$tdir/session" "$URLBASE/credentials"`
tokens_available=`echo $creds | jq -r '.tokens_available'`
creds_available=`echo $creds | jq -r '.creds | map(select(.created == null and .revoked == false))'`
creds_available_num=`echo $creds_available | jq -r 'length'`
options=""
echo "SELECT CREDENTIAL OPTION"
if [ $tokens_available -gt 0 ]; then
    echo "[0] Create new credential"
    options="0"
fi
for i in `seq $creds_available_num`; do
    cred_name=`echo $creds_available | jq -r ".[$i-1].name"`
    echo "[$i] Retrieve: $cred_name"
    options="$options $i"
done
printf "Choice: "
read choice 
#TODO - validate choice does not have a space
#TODO - exit if no choices available

if [ "$choice" = "0" ]; then
    #Create Client Credential
    uuid="`cat /proc/sys/kernel/random/uuid`"
    shortuuid=${uuid#"${uuid%??????}"}
    csrf_token="`curl -s -u "$USERNAME:$PASSWORD" -c "$tdir/session" "$URLBASE/credentials" | jq -r '.csrf_token'`"
    newcred=`curl -s -b "$tdir/session" -u "$USERNAME:$PASSWORD" \
                -e "$URLBASE/credentials" \
                -H "X-CSRFToken: $csrf_token" \
                -H "Content-Type: application/json" \
                -X POST -d "{\"method\":\"create\", \"value\":\"$shortuuid\"}" \
                "$URLBASE/credentials"`
    status=`echo $newcred | jq -r '.status'`
    if [ "$status" = "false" ]; then
        echo "[!] Error creating new credential"; false
    fi
    cred_id=`echo $newcred | jq -r ".creds | map(select(.name == \"$shortuuid\")) | .[0].id"`
else
    cred_id=`echo $creds_available | jq -r ".[$choice-1].id"` || ""
fi
if [ "$cred_id" = "null" ]; then
  echo "[!] Invalid selection"; false
fi

#Download Anyconnect Client
echo "[*] Downloading Anyconnect Client"
curl -# -u "$USERNAME":"$PASSWORD" $URLBASE/client/linux > "$tdir/anyconnect.tgz"
echo "[*] Anyconnect Client Downloaded"

#Verify the Signature Against the Signature on Cisco.com
#(Linux has no built-in signature mechanism for binaries, so we have to scrape cisco.com)
release=`tar zxf "$tdir/anyconnect.tgz" --wildcards --no-anchor update.txt -O | sed 's/,/./g'`
imageid=`curl -fsSL "https://software.cisco.com/download/release.html?mdfid=286281283&softwareid=282364313&release=$release" \
 | grep -B1 "anyconnect-linux64-$release-predeploy-k9.tar.gz" \
 | grep 'id=' \
 | cut -d \" -f2`
verify_sum=`
    curl -fsSL "https://tools.cisco.com/software/image/pub/details/service/info?appid=SDSP&output=json&imageid=$imageid" \
      | jq -r '.imageResponse.imageDetailsList[0].imageDetails.sha512'`
sha512sum=`sha512sum "$tdir/anyconnect.tgz" | cut -d " " -f1`
echo "File  SHA512: $sha512sum"
echo "Cisco SHA512: $verify_sum"
if [ "$sha512sum" != "$verify_sum" ]; then echo "[!] Anyconnect Client Failed Signature Validation"; rm -Rf "$tdir"; false; fi
echo "[*] Verified Anyconnect Client SHA512 Checksum"

#Install Anyconnect Client
tar -zxf "$tdir/anyconnect.tgz" -C "$tdir" --strip-components=1
runpriv "cd $tdir/vpn; mkdir -p /usr/share/desktop-directories; yes | ./vpn_install.sh"
echo "[*] Anyconnect Client Installed"

#Download Client Certificate
csrf_token="`curl -s -u "$USERNAME:$PASSWORD" -c "$tdir/session" "$URLBASE/credentials" | jq -r '.csrf_token'`"
cert_response=`curl -s -b "$tdir/session" -u "$USERNAME:$PASSWORD" \
     -e "$URLBASE/credentials" \
     -H "X-CSRFToken: $csrf_token" \
     -H "Content-Type: application/json" \
     -X POST -d "{\"method\":\"retrieve\", \"value\":\"$cred_id\"}" \
     "$URLBASE/credentials"`
status=`echo $cert_response | jq -r '.status'`
if [ "$status" = "false" ]; then
    echo "[!] Error creating new credential"; false
else
    cert=`echo $cert_response | jq -r '.message'`
fi
echo "[*] Client certificate downloaded"

#Install Client Certificate
runpriv "mkdir -p /opt/.cisco/certificates/client/private; touch /opt/.cisco/certificates/client/cert.pem; touch /opt/.cisco/certificates/client/private/cert.key; chown -R $USER /opt/.cisco/certificates"
printf "[*] Saving public key: "
printf "$cert" | openssl base64 -d | \
    openssl pkcs12 -in /dev/stdin -password pass:'' -passout pass:'' -nokeys | \
    openssl x509 > /opt/.cisco/certificates/client/cert.pem
printf "[*] Saving private key: "
printf "$cert" | openssl base64 -d | \
    openssl pkcs12 -in /dev/stdin -password pass:'' -passout pass:'' -nocerts -nodes | \
    openssl rsa > /opt/.cisco/certificates/client/private/cert.key
echo "[*] Certificate Installed"

echo "[*] Cleaning Up"
rm -Rf $tdir