FreeBSD sysrc Operations: Query and Change rc Configuration Safely
Use sysrc to inspect, change, append, and validate FreeBSD rc.conf settings without confusing saved configuration with live service state.
sysrc(8) is FreeBSD’s supported command-line interface for reading and changing variables in the system’s rc configuration files. It is useful in change scripts, remote administration, and configuration-management workflows because it understands the rc configuration file list and performs targeted updates instead of relying on fragile text substitutions. Its scope is deliberately narrow: it edits persistent rc settings. It does not start a service, prove that a daemon is healthy, or update the environment of an already-running process.
That distinction is the core operational safeguard. A successful sysrc write proves that a configuration value was saved. You still need to validate syntax, determine which service consumes it, apply the appropriate runtime action, and verify the effective state. Treat those as separate steps and preserve a rollback path before changing network, storage, or remote-access settings.
Discover the configuration source before editing
FreeBSD can read more than one rc configuration file. The default order is defined by rc_conf_files, and local site policy can change it. A query that reads the effective configured value is safer than assuming a value lives in /etc/rc.conf:
sysrc -a | less
sysrc sshd_enable
sysrc -n hostname
sysrc -l
sysrc -L
-a lists configured non-default variables, while -A includes defaults. -n omits the variable name and prints only the value, which is convenient for scripts but can make logs ambiguous if several values are queried. -l lists rc files used at startup. -L lists configuration files including rc.conf.d entries; it can be combined with -v or -e to show service names and status. For a specific service’s rc.conf.d view, use the documented -s service -l form. Always test command options against that release’s manual page before depending on them in portable automation.
When a value appears unexpectedly, inspect all files in the reported order and the default configuration rather than editing the first matching line. Shell-style rc configuration allows a later file to override earlier state. Local automation may also set RC_CONFS or invoke sysrc -f against a different file. Capture the command, target, and output in a change record so another operator can reproduce what was queried.
Use a named file only when the deployment deliberately owns that file:
sysrc -f /etc/rc.conf.d/sshd sshd_enable
sysrc -f /etc/rc.conf.d/sshd sshd_enable="YES"
Do not assume that an arbitrary file under /etc/rc.conf.d is loaded simply because sysrc -f can edit it. Confirm that the system’s rc_conf_files includes the path or that the corresponding rc framework loads that directory. Prefer modifying the existing local file identified by sysrc -l unless there is a documented configuration-management policy for separate files.
Make one idempotent change and inspect the diff
For ordinary assignments, quote values that contain spaces or shell metacharacters:
sysrc ntpd_enable="YES"
sysrc ntpd_flags="-g"
sysrc ntpd_enable ntpd_flags
The assignment is persistent but does not call service ntpd start or restart the daemon. If the service is already running, changing its flags generally requires a controlled restart to take effect. Consult the service manual and rc script because not every setting has the same apply behavior.
The += and -= forms append to or remove items from list-like variables. They are not a universal safe merge operation for every rc value: a variable may be interpreted as a shell string, a whitespace-delimited list, or a service-specific mini-language. Read the owning manual page and inspect the exact resulting value:
sysrc cloned_interfaces+="gif0"
sysrc cloned_interfaces
sysrc cloned_interfaces-="gif0"
This example illustrates list editing only. It does not create or destroy an interface. A value can also contain a literal plus or minus character, so quote and test uncommon assignments carefully. Avoid multiple concurrent writers to the same rc file; separate edits can race or make a review diff misleading.
Use the check-only mode to test whether a change would be needed before an automation run. A check result is about configuration drift, not the runtime state of the daemon. Build scripts should handle nonzero status explicitly rather than interpreting all failures as “value is absent.” For multi-host automation, first run read-only queries against a representative host and compare the current value to the desired value before rolling out.
Separate configuration, enablement, and service state
Three questions are often conflated:
- Is the desired value present in the rc configuration?
- Is the service enabled by its rc variable?
- Is the daemon currently running and serving the intended workload?
sysrc answers the first two as saved policy. service(8) status can help answer whether an rc-managed process is present, but a process can be running and still fail its protocol-level health check. Use the application’s own status endpoint or a real client transaction for the third question.
For example, writing nginx_enable="YES" arranges for the rc framework to consider nginx at startup. It does not validate its configuration, bind its listening sockets, or prove that a reverse proxy can reach its upstream. A safe rollout checks the config with the service’s native validation command, starts or reloads it deliberately, inspects logs and listeners, and tests a request from the relevant network path.
Similarly, changing an interface variable in rc.conf does not necessarily reconfigure the live interface immediately. A network restart can interrupt SSH and may remove the very route needed to correct the mistake. Make such changes from a console or out-of-band path, keep a timed rollback if appropriate, and verify addresses, routes, DNS, and reachability before ending the maintenance window.
Validate and roll back by configuration ownership
Before editing, save the complete relevant file with permissions and ownership preserved, and record the effective value:
cp -p /etc/rc.conf /etc/rc.conf.pre-change
sysrc -a > /var/tmp/rc-values.before
For a focused review, inspect the file diff and query the value again:
diff -u /etc/rc.conf.pre-change /etc/rc.conf
sysrc service_name_enable service_name_flags
Replace the placeholders with the actual service variables. If a configuration-management agent owns /etc/rc.conf, make the source-of-truth change there instead of creating unmanaged local drift. A later agent run may overwrite a manual edit, and simply rerunning sysrc can create a split-brain configuration process.
Rollback means restoring the old setting in the authoritative file, then deciding whether the running service must be reloaded or restarted to return to the prior behavior. It is not enough to restore a text file while leaving a changed daemon state in place. Conversely, a service restart should not be used as a generic way to make every rc value “take effect”; some values are consumed only at boot or by a different subsystem.
Jail and alternate-root scope
sysrc supports operations against a jail or an alternate root in releases that document the relevant options. Those options change the target filesystem context; they do not prove that the target’s service is running or that a host-level restart is appropriate. Confirm the jail identity, mounted root, target rc files, and release compatibility before modifying remote or offline state. Avoid running a host service command after changing a jail’s configuration unless the operation explicitly targets that jail.
For a fleet, the most reliable pattern is declarative: query, compare, change one variable, re-query, render a diff, apply service-specific actions, then perform an application health check. Use a test machine and staged rollout for values that can affect boot, routing, firewalling, storage, or authentication. Record the exact FreeBSD release, rc file, current and requested value, operator, change identifier, runtime action, and rollback result.
Acceptance criteria should be measurable: the expected file contains one intended value, sysrc returns the expected effective setting, the rc service reports the desired enablement, a fresh boot or controlled service action behaves as documented, and a real application check passes. If any of those checks disagree, stop and identify which layer owns the discrepancy instead of repeating writes.
Related:
- How to Place FreeBSD Tunables in sysctl.conf, loader.conf, or rc.conf Correctly
- FreeBSD’s rc.d Init System: Scripts, Dependencies, and Service Ordering
Sources: