Hardening Solaris

Securely installing a firewall bastion host

By Seán Boran

- a second Version of this article includes Solaris 8 and Yassp beta#5 (very old)
- a third version  includes Yassp beta#15
- a fourth version uses Jass (this is the most recent and up-to-date)
- This version will not longer be updated, but it is still useful, as it runs through MANUAL hardening, as opposed to allowing a tool like Yassp to do all the work for you.

Originally published October 25, 1999. This article presents a concise step-by-step approach to securely installing Solaris for use in a firewall DMZ, or other sensitive environment. There are many books and web articles on general hardening, but deciding exactly how to do it for your Solaris system can be tricky.

The focus in this article is on preparing the Operating System to securely run services, rather than the setup of the services themselves. Firewall engines like Raptor, Firewall-1, Sunscreen etc. are not examined here.

This article is specific to Solaris 2.7, other versions are similar, but will have some differences in startup file names, kernel parameters etc. It is planned to update this article for Solaris 8 when it is shipped in March 2000.
This article has been updated since the original release, see the Additional Notes section.

We welcome your feedback on this article.

We divide up the process into the following steps:

  1. Preparation
  2. Initial OS installation
  3. Stripping/configuring OS: 1st pass
  4. Connect to test network
  5. Installing tools & sysadmin software
  6. Stripping/configuring OS: 2nd pass
  7. Create Tripwire image, backup, test
  8. Install, test, harden applications.
  9. Install on live network, test

Additional Notes

1. Preparation

2. Initial OS installation

Connect the serial console, switch on, halt to the OK prompt by sending a Stop-A (~#, ~%b, or F5 depending on whether you use tip, cu or a vt100 terminal), then start the installation procedure -
"boot cdrom - install".

Install the minimum end user bundle (or even better the core packages), set hostname, terminal, IP parameters, timezone, etc. Don't enable naming services like NIS or NFS. Don't enable power management. Don't mount any remote file systems (NFS).

Choose manual disk partitioning: Keep /usr and /opt separate from root, so that they can be later mounted read-only (see below). Consider a separate, large /var filesystem for syslog/web/news/proxy servers. Servers containing lots of data (web, ftp) should use a separate disk for their data.
If you don't wish to mount partitions read-only, then put the whole boot disk under root.
Suggestion for a 2GB disk: 200MB / (+var), 200MB swap,  600MB /usr and 1GB on /opt.
Suggestion for a 1GB disk: 300MB / (+var+opt), 200MB swap,  500MB /usr.

Set a strong password (7 or 8 chars with numbers, letters and punctuation) for root, and reboot. 

No man pages are installed with the user bundle, so install some while the the Solaris CD is still mounted:

cd /cdrom/cdrom0/s0/Solaris_2.7/Product;
pkgadd -d . SUNWman SUNWdtmaz SUNWdtma SUNWjvman SUNWpmowm SUNWolman SUNWolman SUNWtltkm SUNWxwman SUNWxwpmn

Update indices, so that "man -k keyword" will allow searching of relevant man pages:

/usr/lib/makewhatis /usr/man; /usr/lib/makewhatis /usr/openwin/man;
/usr/lib/makewhatis /usr/local/man

Install the recommended & security patches from Sun. Typically a separate CD "Maintenance Release" is provided with a patch bundle. Reboot and logon again as root. The list of patches installed can be listed with showrev -p .

3. Stripping/configuring OS: 1st pass

Disk mounting: To reduce the risk of trojan horses and unauthorised modifications, in /etc/vfstab, mount / with options "remount,nosuid", /var with "nosuid", /tmp with "size=100m,nosuid" (allow /tmp to only use 100MB of swap space and disallow execution of SUID programs).

The commands listed below assume you use the C-Shell. If you use the C-Shell, the following will make editing easier and enable history functions:
  setenv TERM vt100; setenv VISUAL vi; setenv EDITOR vi;
  set filec; set history=40; alias h history; alias ls 'ls -aF \!*';

Shutdown the network interface during this phase, just in case (the interface name depends on the architecture e.g. hme0 or le0):

ifconfig le0 down

Disable NFS :

rm /etc/rc2.d/{S73nfs.client,K28nfs.server} /etc/rc3.d/S15nfs.server /etc/dfs/dfstab

Disable Sendmail daemon. Although sendmail is not running as a daemon, the binary is still present and email can be sent from (but not received by) the host. The only host that needs to receive email, the mail gateway, should use smap or an equivalent to minimise sendmail risks.

rm /etc/rc2.d/S88sendmail
And add a root cron entry to process the mail queue hourly:
0 * * * * /usr/lib/sendmail -q

Disable more services (automounter, power mgt., serial protocols, caching fs, etc.):

rm /etc/rc2.d/{S74autofs,S30sysid.net,S71sysid.sys,S72autoinstall} /etc/auto_*;
rm /etc/rc2.d/{S93cacheos.finish,S73cachefs.daemon,S80PRESERVE};
rm /etc/rc2.d/{S85power,K07dmi};
rm /etc/rc3.d/S77dmi;
If you have server/developer packages:
rm /etc/rc2.d/{S47asppp,S89bdconfig,S70uucp}

Disable RPC: This is highly desirable, but will break some programs like CDE or Disksuite. If you don't disable RPC, then a packet filter that blocks it is an absolute must.

rm /etc/rc2.d/S71rpc

Disable printing (unless there's a local printer attached):

rm /etc/rc2.d/{S80lp,S80spc}

Consider disabling the naming Services Caching Daemon: I've had problems with nscd (& Soalris 2.5) and don't like daemons running that I don't trust. It might offer performance advantages however, and some applications such as Netscape webproxy V3.5 needs it.

mv /etc/rc2.d/S76nscd /etc/rc2.d/.S76nscd

Disable CDE: unless you insisted on a graphical console?

rm /etc/rc2.d/S99dtlogin

Consider disabling NTP - Network Time Protocol. (NTP is accurate but complex, uses bandwidth and is an additional security worry. I prefer to use rdate to one central host, which then uses NTP to get accurate time). See also the additional notes below. To disable it:

mv /etc/rc2.d/S74xntpd /etc/rc2.d/.S74xntpd

Disable SNMP, unless you do really need to use HP Openview or whatever. I prefer simple ping/traceroute scripts. If SNMP is switched on, only allow read (not write) access and change the community string.

rm /etc/rc2.d/K07snmpdx /etc/rc3.d/S76snmpdx

Inetinit: Disable ip forwarding, source routing (if there is more than one network interface), and avoid echo broadcasts.  Add a few lines to the end of /etc/init.d/inetinit:

## hardening
ndd -set /dev/ip ip_forward_directed_broadcasts 0
ndd -set /dev/ip ip_forward_src_routed 0
ndd -set /dev/ip ip_forwarding 0
ndd -set /dev/ip ip_respond_to_echo_broadcast 0
ndd -set /dev/ip ip_strict_dst_multihoming 1

And in /etc/default/inetinit, prevent TCP sequence prediction (IP spoofing) attacks, by generating initial sequence numbers as suggested in RFC 1948.

This change can be edited automatically with:
mv /etc/default/inetinit /etc/default/inetinit.orig;
sed 's/TCP_STRONG_ISS=1/TCP_STRONG_ISS=2/' /etc/default/inetinit.orig \
> /etc/default/inetinit; chgrp sys /etc/default/inetinit;

Prevent some buffer-overflow attacks by adding the following lines to /etc/system. This protects against forms of attack where the code to be executed lives on the stack. The OS won't allow the code to be executed, but it requires hardware support (it's only effective on sun4u/sun4d/sun4m systems).

* Hardening
set noexec_user_stack=1
set noexec_user_stack_log=1

Use default routes: add the IP address of the router to /etc/defaultrouter, or create a startup file in /etc/rc2.d/S99static_routes using the "route" command. To disable dynamic routing:
        touch /etc/notrouter
        mv /usr/sbin/in.routed /usr/sbin/.in.routed

- Disable multicasting by commenting the lines around "route add" (it's about 14 lines, make sure you get all the ones in brackets).
- Enable logging of all INETD connections: Add add "-t" to the inetd startup line at the bottom, it should read:  /usr/sbin/inetd -s -t . Even better: disable inetd (see below)

Configure /etc/hosts with a list of critical machines (which you don't want resolved via DNS).



4. Connect to test network

The system has now gone through a first hardening phase and should be still working! Connect it to a secure, isolated network where standard tools/software can be downloaded. Boot and login on the console as root. Check for error messages on the console during boot, fix if necessary.

Tools are typically copied down with ftp. Avoid using the root account on the target server and change the password to a temporary one during the downloads, change back afterwards.
Once SSH has been installed, use it, rather than ftp for downloads.

5. Installing tools & sysadmin software

At this stage standard tools/utilities are going to be installed, the most important being SSH. These tools should already have been compiled and tested extensively on another machine. They are typically transferred as tar files, by CD or FTP. 

6. Stripping/configuring OS: 2nd pass

More OS patches: The Patch CD above won't be quite up to date. Get the Patchdiag tool from Sunsolve along with and update patchdiag.xref and run it to see what recommended and security patches are needed, then download & install the missing ones.

Configure logging:

Enable SU logging to console in /etc/default/su.

Enable logging of failed attempts to login:
touch /var/adm/loginlog; chmod 600 /var/adm/loginlog; chgrp sys /var/adm/loginlog

Syslog logging: Split up log analysis according to the example syslog.conf which enables more logging than the default and splits up services into separate logfiles. Designate one machine as the loghost (in /etc/hosts) or log locally.

Syslog "loghost"

Give the loghost a whopping great disk for logs.
Create empty logs & set permissions:
   cd /var/log; touch daemonlog authlog kernlog userlog maillog lprlog cronlog newslog locallog alertlog;
   chmod 600 daemonlog authlog kernlog userlog maillog lprlog cronlog newslog locallog alertlog;
   kill -1 `pgrep syslogd`

Use rotate_log to prune & compress logs, add the root cron entries:
## Prune syslog logs weekly, keeping the last 6 months or so:
55 23 * * 6 /secure/rotate_log -n 40 alertlog
55 23 * * 6 /secure/rotate_log -n 40 authlog
55 23 * * 6 /secure/rotate_log -n 20 cronlog
55 23 * * 6 /secure/rotate_log -n 40 daemonlog
55 23 * * 6 /secure/rotate_log -n 40 kernlog
55 23 * * 6 /secure/rotate_log -n 40 locallog
55 23 * * 6 /secure/rotate_log -n 20 newslog
55 23 * * 6 /secure/rotate_log -n 40 userlog
55 23 * * 6 /secure/rotate_log -n 10 lprlog
55 23 * * 6 /secure/rotate_log -n 20 maillog

Disable the Solaris log pruning (& other) lines in the root cron, since you're doing it yourself:

#10 3 * * 0,4 /etc/cron.d/logchecker
#10 3 * * 0 /usr/lib/newsyslog 
#15 3 * * 0 /usr/lib/fs/nfs/nfsfind
#1 2 * * * [ -x /usr/sbin/rtc ] && /usr/sbin/rtc -c > /dev/null 2>&1
#30 3 * * * [ -x /usr/lib/gss/gsscred_clean ] && /usr/lib/gss/gsscred_clean

Pruning of login & other logs:

## Empty login/logout records at year end
0 0 31 12 * /secure/wtrim.pl wtmp 20
0 0 31 12 * /secure/wtrim.pl wtmpx 20
# Solaris 2.x logs:
0 4 * * 6 /secure/rotate_log -L /var/adm -n 30 loginlog
0 4 * * 6 /secure/rotate_log -L /var/adm -n 30 sulog
0 4 * * 6 /secure/rotate_log -L /var/adm -n 2 vold.log
0 4 * * 6 /secure/rotate_cron


Remove unnecessary crons:
rm /var/spool/cron/crontabs/{lp,sys,adm}
Don't delete the adm cron if you want sar performance collection or accounting .

Root cron entries:

Set date once a day with a reliable source using rdate (you may prefer NTP, it's more accurate, but complex, uses bandwidth and is an additional security worry):

## Synchronise the time:
0 * * * * /usr/bin/rdate YOURTIMEHOST  >/dev/null 2>&1

File permissions: tighten basic permissions, and restrict certain tools to root or disable:

chmod 0500 /usr/sbin/snoop /usr/sbin/devinfo
chmod o-r /var/spool/cron/crontabs/*
chmod 000 /bin/rdist
chmod o-rx /etc/security
chmod og-rwx /var/adm/vold.log
chmod u-s /usr/lib/sendmail        #Not for mailgateways or multi-user hosts
chmod 400 /.shosts /etc/sshd_config /etc/ssh_known_hosts

Then download, compile and run Casper Dik's script ftp://ftp.fwi.uva.nl/pub/solaris/fix-modes.tar.gz for improving file and directory permissions (runs on Solaris 2.2-2.7).


Document configuration changes in a text file such as /etc/mods, update after each change, with date, author, files affected, description.
cat > /etc/mods <<EOF
29.11.99  sb  New install of Solaris2.7 & tools according to hardening guidelines

Set login banners to warn users about unauthorised access (you'll need this if you want to prosecute intruders). For Telnet and SSH, use /etc/issue (for pre-login) /etc/motd (for post-login), containing, for example:

ATTENTION: You have logged onto a secured XXXX Corporation server.
Access by non YYYY administrators is forbidden.
For info contact YYYY@XXX.com

Reboot, login via SSH.

Now, ps -e should show a small process list:
   0 ? 0:00 sched
   1 ? 0:00 init
   2 ? 0:00 pageout
   3 ? 0:09 fsflush
   156 ? 0:00 ttymon
   152 ? 0:00 sac
   447 ? 0:06 sshd
   88 ? 0:00 inetd
   98 ? 0:00 cron
   136 ? 0:00 utmpd
   605 ? 0:00 syslogd
   175 console 0:00 ttymon
   469 pts/1 0:00 csh
   466 ? 0:01 sshd
   625 pts/1 0:00 ps

and netstat -a should show a minimum of network connections (e.g. only SSH).

Local Address Remote Address State
-------------------- -------------------- -------
*.syslog Idle
*.* Unbound

Local Address Remote Address Swind Send-Q Rwind Recv-Q State
-------------------- -------------------- ----- ------ ----- ------ -------
*.* *.* 0 0 0 0 IDLE
*.22 *.* 0 0 0 0 LISTEN
*.* *.* 0 0 0 0 IDLE

7. Create Tripwire image, backup, test

Mount /usr and /opt read-only (in /etc/vfstab with "ro" option). This reduces the risk of trojan horses and unauthorised modifications.
Mount other partitions nosuid (SUID programs cannot assume other identities).
Run the mount command to check that filesystems options are effective.

8. Install, test, harden applications

Consider installing applications on a separate partition or /opt. If /opt is used, it will have to be mounted read-write during installation and testing, and switched back to read-only afterwards.

Depending on the function of the server, applications such as ftpd, BIND, proxies, etc. are installed at this point. Web servers and firewall engines in particular, are complex and require careful configuration. The following is a general checklist that servers/applications should conform to:

A few tips for well known services

1. FTP server (ftpd):

2. DNS servers:

3. A good article on general chroot environments, also called "padded cells" can be read at Sunworld www.sunworld.com/swol-01-1999/swol-01-security.html

4. HTTP servers:

Preparing to go live

You probably won't need CR-ROMs or floppies anymore, so disable the volume manager:
    mv /etc/rc2.d/S92volmgt /etc/rc2.d/.S92volmgt
If you do need to mount a CD in the future, start vold manually & check for new devices:
    drvconfig; disks; vold &; volcheck; df -k

Consider installing a script to check that important daemons are running. Install monitor_processes.pl and add a root cron entry:
## Check that important processes are running during office hours:
## [If you run 7x24, modify accordingly]
0,30 8-19 * * 1-5 /secure/monitor_processes.pl inetd sshd httpd

If partitions such as /opt or /usr had to be mounted read-write during the application install/testing, mount them read-only now.

Reinitialise tripwire (or equivalent integrity checker).

Backup the system to two tapes, one offsite.

Run a network scan on the system, to ensure that only expected services are visible. A commercial tool such as ISS or a free one like Nessus, nmap or Satan should do the job. Print out the results and archive.

If possible, have additional people do the final testing, just in case something was forgotten.

Test in detail - What works? What is forbidden? Check console/log entries. Does the system behave as expected? Watch the logs very frequently during the first few days of production.

9. Install on live network, test

Test in detail. Check log entries. Does the system behave as expected?

Have applications been tested in detail, by different people with different points of view, from different access points on the network?

10. Regular maintenance

The following activities should take place hourly, daily, weekly or monthly, depending on how critical the system is:

Additional Notes

This article has been very specific, in the interest of making it practical. However, each security administrator has his own methods and each site has different requirements.


  1. Security Portal Research Centre:
    Firewall products www.securityportal.com/research/center.cgi?Category=firewalls
    Firewall white papers www.securityportal.com/research/center.cgi?Category=whitefaqfire
  2. Free Tools
    Top, gzip, lsof, traceroute, perl: www.sunfreeware.com
    SSH notes: www.boran.com/security/ssh_stuff.html
    TCP Wrappers www.cert.org/ftp/tools/tcp_wrappers
    SMAP & FWTK www.fwtk.org
    Rdist www.magnicomp.com/rdist/rdist.shtml
    Network weaknesses scanners: Nessus, Satan, Nmap.
    Sample tools for analysing logs:
       Logcheck www.psionic.com/abacus/logcheck
       [See also my improved version of logcheck.sh]
       Swatch  ftp://ftp.stanford.edu/general/security-tools/swatch
  3. Sun
  4. sunsolve.sun.com


  5. Tripwire:
  6. Firewall Feature Comparison www.spirit.com/cgi-bin/report.pl
  7. Sunworld security columns www.sunworld.com/sunworldonline/common/swol-backissues-columns.html
    Solaris Security FAQ www.sunworld.com/common/security-faq.html
    Padded Cells: www.sunworld.com/swol-01-1999/swol-01-security.html
  8. Education: A good reference for any security issue is the SANS Security Roadmap.
    Visiting the SANS security conferences is also worthwhile, they have a workshop on Hardening Solaris, among many other interesting courses.
  9. CERT Advisories: www.cert.org  www.first.org   www.ciac.org

Seán Boran is an IT security consultant based in Switzerland and the author of the online IT Security Cookbook.