0

I have a fleet of linux computers ("nodes" from here on out) who are what I'll call ephemeral members of a network. The nodes are vehicle mounted and frequently move into and out of wifi coverage.

Of course, it's often beneficial for me to push the update of a single script, program or file to all nodes. What I came up with is this:

  1. Generate a key pair to be shared by all nodes
  2. Encrypt the new file version, with a header that contains installation path, on my workstation. My workstation of course has the public key.
  3. Place the encrypted update in a node-accessible network "staging" folder
  4. When a node finds itself with a good connection, it checks the staging folder.
  5. If there are new files, they're:
    • copied to the node
    • decrypted
    • checked for integrity("Does the file header look good?")
    • moved to the location prescribed by the header

Here's a simple version of my code. Is this a bad idea? Is there a more elegant way to deal with updating unattended nodes on a super flaky connection?

  #!/bin/bash
    #A method for autonomously retrieving distributed updates

    #The latest and greatest files are here:
    stageDir="/remoteDirectory/stage"
    #Files are initially moved to a quarantine area
    qDir="/localDirectory/quarantine"
    #If all went well, put a copy of the encrypted file here:
    aDir="/localDirectory/pulled"
    #generic extension for encrypted files "Secure Up Date"
    ext="sud"

    for file in "$stageDir"/*."$ext"; do    #For each "sud" file...
        fname=$(basename $file)
        if [ ! -f $aDir/$fname ]; then  #If this file has not already been worked on...
            cp "$file" "$qDir"/"$fname" #Move it to the quarantine directory
        else
            echo "$fname has already been pulled"   #Move along
        fi
    done

    if [ "$(ls $qDir)" ]; then  #If there's something to do (i.e. files in the directory)
        for file in "$qDir"/*."$ext"; do
            fname=$(basename $file)
            qPath="$qDir/$fname"
            untrusted="$qPath.untrusted"
            #Decrypt file
            gpg --output "$untrusted" --yes --passphrase "supersecretpassphrase" --decrypt "$qPath" #Say yes to overwriting
            headline=$(head -n 1 $untrusted)    #Get the header (which is the first line of the file)
            #Check to see if this is a valid file
            if [[ $headline == "#LOOKSGOOD:"* ]]; then  #All headers must start with "#LOOKSGOOD:" or something
                #Get install path
                installPath=$(echo $headline | cut -d ':' -f 2) #Get the stuff after the colon
                tail -n +2 $untrusted > $installPath    #Send everything but the header line to the install path
                #Clean up our working files
                rm $untrusted
                mv $qPath "$aDir/$fname"
                #Report what we did
                echo $headline
            else
                #trash the file if it's not a legit file
                echo "$fname is not a legit update...trashing it"
                rm "$qDir/$fname"*
            fi
        done
    fi
mdjames
  • 11
  • 5
  • I don't think this is a forum for asking for something like "Is this a bad idea? Is there a more elegant way to deal with updating unattended nodes on a super flaky connection?" Questions should be as objective as possible, but you're only asking for subjective opinions. – 4ae1e1 Jun 04 '15 at 21:05
  • Probably better asked at [security](http://security.stackexchange.com). Some hints: you might as well use symmetric crypto for encrypting the updates - the nodes are much easier to attack than your server I presume. You should definitely perform *code signing* on your server, using a private key belonging to your server and checking the signature on your other devices. – Maarten Bodewes Jun 06 '15 at 19:21

0 Answers0