Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Design and Concept of Operations

Manual Setup

  • Generate rsa public/private key pairs (id_rsa/ and set up on target machine
  • ssh-keygen -t rsa -C "your-email@server" - generates id_rsa and (in designated directory with password)
  • scp to target machine
  • On target machine in "user" account:
  • mkdir ~/.ssh
  • mv ~/.ssh
  • cd ~/.ssh
  • cat > authorized_keys
  • chmod 400 authorized_keys
  • rm
  • cd ..
  • chmod 700 .ssh
  • test from local machine: ssh -i id_rsa user@remote-machine (prompts for private key password, not remote login password)


  • Default config under $USER_HOME/.exsiter/application.conf
  • Note: application.conf, id_rsa and permissions should be chmod 400 (only readable by user)!

Required Settings

  • privateKeyLocation - id_rsa private key ( must set up as .ssh/authorized_keys on target machine)
  • privateKeyPassphrase - password for id_rsa private key
  • knownHostsLocation - must contain target machine (log in to target via ssh, could point to $USER_HOME/.ssh/known_hosts)
  • username - username for target machine
  • hostname - full host name of target machine
  • backupRootDir - absolute path to the root of the backup directory
  • contains exsiter-backup dir which is the git repo maintaining

Optional Settings

Mail Report settings

  • smtp.username - name used to log in to mail provider (for example, If not provided, email will be disabled.
  • smtp.password - password for user at mail provider
  • mail.smtp.auth - set to true to enable auth (e.g. true for GMail)
  • mail.smtp.starttls.enable - set to true to enable tls (e.g. true for GMail)
  • - host name of mail provider (e.g. GMail uses
  • mail.smtp.port - port used for provider (e.g. GMail uses 587)
  • smtp.sender - for example,
  • smtp.recipients - comma-separated list of all recipients (,

Using Java-based cron via Quartz

Must run org.medale.exsiter.ExsiterScheduler

  • backupCronFrequency - cron expression for frequency of backups
  • sec min hrs day-of-month month day-of-week optYear
  • JAN-DEC (1-12), SUN-SAT(1-7), * all values, ? unspec day, L last
  • Example 10 o'clock last Friday of month: 0 0 10 ? * 6L
  • For details see Quartz CronExpression API, e.g.

Concept of Operations

  • Run Exsiter Main class as cron job: java -jar exister.jar (Main is default main in manifest)
  • Loads default configuration from $USER_HOME/.exsiter/application.conf


  • Currently Exsiter doesn't do the initial download using bulk. Running Exister backup would download individual files one by one, which would be very timeconsuming/expensive.
  • Therefore manually download initial bulk files via scp -r $user@remote-machine:~/remote-dir (e.g. remote-dir = web) .
  • Note: Beware of symlinks to avoid duplicate downloads. Typically download whole web directory, let Exsiter pick up small files.

Hash local repository and remote backup sites

  • Create local md5/file pair hashes in $backupRootDir/exsiter-backup/localFileNameToMd5Map.csv
  • Get remote md5/file pair hashes SshShellCommandExecutor.LIST_ALL_FILES_AND_THEIR_CHECKSUMS
  • Executes find . -type f | xargs md5sum
  • Returns listing of all files as pairs: 56a329926a92460b9b6ac1377f610e48 ./web/newsletter/grip-it.jpg
  • Parse into FileLocationMd5Pair to create Map<String, String> fileWithPath to its MD5 hash sum in hex
  • Store in $backupRootDir/exsiter-backup/remoteFileNameToMd5Map.csv file

Compare local and remote hashes

  • Do comparison of localFileNameToMd5Map.csv and remoteFileNameToMd5Map.csv
  • Iterates through all entries in the remote map
  • If filename/md5 hash are unchanged against local map, do nothing
  • If filename did not exist in local version or had a different md5 hash (file was updated)
  • Download new/updated file via ScpTool
  • Add downloaded file under $backupRootDir/exsiter-backup/remote-content-dir with correct file path and name
  • Iterates through diff of keys (file names) that were in the local map but not the remote (deleted files on target)
  • Delete corresponding file under remote-content-dir

Perform git add/commit/tag

  • Execute logical "git add -u $gitDir/exsiter-backup/" to add all the new/deleted files
  • Execute git commit
  • Execute git tag "v" + yyyyMMMdd to make rollback easy (if backup gets called multiple times add -1,-2, etc.)

Create HTML Report


TODO and Future Enhancements

  • Automate initial manual setup
  • Execute search through current $gitDir/exsiter-backup/target-web-dir/ for suspicious content and flag those files
  • Download and analyze logs for suspicious content (big files!)

Integration Test

Set up local user/fake directories. Use $USER_HOME/.exsiter/test/test-application.conf to contain test key/password.

Note: Ubuntu openssh server config at /etc/ssh/sshd_config had the following line, which must be commented out to make JSch work !#HostKey /etc/ssh/ssh_host_ecdsa_key

Do a local login via ssh localhost and then copy .ssh/known_hosts to $USER_HOME/.exsiter/test/known_hosts


  • org.medale.exsiter.Main - main entry point with two different types of functionality
  • init - brand-new Exsiter setup. Downloads target files for the first time to initialize local repository
  • backup - incremental backup against existing local repository
  • Either function can be run in test mode
  • org.medale.exsiter.ExsiterScheduler - main entry point for running Quartz scheduler, which calls main backup


No description, website, or topics provided.



No releases published


No packages published