commit b13bf72db23d707f10fbb0b8577af9618674348d Author: tastytea Date: Fri Jun 5 14:04:44 2015 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a126b31 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.sublime-* diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a84f500 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,11 @@ +* 2015-06-05 tastytea + Version 0.3 + Recovery +* 2015-06-03 tastytea + Version 0.2 + Debian initscript (SysV-style) + Gentoo initscript (openrc) + Backup in /var/cache/bootbackup.tar.gz +* 2015-06-03 tastytea + Version 0.1 + Usable skript \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8722cf0 --- /dev/null +++ b/INSTALL @@ -0,0 +1,3 @@ +* Make sure you have sha*sum or md5sum installed +* Make hashboot.sh executable +* Place hashboot.sh where it's needed \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..ee35311 --- /dev/null +++ b/README @@ -0,0 +1,8 @@ +For build instruction see INSTALL. + +Run "hashboot.sh index" to generate checksums for /boot +Run "hashboot.sh check" to check /boot + +A backup is stored in /var/cache/bootbackup.tar.gz + +Detailed documentation is in the sourcecode. \ No newline at end of file diff --git a/TODO b/TODO new file mode 100644 index 0000000..2728d06 --- /dev/null +++ b/TODO @@ -0,0 +1,6 @@ +* SysV-style init scripts +* Systemd init script +* Gentoo ebuild +* Debian package +* Ubuntu package +* recovery \ No newline at end of file diff --git a/hashboot.sh b/hashboot.sh new file mode 100755 index 0000000..802256b --- /dev/null +++ b/hashboot.sh @@ -0,0 +1,88 @@ +#!/bin/sh +#Hashes all files in /boot to check them during early boot +#Exit codes: 0 = success, 1 = wrong usage, 2 = not root, 3 = no hasher found, 4 = checksum mismatch + +VERSION="0.3" +DIGEST_FILE="/var/lib/hashboot.digest" +LOG_FILE="/tmp/hashboot.log" +BACKUP_FILE="/var/cache/boot-backup.tar.gz" +HASHER="" +BOOT_MOUNTED="" + + +#Umount /boot if we mounted it, exit with given exit code +function die +{ + if [ ! -z ${BOOT_MOUNTED} ] + then + umount /boot + fi + + exit ${1} +} + +#If we're not root: exit +if [ ${UID} -ne 0 ] +then + echo "You have to be root" >&2 + die 2 +fi + +#Try different hashers, use the most secure +HASHER=$(/usr/bin/which --skip-dot --skip-tilde sha512sum 2> /dev/null) +test -z ${HASHER} && $(/usr/bin/which --skip-dot --skip-tilde sha384sum 2> /dev/null) +test -z ${HASHER} && $(/usr/bin/which --skip-dot --skip-tilde sha256sum 2> /dev/null) +test -z ${HASHER} && $(/usr/bin/which --skip-dot --skip-tilde sha224sum 2> /dev/null) +#It gets insecure below here, but better than nothing? +test -z ${HASHER} && $(/usr/bin/which --skip-dot --skip-tilde sha1sum 2> /dev/null) +test -z ${HASHER} && $(/usr/bin/which --skip-dot --skip-tilde md5sum 2> /dev/null) + +#If we found no hasher: exit +if [ -z ${HASHER} ] +then + echo "No hash calculator found" >&2 + die 3 +fi + +#If /boot is in fstab but not mounted: mount, mark as mounted +if grep -q '/boot.*noauto' /etc/fstab && ! grep -q /boot /etc/mtab +then + mount /boot + BOOT_MOUNTED=1 +fi + +if [ "${1}" == "index" ] +then + #Write header + echo "#hashboot ${VERSION} - Algorithm: $(basename ${HASHER})" > ${DIGEST_FILE} + #Write hashes of all regular files to ${DIGEST_FILE} + find /boot -type f -exec ${HASHER} --binary {} >> ${DIGEST_FILE} + + #Backup of good files + tar -czpPf ${BACKUP_FILE} /boot + die 0 +elif [ "${1}" == "check" ] +then + if $(${HASHER} --check --warn --quiet --strict ${DIGEST_FILE} > ${LOG_FILE}) + then + die 0 + else + echo " !! TIME TO PANIK: A FILE WAS MODIFIED !!" + echo "Restoring files from backup... (type yes or no for each file)" + #For each failed file: ask if it should be recovered from backup + for file in $(cut -d: -f1 ${LOG_FILE}) + do + tar -xzpPvwf ${BACKUP_FILE} ${file} + done + + echo "Type reboot to reboot now, otherwise you get a shell" + read -r reboot + if [ ${reboot} == "reboot" ] + then + reboot + fi + die 4 + fi +else + echo "Usage: ${0} index|check" >&2 + die 1 +fi \ No newline at end of file diff --git a/initscript.debian b/initscript.debian new file mode 100755 index 0000000..6e4ea6a --- /dev/null +++ b/initscript.debian @@ -0,0 +1,44 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: hashboot +# Required-Start: $mountall +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Check integrity of files in /boot +### END INIT INFO + +PATH=/sbin:/bin:/usr/bin + +# See if hashboot.sh is accessible +test -x $(which hashboot.sh) || exit 0 + +case "$1" in + start) + log_daemon_msg "Checking integrity of files in /boot" + + if ! hashboot.sh check + then + log_end_msg 1 + sh + exit 1 + fi + + log_end_msg 0 + ;; + stop) + # No-op + + ;; + restart|reload|force-reload|status) + echo "Error: argument '$1' not supported" >&2 + exit 2 + ;; + *) + echo "Usage: /etc/init.d/hashboot {start|stop}" + exit 2 + ;; +esac + +exit 0 diff --git a/initscript.gentoo b/initscript.gentoo new file mode 100755 index 0000000..13d5f5b --- /dev/null +++ b/initscript.gentoo @@ -0,0 +1,24 @@ +#!/sbin/runscript + +description="Check integrity of files in /boot" + +depend() +{ + need localmount +} + +start() +{ + ebegin "Checking integrity of files in /boot" + + # See if hashboot.sh is accessible + which hashboot.sh > /dev/null || return 1 + + if ! hashboot.sh check + then + sh + return 2 + fi + + eend 0 +} \ No newline at end of file