Hosting several webpages for someone else means not even to be responsible for their accessibility or to do regular backups. It means to make sure, that measures are in place to detect changes to the code of the webpages itself. Especially if you are using solutions like WordPress or phpBB, the code stays static as long as you don’t apply an update on your own.

So why should you monitor such changes? Because it can be used as an indicator to detect a successful hacking attack against these webpages.

After struggling with some other tools/scripts, I decided to write my own script which fits my needs more.

In the next few weeks, I will extend this script collection and release it to the public, as soon as it seems to be stable enough for daily use.


The following list is far from being complete and more things will be added during the next releases:

  • Documentation
  • Checks have to be done remotely to ensure that the check script itself is not tampered
  • New, Changed and Deleted files must be detected
  • File Hash History
  • Ignoring of files, folders or file types
  • Using sha512 instead of sha1 or md5 (maybe as option to change it to something else)
  • Using sqlite3 for storage of results
  • Python 3 as coding language
  • Export to XML
  • syslog support
  • Re-entrant
  • SCP Support
  • SFTP Support

The following bullet points should be seen as “maybe… maybe not” features:

  • Icinga / Nagios Support
  • Sending alerting mails
  • Defining of thresholds / triggers
  • Backup of downloaded files for archiving them
  • Remote MySQL consistency checks
  • Bug free ;-)


The script supports several options, which are listed below:

./ v0.1 by
Integrity check of a webserver, using ftp, checksums and sqlite


 Database related options:
 (-c) --create specify input SQL file to create SQLite DB
 (-d) --database specify output SQLite DB file
 (-a) --action update/compare
 FTP related options:
 (-u) --user ftp user for connect
 (-p) --path ftp path to start from
 Other options:
 (-h) --help this message
 (-v) --verbose verbose output
 (-V) --version output version number and exit

If you are wondering why there is no option for entering the password…

ATM the password has to be entered interactively to prevent storing it in files.


The first step is to generate an empty sqlite3 database file.

This can be achieved using the following command:

./ -c  mywebpage.db

Next is to initially fill the database with the “known good hashes” of your webpage:

./ -d mywebpage.db -a update -u ftpuser -p / ftpserver.tld

Now we are ready to compare the stored hashes against the page itself:

./ -d mywebpage.db -a compare -u ftpuser -p / ftpserver.tld

If there are differences between the stored hashes, or files have been added or deleted, you will get a console output like that:


In one of the next releases, this behavior will change to a dedicated result log. I am even thinking about a separated script for analyzing different runs over a longer period of time.


The sqlite3 database is flat and simple at the moment. More will be added in the next releases.

 checksum VARCHAR (1024),
 last_update TIMESTAMP


This scripts will not help you in detecting a successful hacking attempt when the ftp server itself is sending you the unchanged files during the webserver is using the modified ones. If the server itself has been hacked, other detection and mitigation processes have to be in place.

On top of that, if the initial fill of the database has been done using tampered data, you will never get what this script should deliver ;-)


This script is far from “THE solution for your problem”. It is something I wanted to have for my own needs. It is far from perfect and there are more similar scripts which may be better or more mature than this one. You are definitely using it on your own risk. Whatever you do, never ever thrust a script without understanding what it will do if started.


The script itself is not working good enough to be published. Give me some more days to get rid of some bugs, implement more features and write more documentation.