TheSin- / rpi-img-builder

Scripts to create custom images for RaspberryPi
MIT License
107 stars 30 forks source link

Add possibility of mounting all the filesystem as read-only to avoid SD corruptions as much as possible #3

Closed Paultok closed 7 years ago

Paultok commented 8 years ago

The aim is to have an optional feature to build an image with read-only filesystems , with the only exceptions of a partition dedicated to logs, because some processes might need to log stuff somewhere. the /var/log system should be a ramdisk to avoid SD writings and the size should be selectable when building the image (this might require to have syslog configured to not exceed the specified size).

Reminder: do not forget to document any new stuff, options and provide a simple example.

TheSin- commented 7 years ago

I think I FINALLY have an idea that is working on this one, it's going to take a lot more testing and it's going to be pretty fragile as it'll aha etc read from the fstab file and make a few assumptions. But it's in the works finally.

TheSin- commented 7 years ago

can you send me an example fstab of an RO build?

jjakob commented 7 years ago

From my experience, the simplest way would be to mount the rootfs as overlayfs with upper dir in tmpfs. Only mounting root as read-only requires too much fiddling with files that various programs want to write to, and would never work well with a wide array of different installed packages, as each has its own locations and files it writes to and would need moving... What works great for me is this: https://gist.github.com/sbonfert/7044eced553ea5c5c2346bcde6bb12e7 It's a script that automatically sets up the overlayfs on boot (it runs in the initramfs), and you can even disable it with a cmdline parameter, so you can still start the system in standard rw-mode when you want to modify something.

TheSin- commented 7 years ago

if you'd like I can turn that script into a plugin for you?

TheSin- commented 7 years ago

I've added this overlays as a plugin in the disabled section. I have not personally tested it yet, but I plan to, I assume at this point I'd need to have an option for a new mount point, maybe for /home or some place. But for now this should work and I like that it uses an fs file or codlin option to enable/disable it. The plugin auto makes the fs file needed to enable it, this might break other plugins that require r/w on initial boot, like resizes, sshkeys etc etc. So maybe having it enabled by default might be a poor choice. If either of you have a chance to test it before me please report back I'd be interested in hearing how it works.

jjakob commented 7 years ago

I can try making the plugin, I need it for my own project anyway. I'm not so sure that it would work the way it is implemented now, I haven't tested it, but I see two issues immediately: -the script needs to be in /etc/initramfs-tools/scripts/init-bottom/root-ro -an initramdisk must be built, cmdline.txt and config.txt changed (as per the instructions in the script itself)

I agree it is best left disabled by default, users can opt to enable it on their own. The problem with ssh keys generation could be solved by a systemd service and target that only run on first boot. (after the ssh keys are succesfully generated, deletes the disable-root-ro file and disables itself by switching back to the normal target, then rebooting) Does the ssh_check_keys.service (part of sshkeys plugin) work correctly on Raspbian? It says it may not work due to missing time.

Also, is there a way to make changes to /boot/*.txt inside the plugin scripts? I could do the changes on first boot in the same systemd service, but that seems uglier to me.

TheSin- commented 7 years ago

the plugin is made it's in the repo in the disabled folder just move it out, and test it, I just haven't had a chance at all to test it honestly.

I didn't know about the placement of the script I'll have a look at it and rework it, as for making an ignited it should be as easy as installing initramfs-tool and running it, but I"ll write all that up as soon as I can, gonna be a busy day but I'll try and get it done.

I have a few tricks but really you'd just have to delete a file in root, pretty easy to add to rc.local I could add that too.

jjakob commented 7 years ago

Well, I already started to work on it, I just got stuck at modifying cmdline and config.txt from within the plugin scripts. If I understand this correctly, I can just modify /boot from within chroot directly, as it is copied to the boot partition later after the rootfs scripts are done. If that's true then that's simpler than what I thought :)

TheSin- commented 7 years ago

I'm just about to push my changes, sorry we overlaped

TheSin- commented 7 years ago

try that and let me know please, it doesn't auto go to ro after first boot yet I need to mod a few of the other plugins first.

TheSin- commented 7 years ago

okay I just added to set to ro after all other things run code. None of this has been tested at all, I'm trying to build an image as we speak.

jjakob commented 7 years ago

Line 11 of postinst should end with > instead of >> otherwise you just add a new line without modifying the previous one. And you probably don't need ramfsfile and ramfsaddr in config.txt because initramfs initrd followkernel already specifies both. It works for me without them.

Can I ask, what are the reasons for using lsb init scripts if we already have systemd? (for backwards compatibility with distros that don't use systemd?)

TheSin- commented 7 years ago

thanks that is what happens when you do things in a hurry without testing ;)

Yeah I didn't know I just following the instructions form the file if you say it's safe I'll remove em.

mostly backwards compat and I'm still learning systemd stuff so it's just quicker for me right now till I convert everything.

TheSin- commented 7 years ago

I mean in this case I could have used systemd for sure, guess I did it for constancy till I convert some of the others.

jjakob commented 7 years ago

mkinitramfs is failing with unable to find file or directory error (sorry, I hosed my terminal history so can't give you full error), it is trying to make an initramfs for my running machine (4.4.0) instead of the kernel version installed in chroot, which is 4.4.38+ (4.4.38-v7+). The version has to be specified manually, e.g. 'mkinitramfs -o /boot/initrd $version', the only way I see this could be done is by getting the version from directory names in /lib/modules, then selecting the appropriate one (how, I don't know, according to some sources -v7 is for rpi2&3 and the one without is for rpi1, so we would need to know if this is being built for rpi v1 or v2/v3)

I have some typo fixes and an added feature ready, I can give you a pull request if that would be fine with you.

Paultok commented 7 years ago

Yes, jjakob, please do if it's fine for TheSin

TheSin- commented 7 years ago

yeah please do a PR, I wish I had more time ATM, but I'm in the middle of selling my house, buying a new one all in 30 days :. But I'll do what I can and if not, likely in 45 days when the dust has settled I'll be able to help test and working this.

TheSin- commented 7 years ago

so it was a little longer then 45 days ;) but I'm back at it. Anyone have any luck with testing this? I didn't see a PR so can I assume it's working?

TheSin- commented 7 years ago

finally had time to test this plugin, and so far it's working great, think we are okay to close this ticket! Thanks for all the help on it guys.