Thursday, May 12, 2016

Last resort remote shell with google drive

When you don't have a public IP for your home network you may use chrome remote desktop, or teamviewer connect remotely. I'm going to demonstrate a simple way which I'm using to control my home server from anywhere.

It is not only simple but also:
  • highly portable where you can issue commands from any device which support google drive such as computer or mobile phone
  • low bandwidth where it is stateless you can decide the execution interval.
  • etc.
The setup is simple your server should have internet access and the device where you issue the commands should have internet access but an end-to-end connection is not required. You will record your command in a document in google drive and the server will read the command execute it and update the results in the same document. 

,--------,         ,---------,           ,--------,
|        |         | google  |           |        |
| server |<------->| drive   |<--------->| device |
|        |         |         |           |        |
‘--------’         ‘---------’           ‘--------’

Implementation

1. Create a document in google drive called terminal 

2. Download gdrive and copy it to /usr/bin/gdrive and make it executable.

$ sudo chmod +x /usr/bin/gdrive 

3 Authenticate the user where the commands going to be executed.

You will can execute a command line 'gdrive list' so it will provide a url where you can copy paste in the web browser and get a verification code. That code should be pasted so the gdrive will be able access your google drive documents afterward. 

$ gdrive list
Authentication needed
Go to the following url in your browser:
https://accounts.google.com/o/oauth2/auth?access_type=...

Enter verification code: 4/6EGPmw3...

4. Create a script in your home directory with following code called gshell.sh

#!/bin/bash
cd $HOME
DOCID=16etAnUd3HfzA9BL_... 
gdrive export --force --mime text/plain $DOCID >& /dev/null
FILE=terminal.txt
OUT=gsout
ERR=gserr
:> $OUT
:> $ERR
RUN=$( tail -1 $FILE | tr -d '\r\357\273\277' )
if [[ $RUN == 'RUN' ]]
then
   echo >> $FILE
   CMD=$(tail -2 $FILE | head -1 | tr -d '\r\357\273\277')

   #check if the command still running
   CMDSUM=$( echo $CMD | md5sum | awk '{print $1}')
   if [[ ! -f $CMDSUM ]]
   then
      echo $CMD > $CMDSUM
      bash $CMDSUM > $OUT 2> $ERR
      rm $CMDSUM
      cat $OUT >> $FILE

      #if returns nothing, ech OK
      if [[ ! -s $OUT ]]
      then
         echo '-OK-' >> $FILE
      fi


      #return errors if exists
      if [[ -s $ERR ]]
      then
         echo '-ERR-' >> $FILE
         cat $ERR >> $FILE
      fi
   fi

   #write back the details
   gdrive update --name terminal $DOCID $FILE  >& /dev/null
fi

5. Run 'gdirve list' and get the 'document id' and change the gshell.sh script accordingly.

6. Add a cron job where this script will be execute as the given user in each 1m.

$ sudo vim /etc/cron.d/gshell 

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user    command
*/1 * * * * <username>  /home/<username>/gshell.sh >& /dev/null

7. That's it now you can issue your command through google drive

After you complete your command you have to type 'RUN' in order to execute the command you entered above. With this simple script only the last adjacent line of 'RUN' will be executed.
The output will be followed after the 'RUN' statement as given below.
You can keep issuing commands further down and grow the file or you can delete the content and insert command in clean file.
Hope this will be helpful to you...

Intel Corporation XMM7360 LTE Advanced Modem in ArchLinux

The required packages are available in ArchLinux User Repository (AUR) so it will be easier if you can use an AUR helper package like yay . ...