System and Network Security - Kernel Options

Kurt Seifried, [email protected], Copyright Kurt Seifried 2002


 

When you ask most network and system administrators about system and network security, they'll respond, "We have a firewall" or "We use SSL encryption." This is all fine and good. However, there are often some things they have missed - not that it is really their fault, since these additional options are not very well documented in most cases. Almost all Unix-based operating systems have the capability to modify various kernel options while the system is running. I'll be concentrating on Linux, *BSD and Solaris.

All three have different facilities for modifying kernel configuration on the fly. Solaris uses ndd and generally manipulates /dev/ entries; Linux uses the /proc interface; and BSD uses sysctl to "get or set kernel state" (quote from man sysctl). For my examples I will be using Solaris 8.0 on an Ultrasparc, Red Hat 7.0 and OpenBSD 2.8, both on Intel platforms.

Where to Find and How to Set the Options

BSD's sysctl is probably the easiest to use. Simply execute

sysctl -a

to get a listing of all the options available, and what their current settings are. "man sysctl" also tells you what type of data it is and whether (and how) you can modify it.

In Linux, you will need to

cat /proc/foo/bar

for each setting to see what it is set to. For a list of all the possible options, get a copy of the kernel source code (usually in /usr/src/linux). The file "Documentation/networking/ip-sysctl.txt" lists their defaults and so on. Another useful file in the Linux kernel source is "Documentation/proc.txt," which covers /proc in general.

In Solaris, ndd lets you "get and set driver configuration parameters." It only applies to network-related items right now. Solaris also lets you query all the options available. Simply run

ndd /dev/foo

where "foo" is one of: arp, ip, ip6, tcp, tcp6, udp, udp6, rawip, rawip6, hme (or other network interfaces). There are probably some I missed, but these will give you a good start. Then enter a "?" at the prompt to list all the options you can fiddle with. You can also issue the "?" with the device to get a list of options.

ndd /dev/tcp ?

Routing Data

So, why would you want to modify the kernel on the fly - what good could it possibly do you from a security point of view? A simple example would be the need to route packets on a system. In almost all operating systems, this is disabled by default. Enabling it by default would create a large security risk in many environments. Requiring someone to build a new kernel capable of routing packets would be extremely troublesome, so instead most operating systems have the capability built in, just disabled by default. In Linux this would be accomplished by:

echo "1" > /proc/sys/net/ipv4/ip_forward

In OpenBSD, with:

sysctl -w net.inet.ip.forwarding=1

And in Solaris:

ndd -set /dev/ip ip_forwarding 0

As you can see, the exact syntax varies but the general idea is the same.

Source Routed Packets

Generally speaking, the only people that would want to source route packets are hostile attackers. Source routing can be useful for sliding packets around firewalls and IDS systems or targeting specific machines. The default in Linux is to disable source routed packets in the kernel, and many firewalls also allow you to block source routed packets, however it is just as easy to block them at the OS level.

In Linux, simply have a bash script.

for i in /proc/sys/net/ipv4/conf/*/accept_source_route 
do
	echo 0 > $i
done

This will do all the interfaces - lo, eth0, ppp0, etc.

In OpenBSD, you would:

sysctl -w net.inet.ip.sourceroute=0

However, this is disabled by default, so you shouldn't need to take care of it.

In Solaris,

ndd -set /dev/ip ip_forward_src_routed 0

This will also set ip_forward_source_routed to 0 on /dev/tcp, /dev/udp and other appropriate devices (tcp6, ip6, etc.).

And now for some OS-specific options.

Solaris

Solaris has some of the coolest options, in my opinion. You can add and remove privileged ports arbitrarily. For example, to make port 2049 (udp) privileged:

ndd -set /dev/udp udp_extra_priv_ports_add 2049

You can also make ports non-privileged, but remember that if you do so, some security implications arise. For example, if you have port 2049 as a privileged port, but you then remove that privileged status, it is possible for a local user to run an NFS service should the "real" one crash or otherwise be disabled. You should be cautious in making ports non-privileged. Most services now drop root immediately once they have bound to the privileged port, or only run a small control program as root - Apache, Bind, Postfix, etc.

Also, in Solaris you can set the following in /etc/system.

set noexec_user_stack = 1
set noexec_stack_user_stack_log = 1

This should provide some protection against malicious code, although I wouldn't bet the farm on it, as there are ways to avoid this type of thing, assuming it works properly.

Linux

Linux has a nice option for multihomed hosts. If you have a Linux box set up as a router for a reasonably small network (i.e., it's not a core router), then you can use reverse path filtering to prevent IP spoofing. While you can also do this with a firewall, it requires less effort and maintenance to do it with the kernel option. The default is to set it to 1, which is reasonably safe. For more security you may wish to set it to 2; however, this will have a performance hit and there are some situations in which your network may be configured in such a way that having strict reverse path checking breaks.

for i in /proc/sys/net/ipv4/conf/*/rp_filter
do
	echo 1 > $i
done

OpenBSD

In OpenBSD you can easily modify the behavior of TCP and UDP. You can set the port ranges for outgoing connections, which will allow you to build very tight firewall rules if you wish to do so. The sysctl properties (and their defaults) are:

net.inet.ip.portfirst = 1024
net.inet.ip.portlast = 49151
net.inet.ip.porthifirst = 49152
net.inet.ip.porthilast = 65535

To set net.inet.ip.portfirst to a higher number, simply:

sysctl -w net.inet.ip.portfirst = 10240

Summary

As you might now realize, there are many hidden or poorly documented security features available in most operating systems. While the majority of people can't be bothered to take basic security measures, there is a growing population of administrators who are willing to do whatever it takes to harden their networks and make them less vulnerable to security incidents. Hopefully vendors will better document these features, if enough demand appears - which is doubtful. So if you find anything interesting, share it with your peers.

 


Back

Last updated 03/08/2002

Copyright Kurt Seifried 2002