Command-Line FreeBSD Configuration: sysrc

The traditional BSD standard of “edit /etc/rc.conf” isn’t sustainable across large numbers of machines. If you must change dozens of servers you want a reliable way to alter the system without either manually editing every configuration file or some sed/awk hackery. (Running a sed/awk script to edit rc.conf on every server I own makes me nervous. I don’t do nervous these days.) FreeBSD 9.2 and later includes sysrc, a program to consistently and safely alter /etc/rc.conf and friends from the command line. (On older versions of FreeBSD, sysrc is available in ports.) I find sysrc very useful for Ansible-managed farms, but it should work just as well with Puppet or Chef or any configuration management system.

Start using sysrc by asking it what it knows about the system configuration.

$ sysrc -a
defaultrouter: 192.0.2.129
dumpdev: AUTO
hostname: mwltest3
ifconfig_em0: inet 192.0.2.160 netmask 255.255.255.128
keymap: us.dvorak.kbd
sshd_enable: YES

Oddly enough, this is exactly what’s in my rc.conf, minus all the comments and such.

I must enable ntpd(8) on this machine. Here, sysrc looks an awful lot like sysctl.

# sysrc ntpd_enable=YES
ntpd_enable: NO -> YES

Note that this doesn’t actually start ntpd, it merely enables it in the configuration. You must run /etc/rc.d/ntpd start or service ntpd start to start the daemon.

To disable a daemon, do the same thing in reverse.

# sysrc ntpd_enable=NO
ntpd_enable: YES -> NO

One potential problem with sysrc is that it’s a tool for editing /etc/rc.conf, not for configuring FreeBSD. It has no idea what legitimate values are. This means that if you make a typo, it propagates to rc.conf.

# sysrc ntpd_enable=YSE
ntpd_enable: NO -> YSE

Here sysrc works as advertised, but ntpd won’t. And you can arbitrarily enable nonexistent services.

# sysrc gerbil_enable=YES
gerbil_enable: -> YES

I do not have gerbils installed. But if I ever do install them, the gerbil wheel will start spinning without any further intervention.

I suspect that one day sysrc will grow a service integrity checker, but it solves my immediate needs.

Experienced FreeBSD administrators who run a small number of servers don’t need sysrc, but those of us with farms will find it invaluable. My thanks to Devin Teske for shepherding this into base.

6 comments to Command-Line FreeBSD Configuration: sysrc

  • D.F.

    I kind of like this particular tool. I’ll have to try it out if I can ever get my FreeBSD machine updated to a newer version.

    Back when I was fortunate enough to herd a largeish number of FreeBSD machines, I realized the problem of propagating changes to rc.conf . I was fortunate that the machines I herded were mostly part of a cluster and, as a result, had to have identical rc.conf files. I solved the problem then by pushing rc.conf to all the machines rather than editing one at a time.

  • Hubert Feyrer

    There’s already an ansible module to change /etc/rc.conf (at least for NetBSD). Of course this could be implemented via sysrc on FreeBSD…

    – Hubert

  • […] W. Lucas has a short article up about sysrc, a FreeBSD tool for handling rc.conf across multiple machines. ┬áThis could easily be a cross-BSD […]

  • Lazhu

    Awesome!
    Now we can say goodbye to the whole bunch of “echo blahblahblah >> /etc/rc.conf” in scripts

  • In case anyone is interested, for Linux there’s Augeas and it’s CLI tool – augtool – which can read and modify a variety of configuration files. A short example from the tour:

    Making sshd accept an additional environment variable [...]

    To add a new variable FOO at the end of the last AcceptEnv line, we perform

    set /files/etc/ssh/sshd_config/AcceptEnv[last()]/01 FOO
    save

  • P.S. There’s also a 3rd party Ansible module which exposes a simple API for match, set and rm operations. You can execute commands one by one or in chunk.

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>