├── hooks_overlay ├── install-experimental.sh ├── README.md └── init-bottom_overlay /hooks_overlay: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # based on https://gist.github.com/mutability/6cc944bde1cf4f61908e316befd42bc4 3 | 4 | PREREQ="" 5 | prereqs() 6 | { 7 | echo "$PREREQ" 8 | } 9 | 10 | case $1 in 11 | prereqs) 12 | prereqs 13 | exit 0 14 | ;; 15 | esac 16 | 17 | . /usr/share/initramfs-tools/hook-functions 18 | manual_add_modules overlay 19 | -------------------------------------------------------------------------------- /install-experimental.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ERR='\033[0;31m' 4 | INFO='\033[0;32m' 5 | NC='\033[0m' # No Color 6 | 7 | if [ $EUID -ne 0 ]; then 8 | echo -e "ERROR: This script should be run as root" 1>&2 9 | exit 1 10 | fi 11 | 12 | KERNEL=$(uname -r) 13 | 14 | VERSION=$(echo $KERNEL | cut -d. -f1) 15 | PATCHLEVEL=$(echo $KERNEL | cut -d. -f2) 16 | SUBLEVEL=$(echo $KERNEL | cut -d. -f3 | cut -d- -f1) 17 | 18 | KERNELVER=$(($VERSION*100000+1000*$PATCHLEVEL+$SUBLEVEL)); 19 | 20 | if [ $KERNELVER -le 409040 ]; then 21 | echo "$ERR WARNING: kernel version not supported. >4.9.40 required $NC" 1>&2 22 | exit 0 23 | fi 24 | 25 | if (cat /etc/issue | grep -v Raspbian) then 26 | echo -e "$ERR ERROR: This script is only compatible with Raspbian Linux. $NC" 1>&2 27 | exit 1 28 | fi 29 | 30 | clear 31 | WELCOME="This script activates read-only filesystem overlay\n 32 | continue installation?" 33 | 34 | if (whiptail --title "Read-only Filesystem Installation Script" --yesno "$WELCOME" 20 60) then 35 | echo "" 36 | else 37 | exit 0 38 | fi 39 | 40 | sed -i '1 s/^/overlay=yes /' /boot/cmdline.txt 41 | 42 | wget -nv https://raw.githubusercontent.com/janztec/empc-arpi-linux-readonly/master/hooks_overlay -O /etc/initramfs-tools/hooks/overlay 43 | wget -nv https://raw.githubusercontent.com/janztec/empc-arpi-linux-readonly/master/init-bottom_overlay -O /etc/initramfs-tools/scripts/init-bottom/overlay 44 | 45 | chmod +x /etc/initramfs-tools/hooks/overlay 46 | chmod +x /etc/initramfs-tools/scripts/init-bottom/overlay 47 | 48 | mkinitramfs -o /boot/initramfs.gz 49 | echo "initramfs initramfs.gz followkernel" >>/boot/config.txt 50 | 51 | if (whiptail --title "Read-only Filesystem Installation Script" --yesno "Installation completed! reboot required\n\nreboot now?" 12 60) then 52 | reboot 53 | fi 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Protect your Raspberry Pi µSD card (use read-only filesystem) 2 | ============================================================= 3 | 4 | **WARNING!! EXPERIMENTAL SETTINGS: create a backup copy of your µSD card before applying these settings!** 5 | 6 | * makes filesystem read only to prevent filesystem corruption after power fail 7 | * writes to µSD card are redirected to overlay filesystem in RAM 8 | 9 | Prerequisites: 10 | * Raspbian Stretch with Desktop (2017-09-07) 11 | * Raspbian Stretch Lite (2017-09-07) 12 | 13 | scripts based on: https://gist.github.com/mutability/6cc944bde1cf4f61908e316befd42bc4 14 | 15 | Make Filesystem Read-Only 16 | ========================= 17 | 18 | **Disable SWAP** 19 | ``` 20 | sudo dphys-swapfile swapoff 21 | sudo systemctl disable dphys-swapfile 22 | sudo apt-get purge dphys-swapfile 23 | ``` 24 | 25 | **Disable man indexing** 26 | ``` 27 | sudo chmod -x /etc/cron.daily/man-db 28 | sudo chmod -x /etc/cron.weekly/man-db 29 | ``` 30 | 31 | **Move /var/log to tmpfs** 32 | 33 | Append to file /etc/fstab 34 | 35 | _tmpfs /var/log tmpfs size=70M 0 0_ 36 | ``` 37 | sudo nano /etc/fstab 38 | ``` 39 | 40 | 41 | **Disable unwanted log files** 42 | ``` 43 | sudo nano /etc/rsyslog.conf 44 | ``` 45 | 46 | **Install script** 47 | ``` 48 | cd /tmp 49 | wget https://raw.githubusercontent.com/janztec/empc-arpi-linux-readonly/master/install-experimental.sh -O install-experimental.sh 50 | pi@raspberrypi:/tmp $ sudo bash install-experimental.sh 51 | ``` 52 | 53 | 54 | Check Status 55 | ------------- 56 | 57 | * Read only mode is enabled 58 | ``` 59 | pi@raspberrypi:/home/pi $ sudo df 60 | Filesystem 1K-blocks Used Available Use% Mounted on 61 | ... 62 | /dev/mmcblk0p2 15205520 4309620 10215392 30% /ro 63 | overlay-rw 262144 115108 147036 44% /rw 64 | ... 65 | ``` 66 | 67 | 68 | Make Filesystem Read-Write Again 69 | ================================ 70 | 71 | * sudo nano /boot/cmdline.txt 72 | * change *overlay=yes* to *overlay=no* 73 | * Ctrl+o and Ctrl+x 74 | * sudo reboot 75 | 76 | 77 | Check Status 78 | ------------- 79 | 80 | * Read only mode is disabled 81 | ``` 82 | pi@raspberrypi:/home/pi $ sudo df 83 | Filesystem 1K-blocks Used Available Use% Mounted on 84 | /dev/mmcblk0p2 15205520 4309756 10215256 30% / 85 | ``` 86 | -------------------------------------------------------------------------------- /init-bottom_overlay: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # based on https://gist.github.com/mutability/6cc944bde1cf4f61908e316befd42bc4 3 | # goes in /etc/initramfs-tools/scripts/init-bottom/overlay 4 | 5 | PREREQ="" 6 | prereqs() 7 | { 8 | echo "$PREREQ" 9 | } 10 | 11 | case $1 in 12 | prereqs) 13 | prereqs 14 | exit 0 15 | ;; 16 | esac 17 | 18 | . /scripts/functions 19 | 20 | RW_SIZE=256m 21 | 22 | # Should we run at all? 23 | 24 | OVERLAY="no" 25 | for arg in $(cat /proc/cmdline) 26 | do 27 | case "$arg" in 28 | overlay=*) 29 | OVERLAY=${arg#overlay=} 30 | ;; 31 | *) 32 | ;; 33 | esac 34 | done 35 | 36 | if [ "$OVERLAY" != "yes" ] 37 | then 38 | log_warning_msg "overlay not enabled, leaving the root fs alone" 39 | exit 0 40 | fi 41 | 42 | log_begin_msg "Remounting root fs in overlay mode" 43 | 44 | if ! modprobe -qb overlay 45 | then 46 | log_failure_msg "can't load overlay module" 47 | exit 0 48 | fi 49 | 50 | # initially we have: 51 | 52 | # / initramfs 53 | # ${rootmnt} readonly-mounted real root FS (mounted from device ${ROOT}) 54 | # 55 | # We want: 56 | # 57 | # / initramfs 58 | # ${rootmnt} overlayfs using ${rootmnt}/ro and ${rootmnt}/rw 59 | # ${rootmnt}/ro readonly-mounted real root FS (mounted from device ${ROOT}) 60 | # ${rootmnt}/rw tmpfs that will be used for changes 61 | # ${rootmnt}/rw/upper overlayfs upper dir 62 | # ${rootmnt}/rw/work overlayfs work dir 63 | # 64 | 65 | # create and mount /ro and /rw on the initramfs, we will move them later 66 | for dir in /ro /rw 67 | do 68 | [ -d "${dir}" ] || mkdir -p "${dir}" 69 | if [ $? -ne 0 ] 70 | then 71 | log_failure_msg "can't create ${dir}" 72 | exit 0 73 | fi 74 | done 75 | 76 | # set up /rw 77 | if ! mount -t tmpfs -o "size=${RW_SIZE}" overlay-rw /rw 78 | then 79 | log_failure_msg "can't mount tmpfs on /rw" 80 | exit 0 81 | fi 82 | 83 | for dir in /rw/upper /rw/work 84 | do 85 | if ! mkdir -p ${dir} 86 | then 87 | log_failure_msg "overlay: can't create ${dir}" 88 | exit 0 89 | fi 90 | done 91 | 92 | # set up /ro 93 | if ! mount -o move "${rootmnt}" /ro 94 | then 95 | log_failure_msg "can't move root fs to /ro" 96 | exit 0 97 | fi 98 | 99 | # set up an overlayfs on rootmnt 100 | if ! mount -t overlay -o lowerdir=/ro,upperdir=/rw/upper,workdir=/rw/work overlay-root "${rootmnt}" 101 | then 102 | log_failure_msg "can't move root fs to /ro" 103 | 104 | # try to recover 105 | if ! mount -o move /ro "${rootmnt}" 106 | then 107 | panic "recovering the old root fs failed, panicking" 108 | exit 0 109 | fi 110 | 111 | log_warning_msg "overlay: moved regular rootfs back into place and continuing" 112 | exit 0 113 | fi 114 | 115 | for dir in "${rootmnt}/ro" "${rootmnt}/rw" 116 | do 117 | [ -d "${dir}" ] || mkdir -p "${dir}" 118 | if [ $? -ne 0 ] 119 | then 120 | log_failure_msg "can't create ${dir}" 121 | exit 0 122 | fi 123 | done 124 | 125 | # move /ro and /rw into place so we can access them later 126 | if ! mount -o move /ro "${rootmnt}/ro" 127 | then 128 | log_failure_msg "can't move /ro to ${rootmnt}/ro" 129 | exit 0 130 | fi 131 | 132 | if ! mount -o move /rw "${rootmnt}/rw" 133 | then 134 | log_failure_msg "can't move /rw to ${rootmnt}/rw" 135 | exit 0 136 | fi 137 | 138 | # populate fstab on the new root 139 | 140 | { 141 | cat <"${rootmnt}/etc/fstab" 174 | 175 | log_end_msg 176 | exit 0 177 | --------------------------------------------------------------------------------