Difference between revisions of "OpenBSD Soekris Read Only Root"

From WTFwiki
Jump to navigation Jump to search
(finish up the content)
(fix typo, update to 7.0)
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Running OpenBSD on a [http://www.soekris.com/net4801.htm Soekris net4801] =
+
= Running OpenBSD on a Soekris [http://www.soekris.com/net4801.htm net4801] / [http://www.soekris.com/net5501.htm net5501] =
  
 
== Introduction/Theory ==
 
== Introduction/Theory ==
Line 6: Line 6:
 
running with the root (only) filesystem mounted read-only.  This means the compact-flash card will live a<br/>
 
running with the root (only) filesystem mounted read-only.  This means the compact-flash card will live a<br/>
 
little longer, not enduring the write cycles that are fabled to kill them, and if someone trips over the power<br/>
 
little longer, not enduring the write cycles that are fabled to kill them, and if someone trips over the power<br/>
cord, you don't lose anything on the filesystems.  You also never need to endure the delay of a length fsck(8).<br/>
+
cord, you don't lose anything on the filesystems.  You also never need to endure the delay of a lengthy fsck(8).<br/>
 
<br/>
 
<br/>
 
All the bonuses out of the way: it's kind of a bastard to setup.. I'll try my best to detail it, including a<br/>
 
All the bonuses out of the way: it's kind of a bastard to setup.. I'll try my best to detail it, including a<br/>
patch(1) file for '/etc/rc'.  There are a number of "neat" tricks to play with symbolic links and MFS style<br/>
+
replacement for '/etc/rc'.  There are a number of "neat" tricks to play with symbolic links and MFS style<br/>
 
RAM-disks.<br/>
 
RAM-disks.<br/>
 
<br/>
 
<br/>
 +
 +
== Caveats ==
 +
Unfortunately, a few great features get disabled as part of this.  KARL and library ASLR, for example.
 +
=== KARL ===
 +
KARL requires a lot of disk space for my target 512MB CF card, as well as needing a read-write disk.<br/>
 +
If you have the space (say, a 1GB CF card!), you could easily run the relink process manually whenever<br/>
 +
you feel like it to regain use of this feature to some degree:
 +
  # /usr/libexec/reorder_kernel &
 +
If you're not going to use KARL and are space-constrained on your CF card, you can remove the relink<br/>
 +
directory like so:
 +
  # rm -fr /usr/share/relink
 +
 +
=== library ASLR ===
 +
ASLR is a bit more complicated, although it does happen at least one time (first boot after installation),<br/>
 +
so not all is lost!
 +
 +
=== On-boot randomness seeding ===
 +
The "random_seed()" function in /etc/rc gets largely commented out due to needing filesystem write privileges.<br/>
 +
You can manually run these commands on occasion to regain partial use of this feature as well.  Like ASLR, this<br/>
 +
at least happens on first boot.
  
 
== Installation ==
 
== Installation ==
  
I usually go with the PXE boot method, its really the easiest on a soekris, since you need a small network with<br/>
+
Perform a [[Setting up PXE|PXE-boot]] standard OpenBSD/i386 install, the following differences apply:<br/>
internet connectivity (or a local FTP/HTTP mirror), a DHCP server and a TFTP server.  OpenBSD already comes with<br/>
 
all of this capability, so a random crap PC on your network running it will do.<br/>
 
<br/>
 
'''dhcpd.conf''':
 
You need to add 'next-server <IP of TFTP server>' and 'filename "pxeboot"' to your 'subnet' declaration.. thats it.<br/>
 
<br/>
 
'''inetd.conf''':
 
Uncomment the IPv4 TFTP line and 'pkill -9 inetd && inetd'.<br/>
 
<br/>
 
Once that's done, get 'pxeboot' and 'bsd.rd' from your desired version of OpenBSD (4.4, in my case) and put it in <br/>
 
'/tftpboot' on the TFTP server, make sure permissions are set world-readable.<br/>
 
<br/>
 
 
Power on your soekris with a serial console connected.  They use a standard DB9M connector, and supply 19200 baud, 8n1.<br/>
 
Power on your soekris with a serial console connected.  They use a standard DB9M connector, and supply 19200 baud, 8n1.<br/>
 
If you don't know what that means, figure it out via google or wikipedia.<br/>
 
If you don't know what that means, figure it out via google or wikipedia.<br/>
Line 43: Line 51:
 
You should see the kernel boot, just wait until it comes to the Install, Upgrade, etc menu; it will take a minute or a few.<br/>
 
You should see the kernel boot, just wait until it comes to the Install, Upgrade, etc menu; it will take a minute or a few.<br/>
 
<br/>
 
<br/>
Choose 'Install', and proceed as any normal OpenBSD install would; you'll make modifications when its booted multi-user.<br/>
+
Choose 'Install', and proceed as any normal OpenBSD install would, with some exceptions:<br/>
 +
* When installing, you should partition your CF card with 1 giant / partition, and *no swap*
 +
* It'll ask you later on if you want to change the console to com0, tell it yes and choose 19200 to match the soekris BIOS settings.<br/>
 +
* KARL will fail during install with "out of swap" style memory errors.  The installation still completes, and we'll disable KARL post-install.<br/>
 +
* Once installed, reboot into your installation and do basic post-install configuration, including setting up network interfaces, adding packages, configuring doas/sudo, etc.. the idea is to have a fully installed system that just needs configuration.
 
<br/>
 
<br/>
  
Line 49: Line 61:
  
 
Some general good-idea step are in order:<br/>
 
Some general good-idea step are in order:<br/>
* Add yourself a user, and configure sudo(8) properly for that user.
+
* Add yourself a user, and configure doas(8)/sudo(8) properly for that user.
 
* Setup any networking you'll need; this includes pf(4), any hostname.if(5) files, dhcpd(8), etc.  I don't care what you do here.
 
* Setup any networking you'll need; this includes pf(4), any hostname.if(5) files, dhcpd(8), etc.  I don't care what you do here.
 
* Install any packages you want.. GNU screen, zsh, multitail, openvpn, and ruby are some of the ones that I put on everything.
 
* Install any packages you want.. GNU screen, zsh, multitail, openvpn, and ruby are some of the ones that I put on everything.
* Enable any services you'll want in '/etc/rc.conf.local'.. I usually have something like this:<br/>
+
* Enable any services you'll want in '/etc/rc.conf.local', plus disable a few things that are unhelpful/unnecessary:<br/>
   rdate_flags="-n time.slic.com"
+
   library_aslr=NO              # takes ages and requires read-write disk
 +
  sndiod_flags=NO
 
   watchdogd_flags="-i 3 -p 10"
 
   watchdogd_flags="-i 3 -p 10"
  pf=YES
 
  ntpd_flags=""
 
  named_flags=""
 
  isakmpd_flags="-K"
 
  ipsec=""
 
  dhcpd_flags="sis1"
 
 
<br/>
 
<br/>
 
Now to get to the real work.. modifying your config files and filesystem to work with the read-only root configuration.<br/>
 
Now to get to the real work.. modifying your config files and filesystem to work with the read-only root configuration.<br/>
Line 67: Line 74:
 
== Read-only Root Config ==
 
== Read-only Root Config ==
  
* First: edit '/etc/fstab' and change "rw" to "ro" on your root filesystem line.
+
Login and 'doas -s' or 'sudo -s' if you haven't already: you'll need to perform a number of steps,<br/>
* Copy '/dev/MAKEDEV' to '/etc/MAKEDEV'; '/dev' will be MFS-mounted and won't have MAKEDEV.  This step is IMPERATIVE.
+
which I'll detail below..<br/>
* Edit 'sysctl.conf', enable 'net.inet.ip.forwarding' and disable 'vm.swapencrypt.enable' for speed reasons.  Shouldn't matter, we don't use swap.
+
 
* Patch '/etc/rc', I provide my changes [http://wtf.hijacked.us/patches/2008-11-20--openbsd44-rc.patch HERE] because it isn't obvious what to do.
+
   # cp /etc/rc /etc/rc-dist
<br/>
+
   # ftp -o /etc/rc https://wtf.hijacked.us/random/OpenBSD-ro-rc/7.0-rc
=== Explanation of 'rc' patch: ===
+
   # cp /dev/MAKEDEV /etc/MAKEDEV
* I remove a number of things that don't apply to a soekris, to aid in speedy bootup.  Everything helps.
+
   # touch /var/run/dhcpd.leases
* Remove the mixer stuff, CCD/RAID, swap
+
   # touch /var/run/dhclient.leases.sis{0,1,2}
* Replace the read-write mount stuff with a bunch of properly sized MFS mounts: '/dev', '/var/run', '/var/empty', '/var/log', '/var/named', '/tmp', and '/home'.
+
   # touch /var/run/dhclient.leases.vr{0,1,2,3}
* Create the RAM-disk version of '/dev', OpenBSD includes a neat target called 'ramdisk' that sets up the bulk of this for you; I add a few things for my own convenience (extra ptys, bpfs, and tun for VPNs)
+
   # ln -s /var/run/dhclient.leases.* /var/db/
* Create empty versions of a number of logfiles, and set their permissions correctly for syslogd(8).
+
   # ln -s /var/run/dhcpd.leases /var/db/
* Create empty dhclient.leases files in a nonstandard (writable) location, fix their permissions.
+
   # mv /var/db/ntpd.drift /var/run/ntpd.drift
* Copy a persistant version of '/home' from '/cfhome'
+
   # ln -s /var/run/ntpd.drift /var/db/
* Copy in BIND9 configs from '/var/named-dist'
+
   # pkill -9 cron
* Setup a usable cron(8) environment from a persistant version
+
  # mv /var/cron /var/cron-dist
* Get rid of the resolv.conf mangling stuff, it won't work anyway
+
  # rm -f /var/cron-dist/tabs/.sock
* Get rid of the '/var/spool' lockfile management, optionally move it to a writable location if you care.
+
   # cp -Rp /var/cron-dist /var/log/cron-running
* Get rid of 'amd', 'savecore', 'afs', quota checking, 'lpd', the kerberos master/slave stuff, 'apmd', 'wsmoused', and 'xdm'.
+
   # ln -s /var/log/cron-running /var/cron
<br/>
+
   # sed -i '1,$s/\/ ffs rw/\/ ffs ro/g' /etc/fstab
=== Filesystem Modifications ===
+
  # mv /home /cfhome
I present these details as commands, it's easier to express that way, and easier to understand.<br/>
+
   # mkdir /home
<br/>
+
  # cat /etc/syslog.conf | grep -v -e xferlog -e lpd-errs >/etc/syslog.conf
  # pkill -9 syslogd
+
   # cat /etc/newsyslog.conf | grep -v -e xferlog -e lpd-errs >/etc/newsyslog.conf
  # pkill -9 dhclient
+
  # reboot
   # pkill -9 pflogd
+
 
  # pkill -9 ntpd
+
There.. if you did everything correctly and didn't do anything too funny with your system<br/>
  # pkill -9 named
+
before setting up read-only-root, things should come up with *no errors during boot*.. good luck.
  # pkill -9 dhcpd
 
  # pkill -9 sendmail
 
  # mv /var/named /var/named-dist &&  mkdir /var/named
 
   # rm -fr /var/run && mkdir /var/run
 
  # mv /home /cfhome && mkdir /home
 
  # mkdir -p /var/log/cron-running
 
  # ln -s /var/cron/tabs /var/log/cron-running/tabs
 
   # ln -s /var/cron/atjobs /var/log/cron-running/atjobs
 
   # mv /var/cron/tabs /var/cron/tabs-dist
 
   # mv /var/cron/atjobs /var/cron/atjobs-dist
 
  # rm /var/cron/log
 
   # touch /var/log/cron
 
   # ln -s /var/log/cron /var/cron/log
 
  # touch /var/run/dhclient.leases.sis0 && rm /var/db/dhclient.leases.sis0
 
   # ln -s /var/run/dhclient.leases.sis0 /var/db/dhclient.leases.sis0
 
   # touch /var/run/dhclient.leases.sis1 && rm /var/db/dhclient.leases.sis1
 
   # ln -s /var/run/dhclient.leases.sis1 /var/db/dhclient.leases.sis1
 
   # touch /var/run/dhclient.leases.sis2 && rm /var/db/dhclient.leases.sis2
 
   # ln -s /var/run/dhclient.leases.sis2 /var/db/dhclient.leases.sis2
 
   # touch /var/run/dhcpd.leases && rm /var/db/dhcpd.leases
 
   # ln -s /var/run/dhcpd.leases /var/db/dhcpd.leases
 
   # touch /var/run/ntpd.drift && rm /var/db/ntpd.drift
 
   # ln -s /var/run/ntpd.drift /var/db/ntpd.drift
 
  
Once you've got all this setup, reboot(8) and hope it comes back up.  I recommend leaving the serial console connected for<br/>
+
I recommend leaving the serial console connected for a while.  At least until you're used to<br/>
a while.  At least until you're used to managing this setup, it'll be helpful.<br/>
+
managing this setup, it'll be helpful.<br/>
  
 
== Maintaining Your Soekris ==
 
== Maintaining Your Soekris ==

Latest revision as of 16:54, 14 October 2021

Running OpenBSD on a Soekris net4801 / net5501

Introduction/Theory

A number of ways exist to do this, I've chosen the slightly more complicated but fairly rewarding method of
running with the root (only) filesystem mounted read-only. This means the compact-flash card will live a
little longer, not enduring the write cycles that are fabled to kill them, and if someone trips over the power
cord, you don't lose anything on the filesystems. You also never need to endure the delay of a lengthy fsck(8).

All the bonuses out of the way: it's kind of a bastard to setup.. I'll try my best to detail it, including a
replacement for '/etc/rc'. There are a number of "neat" tricks to play with symbolic links and MFS style
RAM-disks.

Caveats

Unfortunately, a few great features get disabled as part of this. KARL and library ASLR, for example.

KARL

KARL requires a lot of disk space for my target 512MB CF card, as well as needing a read-write disk.
If you have the space (say, a 1GB CF card!), you could easily run the relink process manually whenever
you feel like it to regain use of this feature to some degree:

 # /usr/libexec/reorder_kernel &

If you're not going to use KARL and are space-constrained on your CF card, you can remove the relink
directory like so:

 # rm -fr /usr/share/relink

library ASLR

ASLR is a bit more complicated, although it does happen at least one time (first boot after installation),
so not all is lost!

On-boot randomness seeding

The "random_seed()" function in /etc/rc gets largely commented out due to needing filesystem write privileges.
You can manually run these commands on occasion to regain partial use of this feature as well. Like ASLR, this
at least happens on first boot.

Installation

Perform a PXE-boot standard OpenBSD/i386 install, the following differences apply:
Power on your soekris with a serial console connected. They use a standard DB9M connector, and supply 19200 baud, 8n1.
If you don't know what that means, figure it out via google or wikipedia.

At some point, the soekris' BIOS will ask you to hit Ctrl+P to interrupt the boot and enter the monitor, do so, and at
the prompt, type "boot F0". "F0" is the name of the first ethernet port on the device.

You should see the soekris come up with an address via DHCP, and put you at an OpenBSD PXE boot loader prompt, you should
type the following to ensure a successful boot.. order matters:

 > stty com0 19200
 > set tty com0
 > boot bsd.rd


You should see the kernel boot, just wait until it comes to the Install, Upgrade, etc menu; it will take a minute or a few.

Choose 'Install', and proceed as any normal OpenBSD install would, with some exceptions:

  • When installing, you should partition your CF card with 1 giant / partition, and *no swap*
  • It'll ask you later on if you want to change the console to com0, tell it yes and choose 19200 to match the soekris BIOS settings.
  • KARL will fail during install with "out of swap" style memory errors. The installation still completes, and we'll disable KARL post-install.
  • Once installed, reboot into your installation and do basic post-install configuration, including setting up network interfaces, adding packages, configuring doas/sudo, etc.. the idea is to have a fully installed system that just needs configuration.


Post-Install Madness

Some general good-idea step are in order:

  • Add yourself a user, and configure doas(8)/sudo(8) properly for that user.
  • Setup any networking you'll need; this includes pf(4), any hostname.if(5) files, dhcpd(8), etc. I don't care what you do here.
  • Install any packages you want.. GNU screen, zsh, multitail, openvpn, and ruby are some of the ones that I put on everything.
  • Enable any services you'll want in '/etc/rc.conf.local', plus disable a few things that are unhelpful/unnecessary:
 library_aslr=NO               # takes ages and requires read-write disk
 sndiod_flags=NO
 watchdogd_flags="-i 3 -p 10"


Now to get to the real work.. modifying your config files and filesystem to work with the read-only root configuration.

Read-only Root Config

Login and 'doas -s' or 'sudo -s' if you haven't already: you'll need to perform a number of steps,
which I'll detail below..

 # cp /etc/rc /etc/rc-dist
 # ftp -o /etc/rc https://wtf.hijacked.us/random/OpenBSD-ro-rc/7.0-rc
 # cp /dev/MAKEDEV /etc/MAKEDEV
 # touch /var/run/dhcpd.leases
 # touch /var/run/dhclient.leases.sis{0,1,2}
 # touch /var/run/dhclient.leases.vr{0,1,2,3}
 # ln -s /var/run/dhclient.leases.* /var/db/
 # ln -s /var/run/dhcpd.leases /var/db/
 # mv /var/db/ntpd.drift /var/run/ntpd.drift
 # ln -s /var/run/ntpd.drift /var/db/
 # pkill -9 cron
 # mv /var/cron /var/cron-dist
 # rm -f /var/cron-dist/tabs/.sock
 # cp -Rp /var/cron-dist /var/log/cron-running
 # ln -s /var/log/cron-running /var/cron
 # sed -i '1,$s/\/ ffs rw/\/ ffs ro/g' /etc/fstab
 # mv /home /cfhome
 # mkdir /home
 # cat /etc/syslog.conf | grep -v -e xferlog -e lpd-errs >/etc/syslog.conf
 # cat /etc/newsyslog.conf | grep -v -e xferlog -e lpd-errs >/etc/newsyslog.conf
 # reboot

There.. if you did everything correctly and didn't do anything too funny with your system
before setting up read-only-root, things should come up with *no errors during boot*.. good luck.

I recommend leaving the serial console connected for a while. At least until you're used to
managing this setup, it'll be helpful.

Maintaining Your Soekris

From time to time, you'll obviously have to make changes to the thing; and it isn't very cool to have to reboot into
single-user and remount your filesystem read-write everytime this needs to be done. In fact, thats dumb.. BUT: "There's Another Way"..

Remounting the filesystem read-write on a live system

This should work in any case, and let you modify to your heart's content..

 # mount -uw /

Remounting the filesystem read-only on a live system

This will only work if you haven't started anything thats writing at the moment..

 # mount -ur /