partially read-only system

I want to create a partially read-only system.
-------------------------------------------------------------------------------------------------------------------------
General rant, sorry if i'm not specific,
But then i need to be sure.
Where , which directories does kernel writes.
Where , which directories does base writes
Where, which directories does kernel modules writes
Where, which directories do packages writes


example libexec ... , who , why ,when , where /usr/libexec /usr/local/libexec etc ....

99.999% of modifications i do happen in :
/home/myuser
or
/usr/local
when i install a new package
So these two places read/write ?
But then tmp also read/write & var/tmp also read/write.
Sometimes something gets written on a place we did not imagined.
Or simetimes during boot... , i remember vaguely openssl/ssh.
------------------------------------------------------------------------------------------------------------------------------------------
I now think of zfs sub filesystems,
/var : rw
/home : rw

/boot : r
/lib : r
/libexec : r
/bin : r
/sbin : r
/usr : r

But the system must remain bootable.
The boot script/library to mount /etc/fstab cannot remain on a partition of to be mounted by /etc/fstab

[Maybe stupid two stupid example ; I cannot mount /root in /etc/fstab, because mounting happens as root user :) ; I cannot mount /sbin in fstab because mount belonggs to /sbin/fstab ; But then i know little about boot2]
 
Here's the answer that my particular blend of ChatGPT gives to your inquiry. I hope it helps at least to recruit human commentators to help you. And if ChatGPT's answer is itself helpful, good.


A partially read-only FreeBSD system

A partially read-only FreeBSD system is easiest to reason about if the tree is split into three classes: base system files, third-party installed files, and runtime state. On current FreeBSD, the base system lives outside /usr/local; third-party software installed by pkg(8)() or the Ports framework lives under /usr/local; and the paths that are expected to change during normal operation are concentrated under /var, /tmp, and user home directories. hier(7)()

The base system is primarily this set of installed paths: /boot, /bin, /sbin, /lib, /libexec, /etc, and the base portions of /usr such as /usr/bin, /usr/sbin, /usr/lib, /usr/libexec, and /usr/share. The hier(7)() manual also states that /libexec contains system utilities critical to binaries in /bin and /sbin, while the /usr/libexec subtree contains system daemons and utilities executed by programs.

Third-party software belongs under /usr/local. In current hier(7)(), /usr/local is explicitly described as the location for local executables, libraries, and related files installed by pkg(7)() or ports(7)(). That same hierarchy defines /usr/local/etc as local program configuration, /usr/local/lib as local libraries, and /usr/local/libexec as utilities executed by local utilities. The Handbook also states the general configuration split directly: base configuration in /etc, third-party application configuration in /usr/local/etc.

So the libexec split is this:

  • /libexec: base-system helpers critical to programs in /bin and /sbin.
  • /usr/libexec: base-system daemons and helper programs executed by other base programs.
  • /usr/local/libexec: the third-party counterpart for helpers executed by locally installed software.

The kernel and kernel modules are stored under /boot. The normal module paths are /boot/kernel and /boot/modules. Those directories are mostly read-only in day-to-day operation, but they are not completely exempt from boot-time writes: if kldxref_enable="YES", FreeBSD rebuilds linker.hints files at boot in the module paths.

Hazard: A strictly read-only /boot can break boot-time module metadata updates. If /boot must remain read-only after provisioning, set kldxref_enable="NO" only after confirming that module metadata is already correct.

The main runtime-write area is /var. Current hier(7)() describes /var as the location for log, temporary, transient, and spool files, and it explicitly includes /var/cache/pkg for cached packages. In practice, the important writable subtrees for a normal host are /var/run, /var/log, /var/db, /var/cache, /var/tmp, and sometimes /var/crash.

For package management specifically, pkg.conf(5)() gives the defaults clearly: the package database is /var/db/pkg, the package cache is /var/cache/pkg, and the system-wide pkg configuration file defaults to /usr/local/etc/pkg.conf. The Handbook also notes that many systems do not need a pkg.conf file at all, which is useful when trying to keep configuration minimal.

That is why the statement “almost everything modified is under /home or /usr/local” is close, but not complete. A FreeBSD system that actually boots and runs services normally still expects writable state under /var, writable temporary storage under /tmp or memory-backed /tmp, and user-writable homes under /home.

There are also a few boot-time or first-start writes that surprise people. On current FreeBSD, update_motd="YES" updates /var/run/motd, not /etc/motd. The first time sshd starts, FreeBSD generates the host keys automatically, which writes under /etc/ssh. Kernel crash dumps are another case: the dump is written to the configured dump device, and the saved crash data is associated with /var/crash during processing after reboot.

A practical partially read-only layout therefore looks like this:

Code:
/            read-only
/boot        read-only
/usr         read-only

/usr/local   read-write   (or read-only except during package maintenance)
/var         read-write
/home        read-write
/tmp         read-write or memory-backed

Hazard: This layout works only if /usr/local is its own mount point when /usr is read-only. Otherwise /usr/local inherits the read-only state of /usr.

That layout is sound only if /usr/local is its own mount point when /usr is read-only. The FreeBSD Handbook defines a mount point as a directory where another filesystem is grafted onto its parent. When a filesystem is mounted on a directory, the mounted filesystem replaces what was visible there from the parent. So /usr cannot be mounted read-only while /usr/local remains independently writable unless /usr/local is a separate filesystem or dataset mounted on that directory.

For /tmp, current rc.conf(5)() provides tmpmfs, which creates a memory-backed /tmp using mdmfs(8)(). It is worth being exact here: tmpmfs is not the same knob as mounting tmpfs(5)() manually. tmpmfs="YES" creates /tmp as an MFS via mdmfs, and it can also be triggered automatically if /tmp is not writable. There is a matching varmfs mechanism for /var, but that is usually for more appliance-like or diskless designs because /var often needs persistent state.

A sane starting policy for a machine that still installs packages locally is this:

  • Keep /, /boot, and /usr read-only.
  • Keep /var, /tmp, and /home writable.
  • Keep /usr/local writable if the machine runs pkg install or pkg upgrade locally.
  • Keep /etc read-only during normal operation only after initial provisioning is complete, especially after SSH host keys already exist.

A more locked-down policy is also possible:

  • Keep /usr/local read-only in steady state.
  • Remount /usr/local read-write only during package maintenance.
  • Keep kldxref_enable="NO" if /boot stays read-only after boot.
  • Keep update_motd="NO" if the goal is to avoid even /var/run/motd churn.

Hazard: Making /usr/local read-only in steady state prevents package installs, upgrades, and many post-install actions until it is remounted read-write. This affects the host or dataset mounted there.

Hazard: Disabling crash dumps with dumpdev="NO" removes a useful diagnostic path after kernel panics. This affects host-level debugging and incident analysis.

A compact rc.conf(5)() baseline for this kind of host is:

Code:
# /etc/rc.conf
root_rw_mount="NO"
tmpmfs="YES"
update_motd="NO"
kldxref_enable="NO"

# Optional on hosts where crash dumps are not wanted
dumpdev="NO"

That keeps the root from being remounted read-write during boot, enables a memory-backed /tmp, avoids the motd update, and prevents boot-time rebuilding of linker.hints. The dumpdev="NO" line is a policy choice, not a requirement.

These checks show whether the layout matches the intended policy:

Code:
# mount
# sysrc root_rw_mount tmpmfs update_motd kldxref_enable dumpdev
# pkg config PKG_DBDIR
# pkg config PKG_CACHEDIR
# ls -ld /var /var/run /var/log /var/db /var/cache/pkg /tmp /var/tmp /home /usr/local
# service sshd status

Those commands verify the mount state, the boot-policy variables, the pkg metadata paths, and the writable runtime trees.

The shortest accurate summary is this:

  • Kernel and modules: mostly /boot/kernel and /boot/modules; watch kldxref_enable.
  • Base system: /boot, /bin, /sbin, /lib, /libexec, /etc, /usr/bin, /usr/sbin, /usr/lib, /usr/libexec, /usr/share.
  • Third-party software: /usr/local/**, with config in /usr/local/etc and helper binaries in /usr/local/libexec.
  • Package metadata and cache: /var/db/pkg and /var/cache/pkg.
  • Normal runtime writes: /var/**, /tmp, /var/tmp, /home/**.
  • Common surprise writes: /var/run/motd, /etc/ssh on first sshd start, and linker.hints if kldxref_enable="YES".

So the robust answer is not “make everything read-only except /home and /usr/local.” The robust answer is: make the installed software trees read-only, keep the runtime-state trees writable, and isolate /usr/local as its own mount point if it must remain writable while /usr is read-only.
 
I want to create a partially read-only system.
My first question is why? What is your use case/reason?
Even if it's "just because I want to"?
Is it for security?
If security why not start with securelevel, use chflags to set system files immutable. Both of those go a long way to locking down a system.
Careful with /boot there are some flags that govern a rebuild of linker.hints on reboot, if you set to readonly that may fail
 
We need to ban ChatGPT here.
The whole internet is about AI now, it's becoming hard to avoid it, I can't wait to see what position will be taken about it here.
The other day I was on YT, I've stumbled across three different documentaries on different channels (politics, animals, police) all three were fake, made with AI and TBH at first glance you won't see the difference.
Of course, in most case, "made by AI" is not mentioned anywhere at all and the scariest part is reading comments below the videos from people who believe that's true...


Alain De Vos
I know you're using ZFS but just so you know it is apparently feasible with UFS, the trick is simple, switch the flags of the root filesystem from rw to ro in /etc/fstab.
Then anytime you need to make a change mount temporary the filesystem with the option rw, make your modifications and umount it.

I saw this in this article.
Also possible with NetBSD but a bit more complicated.

That being said, I am curious to know what will be the solution you'll end up with, interesting topic and nice ideas from mer .
 
We need to ban ChatGPT here.
We need to BAN all AI here. This is getting tiresome from a FreeBSD helper standpoint. Bad enough people won't read the manuals now we have to fight outright lies.

When we have to fight outright lies it becomes very dull to me.

Ban users posting slop and AI.

Keep /etc read-only during normal operation only after initial provisioning is complete, especially after SSH host keys already exist.
SSH Keys are in /etc now?

No this is ABSOLUTE SLOP. From a new user. Please ban them now. Enough is enough already. They are ruining the forum. Deliberate falsehoods should be a user posting ban.

PLEASE REMOVE FALSEHOODS. QUIT RUINING THE FORUM WITH JUNK.
 
VladiBG, kent_dorfman766, Maturin, gotnull:

I'll adhere to the rules of the FreeBSD forums. If they are changed so they prohibit LLM-generated content, I'll stop posting it. Meanwhile, I'll post LLM-generated content when I think it may help another user, always specifying clearly that it is LLM-generated.

There are two problems:
  • The LLM generated answers are too long and block reading the thread for others
  • You should only post such output after you reviewed it for correctness. While doing that you can also shorten it to address the previous point
 
The whole internet is about AI now, it's becoming hard to avoid it, I can't wait to see what position will be taken about it here.
The other day I was on YT, I've stumbled across three different documentaries on different channels (politics, animals, police) all three were fake, made with AI and TBH at first glance you won't see the difference.
Of course, in most case, "made by AI" is not mentioned anywhere at all and the scariest part is reading comments below the videos from people who believe that's true...


Alain De Vos
I know you're using ZFS but just so you know it is apparently feasible with UFS, the trick is simple, switch the flags of the root filesystem from rw to ro in /etc/fstab.
Then anytime you need to make a change mount temporary the filesystem with the option rw, make your modifications and umount it.

I saw this in this article.
Also possible with NetBSD but a bit more complicated.

That being said, I am curious to know what will be the solution you'll end up with, interesting topic and nice ideas from mer .
In the end i mount /var & /usr datasets in fstab. All the rest i keep like it is. Not overdoing things.
 
There are two problems:
  • The LLM generated answers are too long and block reading the thread for others
  • You should only post such output after you reviewed it for correctness. While doing that you can also shorten it to address the previous point

Thank you for your opinions, but please note that they are just your opinions, not rules of the forum. I won't do what you think I should do; I will do what I think I should do and the rules of the FreeBSD Forums allow me to do.

That said, my objectives were clearly stated in my first post, and they have been fulfilled, so I deem my post a resounding success.
 
>> "Don't clog up threads" doesn't need a formal rule. It is common curtesy.
> "Shouldn't need to be a formal rule" and common courtesy is not all that common now.
Neither is people's use of the spacebar, obviously. ;p :]

I remember the days when thread "subject titles" and question "quality" were a big deal; I'd point the user to "ESR: how to ask questions" and get labeled as an ass. But the funny thing I came to realize later about the 'how to ask questions' problem was that there was never a "how to answer questions" (a person's region does matter). ...I digress, too muddy of a thought.

RE: (not) made by Ai labels
how about "made without compromise"?


...Well, I'm sure you all are thinking that's enough of me by now (I've done my "dispensing distractions" for the day). :]
 
Back
Top