As it happens, it looks like a bug in debian's package of grub
.
The -kernel grub.img
approach works if I only include the grub modules I need upon grub-mkimage
.
The -bios grub.bin
works with the newer grub package from experimental
(2.00-7). However, the grub.bin
that comes with it is not very useful.
It comes with a memdisk
that comes with the grub.cfg
. It would have been better to use that memdisk to hold the modules and the grub.cfg
be specified with the -c
option of grub-mkimage
. For instance, one of the menu entry looks for /boot/grub/grub.cfg
and finds itself in the memdisk as a result. Also, the debian package doesn't include the qemu grub modules, so you can't build a different grub.bin (though you can binary edit the file to change the grub.cfg) unless you do it from the source package.
The -bios grub.bin
approach sounds like the cleanest approach to me, but I'll use the -kernel
or floppy approach until the debian package is fixed.
EDIT: well, the ata.mod
grub module to read emulated IDE drives is a lot slower than using biosdisk.mod
in combination with seabios
(the default bios when not using -bios grub.bin
). Also, it seems that grub firmware doesn't support virtio-blk nor virtio-scsi disks, so kvm -bios grub.bin
is not going to be an option for me.
In case anyone wants to goes down that path, I'm now using (zsh syntax):
grub-mkimage -O i386-pc -c =(print -l serial 'terminal_input serial' \
'terminal_output serial' 'set prefix=(hd0)/boot/grub' '. grub.cfg') -o grub.img \
at_keyboard configfile biosdisk ext2 linux test serial halt minicmd terminal cat
And -kernel grub.img -nographic
passed to kvm. That is to boot Linux VMs with no graphics (only a serial interface, so make sure that the VM's grub is configured to use serial (or at least not configured to use graphics), that the kernel console goes to ttyS0 and that you run a getty on there). It can easily be adapted to work for VGA consoles as well.
New answer (2015-03-22)
(Note: This answer is simpler than previous, but not more secure. My first answer is stronger because you could keep files read-only by fs mount options before permission flags. So forcing to write a files without permission to write won't work at all.)
Yes, under Debian, there is a package: fsprotect (homepage).
It use aufs
(by default, but could use another unionfs
tool) to permit live session changes but in RAM by default, so everything is forgotten at reboot.
You could install them by running simply:
apt-get install fsprotect
Once done, from online doc:
After that:
- Edit
/boot/grub/menu.lst
or /etc/default/grub2
or /etc/lilo.conf
and add "fsprotect=1G
" to kernel parameters.
- Modify 1G as needed.
- Apply changes (i.e. run
update-grub
)
- Edit
/etc/default/fsprotect
if you want to protect filesystems other than /
.
- reboot
You may also want to password protect the grub bootloader or forbid any changes to it.
From there, if some file is protected against changes, for sample by
chmod ugo-w myfile
if you use for sample vi myfile
and try to write on it with command :w!
, this will work and your myfile
became changed. You may reboot in order to retrieve unmodified myfile
.
That's not even possible with my following first solution:
Old (first) answer:
Yes, it is a strong solution, but powerfull!
Making r/o useable
You have to mount some directories in rw, like /var
, /etc
and maybe /home
. This could by done using aufs or unionfs. I like this another way, using /dev/shm
and mount --bind
:
cp -a /var /dev/shm/
mount --bind /dev/shm/var /var
You could before, move all directories who have not to change in normal operation in a static-var
, than create symlinks in /var:
mkdir /static-var
mkdir /static-var/cache
mkdir /static-var/lib
mv /var/lib/dpkg /static-var/lib/dpkg
ln -s /static-var/lib/dpkg /var/lib/dpkg
mv /var/cache/apt /static-var/cache/apt
ln -s /static-var/cache/apt /var/cache/apt
... # an so on
So when remounting in ro, copying /var
in /dev/shm
won't take too much space as most files are moved to /static-var
and only symlinks are to be copied in ram.
The better way to do this finely is to make a full power-cycle, one day of full work and finely run a command like:
find / -type f -o -type f -mtime -1
So you will see which files needs to be located on read-write partition.
Logging
As in this host no writeable static memory exist, in order to store history and other logs, you have to config a remote syslog
server.
echo >/etc/syslog.conf '*.* @mySyslogServer.localdomain'
In this way, if your system break for any reason, everything before is logged.
Upgrading
When running whith some mount --bind
in use, for doing such an upgrade while system is in use (whithout the need of running init 1
, for reducing down-time), the simplier way is to re-build a clean root, able to do the upgrade:
After remounting '/' in read-write mode:
mount -o remount,rw /
for mpnt in /{,proc,sys,dev{,/pts}};do
mount --bind $mnpt /$mnt$mpnt;
done
chroot /mnt
apt-get update && apt-get dist-upgrade
exit
umount /mnt/{dev{/pts,},proc,sys,}
sync
mount -o remount,ro /
And now:
shutdown -r now
Best Answer
If your rootfs is not too big you can use an initd. Use the
-initrd
option to qemu and provide a (compressed) cpio file with the rootfs. So if you have a tar file you must unpack it and create a cpio instead. You must use-H newc
format for cpio. Example;A nice thing is that you don't need root or sudo for this.