Securing SNMP on Solaris
Reg Quinton
Solaris 8 (also known as Sun OS 5.8) is often configured with
a large suite of network services, including several daemons for
the Simple Network Management Protocol (SNMP) and related services,
especially the Desktop Management Interface (DMI). If you are concerned
with the security of your system, you should consider eliminating
or hardening each service offered (see recommendation of CERT Coordination
Center). The default SNMP configuration, while perhaps reasonably
secure, can be made substantially more secure with a little effort.
If you require SNMP services (e.g., to monitor a server in case
of failover), you should configure it better. Recommendations are
provided in the Sidebar "What Have We Sacrificed".
I believe the observations made here apply equally to Solaris
7 and Solaris 2.6 (the two previous releases of Solaris) but have
not confirmed that on both platforms.
The Problem
We have a Solaris 8 system (call it wally) that was configured
with default SNMP services as provided by the vendor. Our operations
staff monitor the status of the system using the InterMapper, and
we wanted to restrict the SNMP service on our Solaris 8 system to
just that one station (call the monitor ratbert) see the Intermapper
Sidebar. Our basic problem is to configure wally to only answer
SNMP questions from ratbert.
Why would we even consider this problem -- the ratbert system
is busy monitoring wally, what's the big deal? Some things
to consider:
1. Given that you've done nothing special to allow ratbert
to monitor wally, what's to prevent others from doing the same
thing? Hackers use SNMP to profile a system before launching an
attack.
2. SNMP includes get and set commands -- if
ratbert can get information, what's to prevent it, or anyone
else for that matter, from setting values?
3. Any time you offer a network service, you're open to several
attacks. Here are some of the obvious:
- A simple Denial of Service attack making many connections or
sending a lot of data in hope of bringing the system to its knees.
- While ratbert always sends well-formed SNMP messages, what's
to prevent hackers from sending data that compromises the system?
Remember the "Morris Worm"?
If you are familiar with the Solaris history, you will recall
that there have been serious security problems with SNMP services.
If you follow Sun updates and patches, you know that there are
security fixes for these services. A lesson we've learned
the hard way is that no network service can be considered "risk
free."
What We Learned
This section documents our efforts to answer the questions
noted above and secure the SNMP service on a Solaris 8 system.
If you're interested in quick answers, you can safely skip
to the recommendations that follow. If you're interested
in how we came to those recommendations, this section is worth
reading.
I know very little about SNMP, but I do know that's it's
often used to monitor systems and sometimes used to control
them. Typically, network operations use tools (like the InterMapper
noted above) that rely on SNMP to detect and resolve networking
problems like router outages.
A quick peek at our system with ps(1) and lsof(1)
to find SNMP services reveals a couple of candidates to investigate:
[1:28pm wally] ps -ef | grep snmp
root 808 1 0 Oct 03 ? 0:00 /usr/lib/snmp/snmpdx -y -c /etc/snmp/conf
root 815 1 0 Oct 03 ? 0:00 /usr/lib/dmi/snmpXdmid -s wally
reggers 12675 9473 0 14:09:24 pts/2 0:00 grep snmp
[1:29pm wally]# lsof -i | grep snmp
snmpdx 808 root 4u inet 0xf61c8418 0t0 UDP *:snmp (Idle)
snmpdx 808 root 5u inet 0xf61c8568 0t0 UDP *:33037 (Idle)
snmpdx 808 root 6u inet 0xf6459c70 0t0 UDP *:33038 (Idle)
snmpXdmid 815 root 0u inet 0xf61c84f8 0t0 UDP *:33031 (Idle)
snmpXdmid 815 root 1u inet 0xf6459f80 0t0 TCP *:32792 (LISTEN)
snmpXdmid 815 root 6u inet 0xf6459d50 0t0 UDP *:33033 (Idle)
snmpXdmid 815 root 7u inet 0xf6459ce0 0t0 UDP *:6500 (Idle)
We were expecting a simple daemon listening on one port for SNMP
requests, and we've found two daemons listening on seven
different service ports. The manual pages tell us that snmpdx(1M)
is the Sun Solstice Enterprise Master Agent while snmpXdmid(1M)
is the Sun Solstice Enterprise SNMP-DMI mapper subagent. It turns
out that there is an incredibly complicated web of service dependencies.
The snmpdx process that's listening at the "snmp"
port is a master that spawns off "subagents" (i.e.,
processes) to do the work -- an important one is mibiisa(1M).
The snmpdx process starts the mibiisa(1M) process
and instructs it to listen on a particular port. By default
it would listen to the "snmp" port, but that's
busy with the snmpdx process. SNMP requests received
by the snmpdx process (at the "snmp" port)
are sent to mibiisa(1M), and the answers returned to
the snmpdx process are then returned to the client who
made the request. That's a simple relaying operation.
The snmpdx process also relays SNMP traps that the
subagents generate, but nothing had been configured -- our
manager ratbert only polls wally. Traps are event-driven interrupts
such as, "Hey ratbert, I just ran out of memory!"
We weren't using any of them.
These processes are started at boot time from /etc/rc3.d/S76snmpdx.
Likewise, the snmpXdmid is a subagent that processes
"snmp" requests (received on some other port) and
spawns off a sub-process dmispd(1M). The snmpXdmid
process accepts SNMP requests from snmpdx and translates
them into DMI requests serviced by the dmispd process.
That's a translate and relay.
The snmpXdmid process also relays certain DMI events
as SNMP traps. But again, nothing had been configured. These
processes are started at boot time from /etc/rc3.d/S77dmi.
Our simple problem has now become even more complicated:
[1:31pm wally]# ps -ef | egrep 'dmi|mib|snmp'
root 814 1 0 Oct 03 ? 0:01 /usr/lib/dmi/dmispd
root 808 1 0 Oct 03 ? 0:00 /usr/lib/snmp/snmpdx -y -c /etc/snmp/conf
root 838 808 0 Oct 03 ? 1:38 mibiisa -r -p 33036
root 815 1 0 Oct 03 ? 0:00 /usr/lib/dmi/snmpXdmid -s wally
root 12340 12307 1 13:32:41 pts/2 0:00 egrep dmi|mib|snmp
[1:31pm wally]# lsof -i | egrep 'dmi|mib|snmp'
snmpdx 808 root 4u inet 0xf61c8418 0t0 UDP *:snmp (Idle)
snmpdx 808 root 5u inet 0xf61c8568 0t0 UDP *:33037 (Idle)
snmpdx 808 root 6u inet 0xf6459c70 0t0 UDP *:33038 (Idle)
dmispd 814 root 3u inet 0xf61c85d8 0t0 UDP *:33030 (Idle)
dmispd 814 root 4u inet 0xf6459e30 0t0 TCP *:32793 (LISTEN)
snmpXdmid 815 root 0u inet 0xf61c84f8 0t0 UDP *:33031 (Idle)
snmpXdmid 815 root 1u inet 0xf6459f80 0t0 TCP *:32792 (LISTEN)
snmpXdmid 815 root 6u inet 0xf6459d50 0t0 UDP *:33033 (Idle)
snmpXdmid 815 root 7u inet 0xf6459ce0 0t0 UDP *:6500 (Idle)
mibiisa 838 root 0u inet 0xf6459c00 0t0 UDP *:33036 (Idle)
We assumed one process listening at the "snmp" port
but found four processes listening at ten ports, which is considerable
exposure. How can this be managed? The vendor has provided us
with a system that's far too complex -- complex systems are
always less secure than simple systems. We have to simplify.
Our first success was to determine that we could safely disable
all DMI services with no loss of functionality for the InterMapper
at ratbert. That eliminates two processes listening at six different
ports. We assume there are some SNMP requests that can only
be answered by the dmispd(1M) daemon. But we're
not using them!
At least some of those DMI services are delivered as RPC services;
you'll find them using rpcinfo. With a little digging,
you'll discover that both daemons are offering RPC services.
By contrast, SNMP services are not layered on RPC. We assume,
but cannot confirm, that you cannot run DMI services without
also running rpcbind, which is the rendezvous point to
translate RPC service numbers into TCP/UDP port numbers. We
turned our attention to the snmpdx(1M) and mibiisa(1M)
processes, which are configured from files found in /etc/snmp/conf.
The file names are a little confusing --- snmpd.conf
configures mibiisa(1M), while snmpdx.acl configures
snmpdx(1M). There are other configuration files but we
only looked at these.
The manual page for snmpdx(1M) is pretty minimal, but
it points to an access control file snmpdx.acl that looked
promising. Unfortunately, there's no manual page for that,
and the commentary in the access control file provided does
not correspond at all to the Solaris Answerbook, which is available
in the Sun Product Documentation. Nevertheless, we spent several
hours working with the configuration trying variations:
1. Uncommenting this stanza, killing and restarting the daemons,
results in syslog gripes:
# The list of hosts that can send SNMP queries.
# If this list is empty, all the hosts are allowed to
# send SNMP queries.
#managers = {
#}
The managers = fragment is not recognized at all --
it's a syntax error. There are several top-level stanzas
in the vendor-provided configuration. The only allowed stanzas
according to the Answerbook and our tests are acl= and
traps=.
2. We tried changing the "managers" list on this
stanza (again killing and restarting the daemons after each
change):
# The list of community names needed for read/write access
# to the entire MIB.
# If the list is empty, the only valid community name is "public"
# and its access type is read-only
acl = {
{
communities = public, private
access = read-write
managers = *
}
}
But no matter what we did, the server always responded to ratbert.
We were also concerned with what looks like "read-write"
access to both the public and the private data.
We finally gave up on configuring the snmpdx process
and turned our attention to the mibiisa daemon. The manual
page for mibiisa(1M) is very good and even has a section
on security. The default configuration, when stripped of commentary,
looks something like this:
sysdescr Sun SNMP Agent, SPARCstation-10
syscontact System administrator
sysLocation System administrators office
system-group-read-community public
read-community public
trap localhost
trap-community SNMP-trap
managers localhost
We determined that the vendor configuration restricted the daemon
to provide responses only to the localhost (i.e., to the same
system). That's the "managers" line. We ran the
daemon in a debug mode to verify that, as configured, it would
not respond to anyone other than the "managers" listed
in the configuration file. Changing the "managers" to
include ratbert meant the InterMapper got the information it needed.
Conclusion
After considerable effort, we've determined that there
are few unnecessary services, and we can safely configure one
daemon to restrict it's attention to a list of authorized
managers. That's all we needed to satisfy our InterMapper
requirements. If your requirements are similar to ours, you
might try our configuration to satisfy your needs while minimizing
your exposure.
Recommendation
To configure public SNMP services on a Solaris 8 server and
restrict the service to a short list of managers, we recommend:
1. Be sure you have configured syslogd(1M) to be far
more thorough about logging what's happening. We recommend
a detailed audit (at least during the install):
[2:39 wally] grep /syslog /etc/syslog.conf
#mail.debug ifdef('LOGHOST', /var/log/syslog, @loghost)
*.debug ifdef('LOGHOST', /var/log/syslog, @loghost)
The default configuration is to log everything wrt. mail services
at the debug level to the file /var/log/syslog. We recommend
you log everything to the same file. When things go wrong, as
they sometimes do, a good audit trail will be important.
2. Stop the vendor-provided SNMP and DMI services on your
system:
[2:40pm wally]# cd /etc/init.d
[2:40pm wally]# ./init.dmi stop
[2:40pm wally]# ./init.snmpdx stop
If you want to restart those services, run the shell scripts with
a "start" option instead. You may find these scripts
with different names on other versions of Solaris (but I suspect
not).
3. Configure the boot sequence so the vendor-provided SNMP
and DMI services aren't restarted at next reboot:
[2:41pm wally]# cd /etc/rc3.d
[2:41pm wally]# mv S76snmpdx No.S76snmpdx
[2:41pm wally]# mv S77dmi No.S77dmi
Renaming the startup scripts effectively removes them from the
boot sequence. You may find these scripts with different names
on other versions of Solaris, but I doubt it.
4. Configure the "managers" that can send SNMP requests
to the mibiisa(1) server -- edit the snmpd.conf
file. Here's what we use (note that we've filled in
the "system" information, restricted the service to
only "public" information, tossed anything to do with
"traps", and restricted the managers to just ratbert):
[2:43pm wally]# cd /etc/snmp/conf
[2:43pm wally]# egrep -v '^$|^#' snmpd.conf
sysdescr Sun SNMP Agent, SPARCstation-10
syscontact dilbert@ist.uwaterloo.ca
sysLocation IST Machine Room, Rack 4, Tray 3
system-group-read-community public
read-community public
managers ratbert
The grep in the example tosses all commentary and empty
lines -- there's not much to the file. Note the configuration
shown only allows ratbert to query wally. It's a very simple
configuration -- we've even tossed the traps that we
didn't need. We've updated the "system" information
so we can find the system (its physical location) and the support
person.
5. Configure your boot sequence to bring up only the mibiisa(1M)
daemon. Make sure you bring it up in read-only mode. Here's
a sample configuration you might want to use:
#!/sbin/sh
#
# $Id: Solaris_SNMP_Harden.html,v 1.3 2000/10/27 21:00:54 reggers Exp $
#
# Start the minimal SNMP services required for select managers to get public
# data. Install as /etc/rc3.d/S99mibiisa (or insert into your favorite local
# boottime script). Make sure you disable S76snmpdx and S77dmi in the same
# directory.
#
# Reg Quinton <reggers@ist.uwaterloo.ca>; 5-Oct-2000
case "$1" in
'start')
/usr/lib/snmp/mibiisa -r </dev/null >/dev/null 2>&1 &
;;
'stop')
/usr/bin/pkill -9 -x -u 0 'mibiisa'
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
exit 0
The script should be installed in /etc/rc3.d and made executable.
6. Finally, you can start the daemon manually (it will be
started automatically at next reboot if you installed the script
in /etc/rc3.d):
[2:45pm wally]# ./S99mibiisa start
[2:45pm wally]# ps -ef | grep mibiisa
root 19762 1 0 11:55:35 ? 0:00 /usr/lib/snmp/mibiisa -r
[2:45pm wally]# lsof -i | grep snmp
mibiisa 19762 root 2u IPv4 0x300011f8660 0t0 UDP *:snmp (Idle)
If the daemon fails to start, you should check the audit trail
in /var/log/syslog. If you follow these recommendations,
you will have eliminated three daemons (snmpdx(1M), dmispd(1M),
and snmpXdmid(1M)) and nine network entry points. You'll
now have only one daemon (mibiisa(1M)) and one network
entry point -- the snmp port serviced by that daemon.
You will have made your system more secure.
References
Sun Blueprints Online -- see the security papers.
Sun Product Documentation -- includes Answerbook.
SUNSOLVE ONLINE -- includes vendor patches.
The Solaris Security FAQ (Sunworld, Peter Baer Galvin).
Reg Quinton is a security professional at the University
of Waterloo in Ontario, Canada. He has been working with UNIX
systems in the education environment since 1983. His home page
is http://ist.uwaterloo.ca/~reggers. This paper
is an extract of a larger work in progress on Solaris Network
Hardening
|