Skip to content

Instantly share code, notes, and snippets.

@adam-weber
Created August 5, 2019 16:21
Show Gist options
  • Save adam-weber/bad054e1abb870669b3d86166ef7205f to your computer and use it in GitHub Desktop.
Save adam-weber/bad054e1abb870669b3d86166ef7205f to your computer and use it in GitHub Desktop.
#!/bin/bash
# Adapted from this Adafruit script:
# https://learn.adafruit.com/read-only-raspberry-pi/
#
# The scripts for the above commands are in /bin/read_remount*
#
# The kernel panic watchdog is specifically for the bcm2835, found on RPi A, B, B+, CM, 0
#
# Options:
# INSTALL_RW_JUMPER = skipped if 0, adding a GPIO number will disable read only if bridged
# INSTALL_WATCHDOG = enables a kernal panic watchdog that will restart the Pi
# INSTALL_ALIAS = adds aliases to /home/pi/.bash_aliases to quickly re/mount the filesystem
#
# Aliases:
# fs_r = change file system to read only
# fs_rw = change file system to read/write
# Options
# INSTALL_RW_JUMPER=12
INSTALL_WATCHDOG=1
INSTALL_ALIAS=1
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
echo "Try 'sudo bash $0'"
exit 1
fi
clear
# Given a filename, a regex pattern to match and a replacement string:
# Replace string if found, else no change.
# (# $1 = filename, $2 = pattern to match, $3 = replacement)
replace() {
grep $2 $1 >/dev/null
if [ $? -eq 0 ]; then
# Pattern found; replace in file
sed -i "s/$2/$3/g" $1 >/dev/null
fi
}
# Given a filename, a regex pattern to match and a replacement string:
# If found, perform replacement, else append file w/replacement on new line.
replaceAppend() {
grep $2 $1 >/dev/null
if [ $? -eq 0 ]; then
# Pattern found; replace in file
sed -i "s/$2/$3/g" $1 >/dev/null
else
# Not found; append on new line (silently)
echo $3 | sudo tee -a $1 >/dev/null
fi
}
# Given a filename, a regex pattern to match and a string:
# If found, no change, else append file with string on new line.
append1() {
grep $2 $1 >/dev/null
if [ $? -ne 0 ]; then
# Not found; append on new line (silently)
echo $3 | sudo tee -a $1 >/dev/null
fi
}
# Given a filename, a regex pattern to match and a string:
# If found, no change, else append space + string to last line --
# this is used for the single-line /boot/cmdline.txt file.
append2() {
grep $2 $1 >/dev/null
if [ $? -ne 0 ]; then
# Not found; insert in file before EOF
sed -i "s/\'/ $3/g" $1 >/dev/null
fi
}
echo
echo "Starting installation..."
echo "Updating package index files..."
apt-get update
echo "Removing unwanted packages..."
# apt-get remove -y --force-yes --purge triggerhappy logrotate dbus \
# dphys-swapfile xserver-common lightdm fake-hwclock
# Let's keep dbus...that includes avahi-daemon, a la 'raspberrypi.local',
# also keeping xserver & lightdm for GUI login (WIP, not working yet)
apt-get remove -y --force-yes --purge triggerhappy logrotate \
dphys-swapfile fake-hwclock
apt-get -y --force-yes autoremove --purge
# Replace log management with busybox (use logread if needed)
echo "Installing ntp and busybox-syslogd..."
apt-get -y --force-yes install ntp busybox-syslogd; dpkg --purge rsyslog
echo "Configuring system..."
# Install boot-time R/W jumper test if requested
# if [ $INSTALL_RW_JUMPER -ne 0 ]; then
# GPIOTEST="gpio -g mode $INSTALL_RW_JUMPER up\n\
# if [ \`gpio -g read $INSTALL_RW_JUMPER\` -eq 0 ] ; then\n\
# \tmount -o remount,rw \/\n\
# \tmount -o remount,rw \/boot\n\
# fi\n"
# apt-get install -y --force-yes wiringpi
# # Check if already present in rc.local:
# grep "gpio -g read" /etc/rc.local >/dev/null
# if [ $? -eq 0 ]; then
# # Already there, but make sure pin is correct:
# sed -i "s/^.*gpio\ -g\ read.*$/$GPIOTEST/g" /etc/rc.local >/dev/null
# else
# # Not there, insert before final 'exit 0'
# sed -i "s/^exit 0/$GPIOTEST\\nexit 0/g" /etc/rc.local >/dev/null
# fi
# fi
# Install watchdog if requested
if [ $INSTALL_WATCHDOG -ne 0 ]; then
apt-get install -y --force-yes watchdog
# $MODULE is specific watchdog module name
MODULE="bcm2708_wdog"
# Add to /etc/modules, update watchdog config file
append1 /etc/modules $MODULE $MODULE
replace /etc/watchdog.conf "#watchdog-device" "watchdog-device"
replace /etc/watchdog.conf "#max-load-1" "max-load-1"
# Start watchdog at system start and start right away
# Raspbian Stretch needs this package installed first
apt-get install -y --force-yes insserv
insserv watchdog; /etc/init.d/watchdog start
# Additional settings needed on Jessie
append1 /lib/systemd/system/watchdog.service "WantedBy" "WantedBy=multi-user.target"
systemctl enable watchdog
# Set up automatic reboot in sysctl.conf
replaceAppend /etc/sysctl.conf "^.*kernel.panic.*$" "kernel.panic = 10"
fi
# Write the alias' to bash profile
if [ $INSTALL_ALIAS -ne 0 ]; then
ALIAS="alias fs_r='sudo bash /bin/remount_readonly'\n\
alias fs_rw='sudo bash /bin/remount_readwrite'"
echo -e $ALIAS > /home/pi/.bash_aliases
fi
# Add scripts
RW_SCRIPT="#!/bin/sh\n\
mount -o remount,rw /"
echo -e $RW_SCRIPT > /bin/remount_readwrite
# Create read script
READ_SCRIPT="#!/bin/sh\n\
mount -o remount,ro /"
echo -e $READ_SCRIPT > /bin/remount_readonly
# Change permissions of scripts
chmod +x /bin/remount_read*
# Add fastboot, noswap and/or ro to end of /boot/cmdline.txt
append2 /boot/cmdline.txt fastboot fastboot
append2 /boot/cmdline.txt noswap noswap
append2 /boot/cmdline.txt ro^o^t ro
# Move /var/spool to /tmp
rm -rf /var/spool
ln -s /tmp /var/spool
# Move /var/lib/lightdm and /var/cache/lightdm to /tmp
rm -rf /var/lib/lightdm
rm -rf /var/cache/lightdm
ln -s /tmp /var/lib/lightdm
ln -s /tmp /var/cache/lightdm
# Make SSH work
replaceAppend /etc/ssh/sshd_config "^.*UsePrivilegeSeparation.*$" "UsePrivilegeSeparation no"
# Change spool permissions in var.conf (rondie/Margaret fix)
replace /usr/lib/tmpfiles.d/var.conf "spool\s*0755" "spool 1777"
# Move dhcpd.resolv.conf to tmpfs
touch /tmp/dhcpcd.resolv.conf
rm /etc/resolv.conf
ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
# Make edits to fstab
# make / ro
# tmpfs /var/log tmpfs nodev,nosuid 0 0
# tmpfs /var/tmp tmpfs nodev,nosuid 0 0
# tmpfs /tmp tmpfs nodev,nosuid 0 0
replace /etc/fstab "vfat\s*defaults\s" "vfat defaults,ro "
replace /etc/fstab "ext4\s*defaults,noatime\s" "ext4 defaults,noatime,ro "
append1 /etc/fstab "/var/log" "tmpfs /var/log tmpfs nodev,nosuid 0 0"
append1 /etc/fstab "/var/tmp" "tmpfs /var/tmp tmpfs nodev,nosuid 0 0"
append1 /etc/fstab "\s/tmp" "tmpfs /tmp tmpfs nodev,nosuid 0 0"
# PROMPT FOR REBOOT --------------------------------------------------------
echo "Done."
echo
echo "Settings take effect on next boot."
echo
echo -n "REBOOT NOW? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Exiting without reboot."
exit 0
fi
echo "Reboot started..."
reboot
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment