As noted in earlier chapters, the OpenBSD kernel includes a variety of parameters known as system controls, or sysctls. Some sysctls are static and can be viewed but not changed. The root account can change others, either at runtime or at boot.
Sysctls allow an application to retrieve information from the kernel. They also let a sysadmin change system behavior without reconfiguring applications, recompiling the kernel, or rebooting. You can view sysctl values and adjust those that can be changed with sysctl(8)
.
That said, just because you can change sysctls doesn’t mean you should change them. The OpenBSD developers set the sysctls to default values that work well for most environments. You might need to change one or two for your system, but if you find yourself changing sysctls all over the place, you’re probably sending yourself down the sysadmin rabbit hole.
The kernel presents sysctls in a MIB tree. As you learned in Chapter 16, MIB trees organize information into hierarchical categories. The top-level categories include kern
(kernel), vm
(virtual memory), net
(networking), hw
(hardware), machdep
(machine-dependent values), and so on. Each of these categories has additional subcategories. For example, net
has the categories inet
(IPv4) and inet6
(IPv6). The inet6
MIBs have subcategories ip6
(general IPv6 characteristics) and icmp6
(ICMP for IPv6). When you reach the end of categories, you’ll find individual MIBs like these:
net.inet6.ip6.forwarding=0
This MIB configures forwarding IPv6 packets between interfaces, turning the host into the router. How do I know? I’ve read it in the documentation, and it’s a commented example in /etc/sysctl.conf. OpenBSD doesn’t maintain a central list of sysctl values, but the man pages refer to any related sysctls.
If you want to explore sysctls, get a list from your system, as described next.
Use sysctl(8)
to view the sysctls available on a system.
$ sysctl kern.ostype=OpenBSD kern.osrelease=5.2 kern.osrevision=201211 kern.version=OpenBSD 5.2-current (GENERIC) #287: Tue Aug 21 18:15:00 MDT 2013 [email protected]:/usr/src/sys/arch/i386/compile/GENERIC …
This particular system has more than 400 sysctls. Interpreting the kern.ostype
and kern.osrelease
sysctls is fairly straightforward, but why would an OpenBSD system have a sysctl to report the operating system?
The sysctl(3)
interface appears in all BSD-derived operating systems and even in Linux, so checking the kern.ostype
sysctl, or checking for its existence, is a good way for third-party software to identify the operating system. kern.osrevision
is just the year and month this particular snapshot was built. kern.version
is the kernel compilation information displayed at boot. That’s not hard, is it? Let’s look at the next few sysctls:
kern.maxvnodes=5926 kern.maxproc=1310 kern.maxfiles=7030 kern.argmax=262144
Figuring out what these do is a little harder than interpreting the previous sysctl names. An experienced sysadmin could make really good guesses about these, but guessing isn’t system administration. Always research sysctls before changing them.
When you know the name of a sysctl and you want to view its current value, give the sysctl name as an argument to sysctl
. For example, to view the current securelevel (discussed in Chapter 10), check the kern.securelevel
sysctl.
$ sysctl kern.securelevel
kern.securelevel=1
The current value of kern.securelevel
is 1.
You can view subsets of the sysctl tree by giving just the part of the tree you’re interested in. For example, to view only the sysctls related to ICMP, check the sysctl net.inet.icmp
subcategory.
$ sysctl net.inet.icmp
net.inet.icmp.maskrepl=0
net.inet.icmp.bmcastecho=0
net.inet.icmp.errppslimit=100
net.inet.icmp.rediraccept=0
net.inet.icmp.redirtimeout=600
net.inet.icmp.tstamprepl=1
OpenBSD has six sysctls for IPv4 ICMP networking. You can view any portion of the sysctl tree this way, going as deep or as shallow as you like.
Some sysctls are read-only. For example, the hw.ncpufound
sysctl shows how many processors the system has.
$ sysctl hw.ncpufound
hw.ncpufound=1
This system has one processor. You cannot change the number of hardware processors through software (duh).
On the other hand, a system decides whether or not to forward packets in software. OpenBSD performs packet forwarding entirely in the kernel, like embedded firewalls and routers. The sysctl net.inet.ip.forwarding
controls this feature. If this is set to 0
, packets are not forwarded. If it’s set to 1, the system routes packets.
$ sysctl net.inet.ip.forwarding
net.inet.ip.forwarding=0
To change this, use the equal sign to assign a new value.
# sysctl net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
If you need to stop forwarding packets, set this sysctl to 0
.
Changes take effect immediately. Remember that only root can change sysctl values.
Most sysctls have a numerical value, but the interpretation of that number depends on the sysctl. A few sysctls are words, and some generate tables.
Some sysctls are Boolean—either on or off. For example, IP forwarding is either on or off. You can’t have 50 percent packet forwarding on a properly functioning system.
Other numerical sysctls have a range of valid numbers. For example the kern.securelevel
sysctl can range from -1
to 2
, as discussed in Chapter 10. While you could assign a value outside this range, it wouldn’t have any effect beyond the closest valid value.
Some sysctls have numerical values that map directly to some kernel value. For example, the kern.maxproc
sysctl gives the maximum number of processes that the system can run. You can adjust this value as needed to support your applications. While there’s no maximum value, increasing kern.maxproc
increases the memory used by various in-kernel tables. By the same token, there’s no minimum size, but if you reduce this setting too far, the system won’t run correctly.
A few sysctls are words, such as the kern.ostype
sysctl examined earlier. Most of these sysctls cannot be changed with sysctl
, but some can be changed with other programs. For example, the sysctl kern.hostname
gives the system’s hostname. You cannot change kern.hostname
with sysctl
, but you can change it with hostname(8)
.
In addition to words and numbers, some sysctls generate output in the form of tables. These sysctls are not intended for direct human consumption, but are meant for processing by dedicated userland programs. For example, netstat(1)
reads table sysctls to create its output.
To view all sysctls, including tables, pass the -A
option to sysctl
.
$ sysctl -A
Many table sysctls still won’t print (they will generate warnings that you should use program such-and-such to view that data), but you’ll get a few tables amid the regular output.
And by the way, tabular sysctls are read-only.
Sysctl changes are not permanent; they revert when you reboot. To make sysctl changes permanent, set them in /etc/sysctl.conf.
Changes specified in sysctl.conf take place early in the booting process, before any server software starts. For example, if you need to customize the network stack, those changes should take place before the system opens any network connections. List the sysctls you need to change, an equal sign, and the desired value in sysctl.conf.
The default sysctl.conf contains commonly changed sysctls (those that the OpenBSD team expects you might reasonably want to change). Each is commented out with a pound sign (#
) and set to the most common nondefault setting. If you want to change the sysctl, uncomment the entry.
The following are some commonly changed entries from sysctl.conf. (You might have different entries in your system, depending on your OpenBSD version.)
net.inet.ip.forwarding
This controls forwarding of IPv4 packets between interfaces. When set to
1
, the system forwards packets received on any interface according to the internal routing table. When set to0
(the default), packets are not forwarded.
net.inet.icmp.rediraccept
This determines whether the host will accept ICMP redirects. Routers send ICMP redirects to direct hosts to use different local gateways for more specific routes. While the router can forward the packets for the clients, using redirects reduces network load. Accepting ICMP redirects means the host could be redirected to an invalid gateway, however, so they can be a security issue. Set this to
1
to accept ICMP redirects. The default of0
ignores ICMP redirects.
net.inet6.ip6.forwarding
This controls the forwarding of IPv6 packets, much like
net.inet.ip.forwarding
does for IPv4 packets. You can control IPv4 and IPv6 forwarding separately. Set this to1
to forward IPv6 packets.
net.inet6.icmp6.rediraccept
By default, OpenBSD ICMPv6 ignores redirects, just as it ignores IPv4 ICMP redirects. Set this to
1
to accept ICMPv6 redirects.
net.inet6.ip6.accept_rtadv
IPv6 autoconfiguration listens for router advertisements, much as IPv4 autoconfiguration listens for configurations from DHCP servers. To autoconfigure IPv6, a host must accept router advertisements. Set this to
0
to disable accepting router advertisements.
net.inet.tcp.always_keepalive
The TCP keep-alive feature sends packets over otherwise idle connections so that intermediate devices will recognize that a connection is still in use. Proper firewalls recognize live but idle TCP connections even without keep-alives. If you have a broken firewall or NAT device, TCP keep-alives can help hold a connection alive. Set this to
1
to enable keep-alives.
net.inet.tcp.ecn
By default, OpenBSD’s TCP stack does not use Explicit Congestion Notification (ECN). Set this to
1
to enable ECN.
ddb.panic
OpenBSD uses the
ddb(4)
kernel debugger. If you want the system to drop into the debugger in the unlikely event of a kernel panic, leave this at1
. If you want the system to reboot as soon as possible, set this to0
.
ddb.console
When set to
1
, this enables entering theddb(4)
debugger from the console when someone presses CTRL-ALT-ESC. This option is primarily of interest to developers.
vm.swapencrypt.enable
By default, OpenBSD encrypts all data written to swap. To disable encrypting swap, set this to
0
. There’s really no reason to disable swap encryption, because encrypting swap space induces minimal system load.
machdep.allowaperture
This controls userland program access to the memory that userland really shouldn’t be able to access. The X Windows System needs access to this memory to display a graphical console. (Chapter 17 covers this sysctl and X.)
machdep.kbdreset
On amd64 and i386 systems, setting this to
1
allows you to press CTRL-ALT-DEL on the console to do a clean shutdown and reboot. When set to0
(the default), pressing CTRL-ALT-DEL has no effect.
As a rule, if you don’t understand the thing that a sysctl affects, don’t change it. You won’t learn about RFC 3390 by playing with a sysctl related to it; you’ll learn about RFC 3390 by actually reading RFC 3390 and spending quality time with a packet sniffer watching traffic with RFC 3390 disabled and enabled.
And if you want to change a sysctl that’s not listed here, think twice. If the OpenBSD guys wanted you to change it, they would list it in sysctl.conf.