Introduction
The Solaris kernel provides a great deal of user-configurable control over the system TCP/IP stack. Everything from cache table lifetimes to the number of TCP connections that the system can address are controllable. However, without understanding the underlying need for tuning these kernel parameters many system administrators choose to ignore them – thereby leaving their systems vulnerable to a resourceful assailant.
Solaris Kernel Tools
The only tool available to Solaris system administrators for tuning kernel parameters is ndd. Currently, ndd only supports the TCP/IP kernel drivers. It can be used to both show and set the values of parameters for these drivers.
Solaris Kernel Parameters
In general to show a particular parameter the command format is:
# ndd /dev/
# ndd /dev/
To set a kernel parameter using ndd, the format of the command is:
# ndd -set /dev/
Unfortunately, changes to the Solaris kernel parameter values using ndd are not permanent. The values for these parameters return to default upon system reboot. To make these changes more permanent a system administrator needs to put these changes into a shell script that is run at system boot (one possible location would be /etc/init.d/inetinit or in a separate shell script). One of the primary problems with setting these parameters into a shell script is that the parameters are implementation-specific and may change from one Solaris release to another.
ARP
ARP (Address Resolution Protocol) is used to dynamically map layer-3 network addresses to data-link addresses. When one system wants to communicate with another system on a network it first sends an ARP packet to the broadcast address, FF:FF:FF:FF:FF:FF. The packet asks the simple question: “who has network address A?…tell network address B”. Since all hosts on a network receive these broadcast packets, system A receives the ARP request and sends back a response. The originating host then uses the responses to its ARP broadcasts to build a table, or cache, mapping the 32-bit IP addresses to Layer-2 hardware, or MAC, addresses. A second table is maintained by the network layer. This table is built from information provided by the data-link layer and contains network-routing information for active connections. The network layer requests MAC addresses from the data-link layer and inserts these addresses into a network routing table. Network routing entries expire after 20 minutes.
When a network host prepares to communicate with another the IP layer checks the ARP cache first. If an entry for the network peer does not exist in the cache, an ARP request is broadcasted. ARP cache entries expire after five minutes.
The ARP cache is susceptible to two types of attacks: ARP cache poisoning and ARP spoofing. ARP cache poisoning involves “inserting” either a non-existent ARP address or an incorrect ARP address into a system’s ARP cache. This results in a denial of service since the target system will send packets to the peer’s IP address but the MAC address will be incorrect.
ARP spoofing can result in system compromise. Just like IP spoofing, ARP spoofing relies on, first, disabling a host on the network so that it cannot reply to any ARP request broadcasts. Once that is done the attacker can configure the disabled host’s IP address on the attacking host. When the victim host tries to communicate with the disabled host the attacker’s system responds to any ARP request broadcasts, thereby inserting its MAC address in the victim’s ARP cache. Communication between the two hosts can then proceed normally.
It is very difficult to defend against ARP attacks. One defence against ARP attacks is to reduce the lifetime of cache entries. The cache lifetime is determined by the kernel parameter arp_cleanup_interval. The IP routing table entry lifetime is controlled by the kernel parameter ip_ire_flush_interval
# ndd -set /dev/arp arp_cleanup_interval
a) shorten the value of the abort timer, and
b) lengthen the TCP connection queue.
To shorten the abort timer the kernel parameter: tcp_ip_abort_cinterval can be used. The value for this parameter is given in milliseconds. By default the abort timer interval is 180 seconds. To set the abort time to 60 seconds the system administrator can use the command:
# ndd -set /dev/tcp tcp_ip_abort_cinterval 60000
The kernel parameter tcp_conn_req_max_q0 controls the queue size for unestablished TCP connections in Solaris 2.6 and above (or in Solaris 2.5.1 w ith patch 103581-11). The default value for tcp_conn_req_max_q0 is 1024. To increase the queue size the following command can be used:
# ndd -set /dev/tcp tcp_conn_req_max_q0 2048
Another type of SYN attack involves exhausting the TCP established connection queue. This attack is not as desirable as the TCP SYN attack mentioned above because of the fact that the connection can be traced back to its source, however, it still presents a problem. Solaris 2.6 and above (as well as Solaris 2.5.1 with patch 103582-11) provide control over the size of the established TCP connection queue. This control is provided by the kernel parameter tcp_conn_req_max_q. By default it is set at 128. To increase the established TCP connection queue, the command is:
# ndd -set /dev/tcp tcp_conn_req_max_q
where
Conclusion
The Solaris kernel has many configurable parameters that are security related. These parameters can be adjusted to strengthen the security posture of a system. The parameters cover such things as ARP timeouts, IP forwarding of packets, IP source routing of packets, TCP connection queue sizes, and many other factors governing network connections. By tuning the kernel properly a system administrator can even prevent OS fingerprinting of a Solaris system as provided by such tools as queso and nmap.