Penguin Crumbs

Notes and tips from a Linux user

home about this blog
search:  

Your personal file hosting service in few lines of code

Ok, let’s say you have a personal server, always on, connected to the internet, with a public IP or always reachable using any dynamic DNS service. Let’s also say that for some reason you don’t want to use anymore a well known cloud storage, e.g. Dropbox, or Google Drive, or Microsoft OneDrive,....

Well, if you need just a simple, light, secure and personal backup service, without multi-user sharing features, rsync is exactly what you need. This solution is secure because you can send data using ssh, light because its synchronization algorithm is very efficient, simple because it needs just few lines of code and personal, allowing you to avoid to rely on an external service: your data will be stored in your server.

The bash script. The core is the rsync command and it’s executed twice: the first run is for simulating the backup process: this can produce file deletion too and that’s why it’simportant to simulate first. The script acts on an entire directory: if it isn’t passed as an argument, it will ask the user. The ssh password is asked just one time and then it’s handled in memory (ok, it’s not the top of the security, anyway it just works on a humble desktop).

#!/bin/bash

# configure here your remote backup server
readonly REMOTE_SERVER="192.168.1.8" # name or IP
readonly REMOTE_PORT="21743" # port
readonly REMOTE_USER="bck_user" # user on the server
readonly REMOTE_DIR="/home/bck_user/BACKUP" # backup dir

# echoes with time
function echo_log() {
    echo "$(date +%H:%M:%S) - $1"
}

# checks for missing commands
if "$(which sshpass)" == "" -o \
    "$(which rsync)" == "" -o \
    "$(which ssh)" == "" ]; then
    echo "this script needs ssh, sshpass and rsync; exit"
    exit 1
fi

# get the directory name
source_dir=""
if "$1" != "" ]; then
    source_dir="$1"
else
    read -p "souce dir? " source_dir
fi
if "$source_dir" == "" ]; then
    echo "no dir, no sync; exit"
    exit 2
fi
if "${source_dir:(-1)}" == "/" ]; then
    # strip slash at the end
    source_dir=${source_dir::-1}
fi
if [ ! -d "$source_dir" ]; then
    echo "dir does not exist; exit"
    exit 3
fi

# asks for ssh password
echo -n "remote password for $REMOTE_SERVER: "
read -s sshpasswordecho

repeat="y"
while "$repeat" == "y" -o "$repeat" == "Y" ]; do
    echo_log "SIMULATION - start"
    rsync -aze "sshpass -p $sshpassword ssh -p $REMOTE_PORT" \
        --progress --dry-run --delete-after "$source_dir" \
        ${REMOTE_USER}@${REMOTE_SERVER}:${REMOTE_DIR}
    status=$?
    if "$status" -ne ]; then
        echo "connection failed; check network, password,..."
        exit 4
    fi
    echo_log "SIMULATION - end"

    echo
    read -p "Proceed (y/n)? " answer
    echo
    if "$answer" == "y" -o "$answer" == "Y" ]; then
        echo_log "SYNCH - start"
        rsync -aze "sshpass -p $sshpassword ssh -p $REMOTE_PORT" \
        --progress --delete-after "$source_dir" \
        ${REMOTE_USER}@${REMOTE_SERVER}:${REMOTE_DIR}
        echo_log "SYNCH - end"
    else
        echo "no action"
    fi
    echo
    read -p "Repeat (y/n)? " repeat
    echo
done

...now just leave it running on a terminal and launch the synchronization when needed.

 
 
Posted on 2019-05-19  
 
⇦  back
 
__________________
 
Copyright © 2019 Marcello Zaniboni