This article presents a
concise step-by-step approach to securely installing Solaris for use in a
firewall DMZ or other sensitive environment, using Sun's Jass tool
(and with Solaris 8 the Sunscreen EFS lite firewall). This article was
written (and tested) for Solaris 8, but the techniques described here should
work fine on earlier versions too.
The hardening process is
divided into the following steps:
27.Jan'03 Corrections to sendmail setup.
22.Mar'02: The latest version of Jass is v0.3.5. The changes to Jass between these versions concern primarily new Driver profiles, new template and support for Solaris |
|||
Reference section
- Regular maintenance
- Jass Overview: Test Drive | How good is Jass hardening? | What I like about Jass? | What don't I like? | Tips
- Additional Notes
- References
- Changes to this article
1. Preparation
- Keep things simple: it is expected that only one or two
services will run on a host. Use several machines, rather than one
superserver that does everything. It's easier to isolate applications,
harden, troubleshoot and upgrade hw/sw. Be minimalist, only run what is
absolutely necessary.
- Hardware: Consider installation via the serial port
console, get rid of the keyboard, screen and framebuffer. i.e. avoid using
X11 and get to know the command line. Have an isolated, trusted network
available for testing.
- Downloading securely: Hopefully
the installation is on an isolated or non-routed private network, in this
case you can ftp to the new box (as root), or ftp from the new box (via
the console) to a server on this net. If you don't have an isolated
network (not advisable), then change the root password to something easy,
download the files and change the password again, shutdown the network
interface immediately. This reduces the window of opportunity for
potential attackers. Alternatively, setup a non-privileged account with
/var/tmp as it's home and use to exchange files (Solaris 8 blocks ftpd for
root by default, with the 'root' entry in /etc/ftpusers).
- Know exactly what the system is supposed to do, what
it's hardware configuration will be etc. Hardening is generic and may
break certain functions. e.g. CDE/OpenWindows, Disksuite, Oracle and
Legato Networker need RPC to run (depending on how you use them) but you
really don't want RPC running on a firewall host, see the notes onRPC.
- It's important to understand how the applications work
(how they use ports, devices, files), to judge what hardening is possible
and to assess the risk posed.
We assume that a
"manual", as opposed to automated Jumpstart installation is used.
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
.
Note: On Solaris 8, make sure your use "Software CD#1" and not the "Installation CD".
Note: On Solaris 8, make sure your use "Software CD#1" and not the "Installation CD".
Install the end
user bundle (or even better only the core packages
which take only 110MB), set hostname, terminal, IP parameters, timezone, etc.
Don't enable any naming services like NIS or NFS. Don't enable power
management, or mount any remote file systems (NFS).
If you use the C-Shell, the following will
make command-line editing easier and enable history functions:
csh;
setenv TERM vt100; setenv VISUAL vi; setenv EDITOR vi; set filec; set history=40; alias h history; alias ls 'ls -aF \!*'; |
|||
Note: On Solaris 8, the user bundle can be customised via "F4", packages can be added or removed.
Choose manual disk
partitioning:
- Consider a separate, large /var filesystem for
syslog/web/news/proxy servers or firewall filters. Servers containing lots
of data (web, ftp) should use a separate disk for their data.
- Consider keeping /usr and /opt separate from root, so
that they can be later mounted read-only (see below). If you don't
wish to mount partitions read-only, then consider putting the whole boot
disk under root.
- If your intend using Sun's Disksuite for
RAID/Mirroring, reserve a 5MB slice. Two free partitions are needed for
the Veritas Volume manager.
- Some partitioning examples:
- 2GB disk, no local logging or /var activity, lots of
programs expected in /opt (also put /usr/local in /opt/local):
200MB / (root+var), 200MB swap, 400MB /usr, 1.2GB on /opt - 2GB disk, all programs together to maximise space but
preserve a separate partition for /var so logs can't fill the root file
system:
1.6GB / (root+usr+opt), 200MB swap, 200MB /var - 1GB disk, no local logging or /var activity, lots of
programs expected:
300MB / (root+var+opt), 200MB swap, 500MB /usr - 1GB disk, maximize space, preserve a separate
partition for /var
700MB / (root+usr+opt), 200MB swap, 100MB /var - 9GB disk on a server:
200MB /, 500MB swap, 2GB /usr, 5GB /opt, 1GB /var
Reboot.
Set a strong password (7
or 8 chars with numbers, letters and punctuation) for root.
The installation is
documented in /var/sadm/install_data/install_log
Next, we install man
pages not included in the User Bundle and the recommended
patches.
Terminfo: SUNWter
Accounting: SUNWaccr SUNWaccu NTP: SUNWntpr SUNWntpu UCB tools: SUNWscpu Man pages tools: SUNWlibC SUNWdoc
Showrev: SUNWadmfw SUNWadmc
The user bundle needs extra packages for
compiling: SUNWarcx SUNWarc SUNWbtoox SUNWbtool SUNWbtoox SUNWdplx SUNWsprox
SUNWhea SUNWlibm SUNWdfbh SUNWcg6h SUNWscpux
For Sunscreen 3.1: SUNWeuluf SUNWsprot
SUNWmfrun
For Sunscreen 3.2: SUNWeulux SUNWapchr SUNWapchu SUNWeu8os SUNWeu8osx SUNWeu8ox |
No man pages are
installed with the user bundle, so install them while the Solaris CD is still
mounted. Note: if you only installed the core bundle, SUNWlibc is
needed for viewing the man pages (which needs sgml2roff), so add this package
as well if needed (it is on CD#1 on Solaris8).
cd /cdrom/cdrom0/s0/Solaris_2.6/Product;
pkgadd -d . SUNWman SUNWdtma SUNWjvman SUNWpmowm SUNWolman SUNWxwman
pkgadd -d . SUNWman SUNWdtma SUNWjvman SUNWpmowm SUNWolman SUNWxwman
cd /cdrom/cdrom0/s0/Solaris_2.7/Product;
pkgadd -d . SUNWman SUNWdtmaz SUNWdtma SUNWjvman SUNWpmowm SUNWxwman
pkgadd -d . SUNWman SUNWdtmaz SUNWdtma SUNWjvman SUNWpmowm SUNWxwman
On Solaris 8, insert
CD#2. To save space, the man pages could be limited to the standard ones and
java:cd
/cdrom/cdrom0/Solaris_*/Product;
pkgadd -d . SUNWman SUNWjvman SUNWj2man
pkgadd -d . SUNWman SUNWjvman SUNWj2man
While we're here, we'll
install compression tools-
zlib (for OpenSSH)
and bash/tcsh (because they are nice shells :).
pkgadd -d . SUNWgzip SUNWbash SUNWbzip SUNWtcshSUNWzlib
pkgadd -d . SUNWgzip SUNWbash SUNWbzip SUNWtcshSUNWzlib
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/openwin/man;
Patches
If you're impatient to learn about patch
management tools for existing hosts, jump to the Patches section.
|
Download and install the
latest recommended and security patch bundle from Sun:
Solaris
|
URL
|
2.6 SPARC
|
ftp://sunsolve.sun.com/pub/patches/2.6_Recommended.tar.Z
|
7 SPARC
|
ftp://sunsolve.sun.com/pub/patches/7_Recommended.zip
|
7 Intel
|
ftp://sunsolve.sun.com/pub/patches/7_x86_Recommended.zip
|
8 SPARC
|
ftp://sunsolve.sun.com/pub/patches/8_Recommended.zip
|
8 Intel
|
ftp://sunsolve.sun.com/pub/patches/8_x86_Recommended.zip
|
9 SPARC
|
ftp://sunsolve.sun.com/pub/patches/9_Recommended.zip
|
These files can be many
tens of megabytes, since they cover all Solaris packages, not just those
relevant to your installation. The uncompressed versions can run to over 150MB.
·
Have a quick read of the CLUSTER_README file.
·
Save a log of what patches are installed already and unzip
patches:
If the system was only installed with the
"core" bundle, showrev will not be available (it
requires the package SUNWadmfw). In this case, on Solaris 7 and later
use patchadd -p.
Patchadd on Solaris 7 needs a little tweak to work with core only
packages though:
cd /usr/sbin;
mv patchadd patchadd-orig; sed s/\\/xpg4// patchadd-orig > patchadd; chown root:bin patchadd; chmod 555 patchadd; |
·
cd /opt/install;
showrev -p > patches.before;
unzip -q *Recommended.zip;
cd /opt/install;
showrev -p > patches.before;
unzip -q *Recommended.zip;
·
When the bundled is unzipped, it creates a subdirectory. To
install all the patches in one go, change to the subdirectory and run the
install script, with either of the following methods:
a) On a new system where
de-installation is unlikely to be necessary, install without being able to
remove patches. This will save lots of disk space:
cd *Recommended;
./install_cluster -nosave;
cd *Recommended;
./install_cluster -nosave;
b) Installation on an
existing system, or where de-installation of the patches must be possible if
the patch cluster messes things up (this will take more disk space as copies
are saved in /var/sadm/patch). Patches can only be individually de-installed,
there is not "deinstall_cluster" functionality.
cd *Recommended;
./install_cluster;
cd *Recommended;
./install_cluster;
·
Some patches installations may give warnings/errors:
o "return code
8" means that the patch in question cannot be applied because the relevant
Solaris modules are not installed. This error can be ignored.
o "return code
2" indicates patches are already installed. This error can be ignored.
o "return code
25" means a patches requires another patch that is not yet installed. Try
re-installing the bundle when finished, it may be a problem with the order of
the installation of patches.
o Other errors should be
investigated. Check the patch installation log:
more /var/sadm/install_data/Solaris_*Recommended_log
more /var/sadm/install_data/Solaris_*Recommended_log
·
Check to see what patches were actually installed:
cd ..;
showrev -p > patches.after;
diff patches.after patches.before;
showrev -p > patches.after;
diff patches.after patches.before;
Reboot and logon again
as root.
See the section Jass Overview for an overview of this tool. This section has been tested
with Jass v0.30 and v0.31.
First: Record a log of
all command actions/taken in the this section, by running:
script -a /jassinstall.log
which will keep a log of all commands and results in jassinstall.log. This may be useful for browsing through later.
which will keep a log of all commands and results in jassinstall.log. This may be useful for browsing through later.
Shutdown the network
interface during this next phase, just in case (the interface name depends on
the architecture e.g. le0 on old SPARCs):
ifconfig hme0 down
Install the Jass
package, no actual hardening is done at this stage. An example log of the
output is at [1]
pkgadd
SUNWjass-0.3.5.pkg
cd /opt/SUNWjass;
cd /opt/SUNWjass;
Next we tune some Jass
configuration settings
a) /opt/SUNWjass/Drivers/user.init is created with some custom settings, to tailor behaviour
for this system. First copy /opt/SUNWjass/Drivers/user.init.SAMPLE to /opt/SUNWjass/Drivers/user.init and add the following to the bottom:
# user.init
# sb, 02.Oct.01
JASS_AGING_MAXWEEKS="26"
JASS_AGING_WARNWEEKS="1"
JASS_AGING_MINWEEKS="0"
JASS_LOGIN_RETRIES="5"
JASS_PASS_LENGTH="6"
JASS_SENDMAIL_MODE="\"\""
JASS_TMPFS_SIZE="200m"
JASS_UMASK="027"
JASS_SHELL_DISABLE="/sbin/noshell"
JASS_CRON_LOG_SIZE="20480";
## v0.3.1
## Don't save files replaced by patches:
JASS_REC_PATCH_OPTIONS="-o -d"
# sb, 02.Oct.01
JASS_AGING_MAXWEEKS="26"
JASS_AGING_WARNWEEKS="1"
JASS_AGING_MINWEEKS="0"
JASS_LOGIN_RETRIES="5"
JASS_PASS_LENGTH="6"
JASS_SENDMAIL_MODE="\"\""
JASS_TMPFS_SIZE="200m"
JASS_UMASK="027"
JASS_SHELL_DISABLE="/sbin/noshell"
JASS_CRON_LOG_SIZE="20480";
## v0.3.1
## Don't save files replaced by patches:
JASS_REC_PATCH_OPTIONS="-o -d"
b) I don't wish to
enable BSM auditing or have process accounting, so comment out the lines
"enable-bsm.fin" and "enable-process-accounting.fin"
in Drivers/hardening.driver and Drivers/undoable-hardening.driver (jass v0.31).
d) If you didn't install
the latest recommended patches above, Jass will do it for you, if you extract
them into the 'Patches' directory. For example the Solaris 8 recommended bundles
would be extracted into Patches/8_Recommended.
e) Jass with run Casper
Dik's Fix-modes to tighten up file permissions, if you download FixModes.tar.Z
from the Jass site to /opt/SUNWjass/Packages. I recommend you do this.
Then we run Jass to do
the actual hardening for standalone use:
/opt/SUNWjass/jass-execute
-d hardening.driver
Reboot, check processes
Switch off the
scripting, remove the install directory if desired.
# exit
Script done, file is /jassinstall.log
Script done, file is /jassinstall.log
Now reboot for the
changes to have effect:
# reboot
Check for error messages
on the console, fix if necessary. Login as root and check the process
list, it should be something like the following example for Solaris 8:
# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 0 0 3 17:05:33 ? 0:17 sched
root 1 0 0 17:05:33 ? 0:00 /etc/init -
root 2 0 0 17:05:33 ? 0:00 pageout
root 3 0 0 17:05:33 ? 0:00 fsflush
root 258 1 0 17:06:11 ? 0:00 /usr/lib/saf/sac -t 300
root 261 258 0 17:06:12 ? 0:00 /usr/lib/saf/ttymon
root 129 1 0 17:06:07 ? 0:00 /usr/sbin/in.routed -q
root 46 1 0 17:05:42 ? 0:00 /usr/lib/sysevent/syseventd
root 239 1 0 17:06:10 ? 0:00 /usr/lib/sendmail -q15m
root 218 1 0 17:06:08 ? 0:00 /usr/sbin/inetd -s -t
root 226 1 0 17:06:09 ? 0:00 /usr/sbin/syslogd -t
root 247 1 0 17:06:10 ? 0:00 /usr/sbin/vold
root 233 1 0 17:06:09 ? 0:00 /usr/sbin/cron
root 242 1 0 17:06:10 ? 0:00 /usr/sbin/nscd
root 251 1 0 17:06:11 ? 0:00 /usr/lib/utmpd
UID PID PPID C STIME TTY TIME CMD
root 0 0 3 17:05:33 ? 0:17 sched
root 1 0 0 17:05:33 ? 0:00 /etc/init -
root 2 0 0 17:05:33 ? 0:00 pageout
root 3 0 0 17:05:33 ? 0:00 fsflush
root 258 1 0 17:06:11 ? 0:00 /usr/lib/saf/sac -t 300
root 261 258 0 17:06:12 ? 0:00 /usr/lib/saf/ttymon
root 129 1 0 17:06:07 ? 0:00 /usr/sbin/in.routed -q
root 46 1 0 17:05:42 ? 0:00 /usr/lib/sysevent/syseventd
root 239 1 0 17:06:10 ? 0:00 /usr/lib/sendmail -q15m
root 218 1 0 17:06:08 ? 0:00 /usr/sbin/inetd -s -t
root 226 1 0 17:06:09 ? 0:00 /usr/sbin/syslogd -t
root 247 1 0 17:06:10 ? 0:00 /usr/sbin/vold
root 233 1 0 17:06:09 ? 0:00 /usr/sbin/cron
root 242 1 0 17:06:10 ? 0:00 /usr/sbin/nscd
root 251 1 0 17:06:11 ? 0:00 /usr/lib/utmpd
·
Although inetd is running, no services are available in
inetd.conf.
·
Sendmail is left running is Queue mode (will deliver but not
accept remote emails), which is fine.
·
The routing daemon is left running in "quiet mode", if
more that one interface is present.
·
The following daemons are left running because they're not
considered risky. Personally, I would prefer to stop every daemon
that is not strictly necessary.
root 43 1 0 10:17:59 ? 0:00 /usr/lib/devfsadm/devfseventd
root 45 1 0 10:18:00 ? 0:00 /usr/lib/devfsadm/devfsadmd
root 46 1 0 17:05:42 ? 0:00 /usr/lib/sysevent/syseventd
root 247 1 0 17:06:10 ? 0:00 /usr/sbin/vold
root 242 1 0 17:06:10 ? 0:00 /usr/sbin/nscd
root 251 1 0 17:06:11 ? 0:00 /usr/lib/utmpd
root 43 1 0 10:17:59 ? 0:00 /usr/lib/devfsadm/devfseventd
root 45 1 0 10:18:00 ? 0:00 /usr/lib/devfsadm/devfsadmd
root 46 1 0 17:05:42 ? 0:00 /usr/lib/sysevent/syseventd
root 247 1 0 17:06:10 ? 0:00 /usr/sbin/vold
root 242 1 0 17:06:10 ? 0:00 /usr/sbin/nscd
root 251 1 0 17:06:11 ? 0:00 /usr/lib/utmpd
netstat -a shows only
SSH listening (if you have SSH installed).
If at this stage, you're
convinced that you really will run Jass on your system, first read through the
Jass Tips section. The following sections go through further
configuration issues to complement the Jass settings.
SSH is a good thing, essential
for every UNIX box. There are several SSH variants (see the SSH section).
|
|||
-----------------
TBD: need to write a
note about Jass + jumpstart and what follows later on.
Several options can be
set to improve the security and robustness of filesystems when they are
mounted. Run the mountcommand to check that filesystems options are
effective.
Mount option
|
OS
|
Description
|
When to use it
|
nosuid
|
2.x
|
Disables SUID programs, but also
disables devices!
|
/var or /home or data disks where
no SUID programs, or devices (and hence chroot environments are used).
/tmp won't work either, unless it is on disk. |
logging
|
2.7 or later
|
keeps a transaction log within the
mounted partition. The advantage is an almost instantaneous filesystem check
- which may take a considerable while with larger hard-disks, e.g. 50 GB. The
disadvantage is the additional time spent writing the transaction log.
|
/usr /opt /home
Recommended for all file systems except: root (if Veritas VxVM is used), or where file write performance is critical. |
noatime
|
2.7 or later
|
allows mounting file systems
without updating inodes at each access to any file. This will significantly
speed up services like web caches or news servers, which do a lot of file IO
with small files.
BUT, it make forensics more
difficult in case of an intrusion, since access times are not recorded.
|
/var or any partition where lots
of file access are expected (web cache or news partitions).
|
size=200m
|
2.5.1 or later
|
Allow /tmp to only use 200MB of
swap space. The value could be set to say 30% of swap space.
|
/tmp
|
ro
|
2.x
|
Read-only
Mounting filesystems read-only provides
only a limited protection against Trojans/attackers (if they get root, they
can remount read-write).
It may save time fsck'ing when
booting, can improve performance (access times don't need to be updated) and
can prevent the sysadmin from making mistakes or help detecting mistakes
(accidentally deleting files etc.).
|
Mounting read-only is a major
argument for maintaining separate file systems for /usr or /opt.
Note that to mount /usr read-only, /usr/local often needs to be on a different partition. |
Be very careful when
editing vfstab, e.g. an error on the / or /usr lines can render the system
unbootable! If this happens, boot from cdrom in single user mode, mount the
problem disk, correct vfstab and reboot. Some examples of vfstab entries are:
A simple server with
only a root and /var partition, running Solaris 2.8:
fd - /dev/fd fd - no -
/proc - /proc proc - no -
/dev/dsk/c0t3d0s1 - - swap
- no logging
/dev/dsk/c0t3d0s0 /dev/rdsk/c0t3d0s0 / ufs
1 no logging
/dev/dsk/c0t3d0s7 /dev/rdsk/c0t3d0s7 /var ufs 1 no
logging,nosuid,noatime
swap - /tmp tmpfs - yes size=100m
and on a larger server:
fd - /dev/fd fd - no -
/proc - /proc proc - no -
swap - /tmp tmpfs - yes size=200m
/dev/dsk/c0t8d0s0 /dev/rdsk/c0t8d0s0 / ufs
1 no logging
/dev/dsk/c0t8d0s1 - - swap
- no -
/dev/dsk/c0t8d0s4 /dev/rdsk/c0t8d0s4 /usr ufs 1 no
logging
/dev/dsk/c0t8d0s6 /dev/rdsk/c0t8d0s6 /var ufs 1 no
nosuid,noatime,logging
/dev/dsk/c0t8d0s5 /dev/rdsk/c0t8d0s5 /opt ufs 2 yes logging
Reboot to allow the vfstab values to have effect.
For maximum protection,
a local firewall can be installed:
1.
On some versions of Solaris 8, the iPlanet CD#2 contains among
other things, a restricted edition of the Sunscreen - the Sunscreen
EFS lite firewall. It can also be download for free from Sun.
Sunscreen lite can be
used to protect network communications to the local machine (among other
things). Below we present a quick overview of setting up some simple
rules on the command line, see [9] for a detailed discussion of Sunscreen configuration.
- Installation:
- When installing on the test system (which was installed with the Solaris 8 end user bundle), the EFS installation complained that SUWsprot was not installed. So, put back in Solaris CD#2 and install it first:
Sunscreen Tip:
Sun have published a paper on the Sunscreen lite v3.1, 18 months after this section was written, so it's worth checking out [9] .Likewise the Sunscreen Lite install doc is now online. |
|||
- pkgadd -d
/cdrom/sol_8_sparc_2/Solaris_8/Product SUNWsprot
- /cdrom/cdrom0/SunScreen/screenInstaller
or a terminal hands-off installation:
./installer -nodisplay - Configuration: Now we setup some simple Firewall rules.
First, find out the name of the current running firewall policy, edit it
and list the default rules and addresses.
# cd
/opt/SUNWicg/SunScreen/bin;
# ./ssadm active
Active configuration: www default Initial.2
Active configuration: www default Initial.2
# ./ssadm edit Initial
edit> list rule
1 "common" "*" "*" ALLOW
edit> list address
"*" RANGE 0.0.0.0 255.255.255.255
"le0.net" RANGE 176.17.17.0 176.17.17.255
"localhost" HOST
"smtp-server" HOST 1.1.1.1
"www_le0" GROUP { } { }
edit> list service common
"common" GROUP "tcp all" "udp all" "syslog" "dns" "rpc all" "nfs prog" "icmp all" "rip" "ftp" "rsh" "real audio" "pmap udp all" "pmap tcp all" "rpc tcp all" "nis" "archie" "traceroute" "ping"
edit> list rule
1 "common" "*" "*" ALLOW
edit> list address
"*" RANGE 0.0.0.0 255.255.255.255
"le0.net" RANGE 176.17.17.0 176.17.17.255
"localhost" HOST
"smtp-server" HOST 1.1.1.1
"www_le0" GROUP { } { }
edit> list service common
"common" GROUP "tcp all" "udp all" "syslog" "dns" "rpc all" "nfs prog" "icmp all" "rip" "ftp" "rsh" "real audio" "pmap udp all" "pmap tcp all" "rpc tcp all" "nis" "archie" "traceroute" "ping"
So we see that the
default policy allows quite a few services through.
Let's presume that we
are setting up a HTTPD server (on port 80) and intend to manage it via SSH. We
also want to allow ping and traceroute for initial trouble shooting. We could
then create and active the new firewall policy restricting access to these
services as follows
# ./ssadm edit Initial
edit> add service ssh SINGLE FORWARD "tcp" PORT 22
edit> add service myhttp GROUP ping traceroute ssh www
edit> replace rule 1 ALLOW myhttp "*" "*"
edit> list rule
1 "myhttp" "*" "*" ALLOW
edit> save
edit> verify
Configuration verified successfully (not activated).
edit> quit
www# ./ssadm activate Initial
Configuration activated successfully on www.
edit> add service ssh SINGLE FORWARD "tcp" PORT 22
edit> add service myhttp GROUP ping traceroute ssh www
edit> replace rule 1 ALLOW myhttp "*" "*"
edit> list rule
1 "myhttp" "*" "*" ALLOW
edit> save
edit> verify
Configuration verified successfully (not activated).
edit> quit
www# ./ssadm activate Initial
Configuration activated successfully on www.
Voila!
- Let's allow ssh or smtp (for email alerts) to a
management host, ping/traceroute outgoing for debugging and incoming only
from management hosts, to reduce the risks even further. Allow
HTTPS. We can also allow dns lookups.
# cd
/opt/SUNWicg/SunScreen/bin;
# ./ssadm edit Initial
edit> add address mgt_net RANGE 176.17.17.0 176.17.17.255
edit> add service mgt GROUP ping traceroute ssh
edit> add service https SINGLE FORWARD "tcp" PORT 443
edit> add service outgoing GROUP ping traceroute dns
edit>
edit> replace rule 1 ALLOW www "*" localhost
edit> replace rule 2 ALLOW https "*" localhost
edit> replace rule 3 ALLOW mgt mgt_net localhost
edit> replace rule 4 ALLOW outgoing localhost "*"
edit> replace rule 5 ALLOW smtp localhost mgt_net
edit>
edit> save
edit> verify
Configuration verified successfully (not activated).
# ./ssadm activate Initial
Configuration activated successfully on www.
# ./ssadm edit Initial
edit> add address mgt_net RANGE 176.17.17.0 176.17.17.255
edit> add service mgt GROUP ping traceroute ssh
edit> add service https SINGLE FORWARD "tcp" PORT 443
edit> add service outgoing GROUP ping traceroute dns
edit>
edit> replace rule 1 ALLOW www "*" localhost
edit> replace rule 2 ALLOW https "*" localhost
edit> replace rule 3 ALLOW mgt mgt_net localhost
edit> replace rule 4 ALLOW outgoing localhost "*"
edit> replace rule 5 ALLOW smtp localhost mgt_net
edit>
edit> save
edit> verify
Configuration verified successfully (not activated).
# ./ssadm activate Initial
Configuration activated successfully on www.
Now test the network
connections, to ensure the rules have the desired effect. To rollback to the
initial configuration, delete all rules and add:
replace rule 1 ALLOW
"common" "*" "*"
Finally, we can stop the
remote Firewall management GUI. Why would we do this? If we are comfortable
with the command line "ssadm" then one daemon more and one more
configuration interface, that needs to be correctly configured and watched.
Disabling the following
line in /etc/rc2.d/S63sunscreen
$SS_LIBDIR/run_httpd start efshttpd
$SS_LIBDIR/run_httpd start efshttpd
In
/opt/SUNWicg/SunScreen/lib/ss_boot, disable:
$SS_LIBDIR/ssadmserver start >/dev/console 2>&1
$SS_LIBDIR/ssadmserver start >/dev/console 2>&1
The system has now gone
through a first hardening phase and should be still working! Boot and login on
the console as root. Check for error messages on the console, fix if
necessary.
- Routing:
- For default routes, add the IP address of the router
to /etc/defaultrouter
[This can be done in Jumpstart, see Jass Tips] - or for static routes, create a startup file in
/etc/init.d/static_routes and a symbolic link under
/etc/rc2.d/S99static_routes using the 'route' command.
- Empty the routing table and add a route for a specific
network, e.g.:
route -f add net 129.97 `cat /etc/defaultrouter` - If you really want to run the routing daemon (we don't
advise this - use a dedicated router instead), make sure you understand
how it works, read [21], as it can mess up your network. Consider running in
quiet mode ('-q'), or tell the interface not to publish routes with the
'private' option to ifconfig. To run in quiet mode, set SUNSTARTUP=YES in
/etc/yassp.conf and make sure no default router is specified.
- Configure /etc/hosts with a list of critical machines
(which you don't want resolved via DNS).
- DNS client (avoid if not needed): add domain name and
DNS servers to /etc/resolv.conf. Add a DNS entry for "hosts" in
/etc/nsswitch.conf. [This can be done in Jumpstart, see Jass Tips]
- Environment: /.cshrc /.profile: set aliases, variables
(such as VISUAL, EDITOR and PATH - don't include "."). [This can
be done in Jumpstart, see Jass Tips]
- The useradd tool
is a typical way of adding new accounts to the system. The first time it
is run and defaults are set, it creates /usr/sadm/defadduser with a
defaults for new user accounts. This might be a good time to edit this
file and set the defaults you expect to use for new user accounts (e.g.
shell, groups, expiration).
- Email client: If hosts are not supposed to send email
outside the subnet, don't configure the mailhost alias
(in /etc/hosts). Delete /usr/lib/sendmail (or even better pkgrm SUNWsndmr SUNWsndmu)
if you don't need any kind of email. Otherwise,
- edit /etc/mail/aliases, at least point mailer-daemon, root and
other system accounts to real addresses. Then runnewaliases.
- add an entry with the IP address of the mail-server in
/etc/hosts with the mailhost alias
- add an entry with the FQDN (fully qualified domain
name) of your machine to /etc/hosts -- i.e. add a hostname.YOURDOMAIN.COM
alias for your machine. (This is to stop sendmail from complaining).
- in /etc/mail/sendmail.cf set the following to ensure
all outgoing email is channeled over mailhost (the
grayed-out bits are normally not needed on Solaris 8):
Dj$w.YOURDOMAIN.COM.
DSmailhost
DRmailhost
DHmailhost
O FallbackMXhost=mailhost - On Solaris 9, to get outgoing email delivery to work
at all it may be necessary to change the 'S' macro in/etc/mail/submit.cf to:
DSmailhost$?m.$m$. - Jass leaves sendmail running is queuing mode (which
means MODE="" in /etc/init.d/sendmail) to retry deliveries that fail initially. If Jass was
not used for hardening and sendmail has been stopped, /usr/lib/sendmail -q can
be added to the root crontab.
- send a test email to check the config:
mailx -v -s test_email root </dev/null - Email server: If you really need to
receive Email (i.e. run an SMTP server),
it's not a trivial task. Refer to [16].
Reboot, check for
errors.
Install tools and scripts: All tools should already have been compiled and tested
extensively on another machine. [These can be installed via Jumpstart,
see Jass Tips]
- Install security scripts in /secure, for example those
used below [3]:
rotate_cron, rotate_log, wtrim.pl, rdistd, Saveit, weekly. Then protect /secure: chmod 700 /secure; chown -R root
/secure
- Solaris 8: Lots of Goodies are provided with Solaris 8
on the many additional CDs, one is The Software Companion CD which
contains popular Freeware, such as ppp, samba, wu-ftp (avoid this),
Development/Libraries, Development/Tools, X11 apps, vim/emacs, window
managers and corresponding sources.
Some tools not listed, that I would have liked were: top and lsof. Apache is not listed, because is included with Solaris itself (CD #2). These tools may save you some time, but will of course not be the very newest versions. Sun is to be commended for this CD, it's a pity there's not more and it didn't come sooner! There is a GUI install tool, to use it on a headless server (i.e. you have no screen), login via SSH and tunnel X11. Or just navigate the directories and use pkgadd.
Choose custom install to control exactly what is installed, where. - Install other useful tools: traceroute (included
in Solaris 7) and maybe top or lsof (without
SUID) .
- Install perl for scripting and create
a link to /bin/perl (ln -s /usr/local/bin/perl /bin/perl).
A version is already included in Solaris 8, but consider deleting it ('pkgrm SUNWpl5u SUNWpl5p SUNWpl5m') and installing a new, fresh copy (e.g. download from Sunfreeware.com and 'pkgadd -d perl-5.6.0-sol8-sparc-local'). The problem, apart from being a bit old, is that it is compiled with Sun's compiler, not gcc. So if you use gcc, you may have problems installing and compiling Perl XSUB modules (the XML::Parser module taught me this).
7. Patches
Wait, don't skip to the
next section just yet! Yes, patches make us all yawn... are they a waste of
time? This sections presents some strategies for handling patches and tools to
make life easier.
During installation, the
Solaris recommend patch bundle was installed. However, not all security fixes
are included in this bundle, and as time goes by you'll have to check regularly
for new patches. Systems which have security patches installed are more secure
than those which don't. For overview of the concepts of Solaris Patching, see
"A SunSolve Patch Primer" [15].
Weakness are continually
discovered in Solaris and 3rd party applications. Not only do the weakness pose
threats but thevolume of weaknesses and patches can be a threat: if
not managed carefully, they will consume too much time or they will be simple
ignored.
The first problem is to
be aware that weaknesses and/or patches actually exist. Possible strategies
are:
1.
Get on all the mailing lists of organisations such as CERT/First,
vendors like Sun, and especially Bugtraq. This can consume quite a lot of time.
2.
Get on the mailing list of an organisation which produces regular
summaries of weakness/patches and security news, for example SecurityFocus (Sun
section/ email list) or SANS. If a regular source of reliable information on
Solaris and the applications that you use can be found, it may save much time.
3.
Run a tool on important servers that checks the current patch
level and compares it with the newest list of patches available from Sun: This
is the ideal situation (it is discussed below in more detail).
4.
Check Sun's recommended patch bundles for changes every month or
two: This requires little effort, but security is not as tight and the
recommended bundles do not cover all Security problems. The recommended bundles
may cause problems with some applications though, if kernel patches are
applied.
5.
3rd party application patches need to be checked and applied too.
Don't forget them!
How do you decide
whether a weakness is worth patching?
- If the weakness concerns a remotely exploitable
weakness in an active network daemon, exposed to a hostile environment like
the Internet, install it soon.
- If the weakness concerns a local exploit of a tool not
normally used, not a daemon and on a host where only root or administrator
accounts exist, it may be enough to install the patch together with a
bundle at regular intervals (e.g. every six months).
- If the weakness concerns a local exploit of a tool on a
host where non-administrative users have accounts, then it depends on how
critical the system is and how much the users can be trusted. Regular
patches to multi-user systems are advised.
- If the systems runs highly specialised software like
databases, be very wary of installing Kernel, I/O and driver patches. It
is advisable to test patches on a separate system first.
- Patches differ by Solaris version and architecture. So
it makes sense to try and keep servers of the same OS/architecture on the
same patch-level and define a master host, whose patch level is
automatically checked at regular intervals.
Warning: Patches may
reverse some of Jass's changes. So reboot after applying patches, check
carefully that no unexpected daemons are running and consider re-running Jass
(it is designed to allow multiple runs).
Some patches
installations may give warnings/errors:
- "return code 8" means that the patch in
question cannot be applied because the relevant Solaris modules are not
installed. This error can be ignored.
- "return code 2" indicates patches are already
installed. This error can be ignored.
- "return code 25" means a patches requires
another patch that is not yet installed. Try re-installing the bundle when
finished, it may be a problem with the order of the installation of
patches.
- Other errors should be investigated. Check the patch
installation log:
more /var/sadm/install_data/Solaris_*Recommended_log
- GetApplyPatch and CheckPatches are two Bourne shell scripts for Solaris patch
management, that I've tested quite a bit and can recommend:
1.
CheckPatches:
is a script that uses showrev to see what patches are
installed, compare this against the Solaris patch report, and makes a list of
recommended and security patches that need installation. It expects to find
'SolarisX.PatchReport' in the current directory (or you can use
'-f' to download the latest Patch report via ftp)
> ./CheckPatches -f
> ./CheckPatches -f
2.
GetApplyPatch:
is a script to get and apply a patch. Arguments are a list of patch numbers. If
run from the command line, it is interactive and will ask you to confirm the
download, show the patch readme, install the patch and delete the patch
directory. It can also run without prompting in "batch mode" (-b).
> ./GetApplyPatch 108875-07
A cron script for automating this and emailing the results is included (CheckPatches.cron).
> ./GetApplyPatch 108875-07
A cron script for automating this and emailing the results is included (CheckPatches.cron).
3.
Both scripts can be used together to get each patch that is needed
and install it. By default this is interactive: it downloads the patch list and
works out what patches are needed, then for each patch, you are asked if you
want to download the patch, then view the readme, then install it, delete the
patch files and move on to the next one. Cool.
> ./CheckPatches | ./GetApplyPatch
A cron script for automating this and emailing the results is included (GetApplyPatch.cron). I would not recommend automatically applying patches on important (high availability) servers.
> ./CheckPatches | ./GetApplyPatch
A cron script for automating this and emailing the results is included (GetApplyPatch.cron). I would not recommend automatically applying patches on important (high availability) servers.
4.
Other features:
§ Man pages are included.
§ Solaris Intel and SPARC
is supported & tested.
§ ftp proxies may be
configured and you can download from your local mirror rather than Sunsolve.
§ CheckPatches can be configured to ignore certain
patches. For example, we have a Solaris8 x86 server andCheckPatches reports
that we need:
109897-03 SunOS 5.8_x86: USB patch
109952-01 SunOS 5.8_x86: jserver buffer overflow
110417-02 SunOS 5.8_x86: ATOK12 patch
But we don't use any of these products, so we'd like to ignore patch information of these. So we create a file Solaris8_x86.PatchReport.Except in the same directory as Solaris8_x86.PatchReport, that contains the above 3 lines and CheckPatches will automatically ignore them! Neat.
109897-03 SunOS 5.8_x86: USB patch
109952-01 SunOS 5.8_x86: jserver buffer overflow
110417-02 SunOS 5.8_x86: ATOK12 patch
But we don't use any of these products, so we'd like to ignore patch information of these. So we create a file Solaris8_x86.PatchReport.Except in the same directory as Solaris8_x86.PatchReport, that contains the above 3 lines and CheckPatches will automatically ignore them! Neat.
§ Alternatively we could
suppress the output of CheckPatches with out own expression,
e.g.:
./CheckPatches | egrep -v "109897|109952|110417"
./CheckPatches | egrep -v "109897|109952|110417"
5.
Problems:
- Several problems were fixed and Dec'00/Jan'01. The version we tested here was from 19.Jan'01.
- Sometimes it does not install a patches because some other patch is required. Hopefully a second run catches those.
- It would be better if the patch exception list did not contain patch version numbers.
- Several problems were fixed and Dec'00/Jan'01. The version we tested here was from 19.Jan'01.
- Sometimes it does not install a patches because some other patch is required. Hopefully a second run catches those.
- It would be better if the patch exception list did not contain patch version numbers.
- The Patchdiag tool from Sunsolve can
be used along with the latest patchdiag.xref to see what
recommended and security patches are missing, then download & install
the missing ones. This tool is apparently free, but only available for
download for contract customers.
- Consider checking with the SecurityFocus vulnerability
calculator. Execute the following:
> showrev -p | cut -f2 -d' ' | xargs
and then paste it into the window on SecurityFocus.com and select OS version, architecture and hit run. This will probably result in a long list of vulnerabilities, most of which are not relevant. Go through the list looking for applications or services that are active on your host, that then need fixing. A link is provided for each vulnerability, where more details and fixes can be found. This list of vulnerabilities includes not just Solaris, but all third party applications. - FastPatch is
a replacement for patchadd, the same but a lot faster.
- Patchreport is
a script that does everything CheckPatches and GetApplyPatch do, plus
checking integrity of patches via MD5, logging in to sunsolve to get the
public patch reports or if you have a Sunsolve ID and getting the full
patchdiag.xref file. It's written in Perl and does require quite a few
Perl modules to be installed. Not yet tested in detail.
8. RPC
RPC services should be
avoided on sensitive servers, such as those on the Internet or in a DMZ. RPC
uses dynamic ports and provides no standard access control methods. However,
some programs insist on having RPC e.g. CDE, OpenWindows, Disksuite and Legato
Networker. If possible avoid RPC, otherwise....
Improving Disksuite
Security:
Disksuite is a tool
bundled with Solaris that allows disks to be mirrored or gathered into RAID
sets. This is useful feature to have in the system. The problem is that
Disksuite uses RPC (specifically: two programsrpc.metamhd and rpc.metad which
run from inetd).
How can Disksuite
security be improved?
1.
Don't run Disksuite. This is my often choice.
o Hardware RAID systems
have the advantage that no special software like Disksuite is needed. This is
better for secure systems (simplicity) and in disaster scenarios you may find
Disksuite isn't all that easy to handle.
o For system disks (where
data does not change often), I've written a script for backing up boot disks
withcpio. See also the section Boot disk backup.
2.
Run Disksuite but stop the associated RPC services (in /etc/inetd.conf)
and stop rpcbind:
o The "metad"
service can be disabled but this means the "metatool" will not work.
Command line tools will work fine -- and you should know them in any case for
disaster scenarios with system disks.
o The "metamhd"
service can be disabled but this means you cannot share metadevices between
systems.
OK, let's get back to
general measures for RPC security:
- If you are using Solaris 8, the bundled (free) Sunscreen EFS Lite Firewall can be used to filter who can access the rpc
services (since the Sunscreen includes an RPC state filter engine),
or...
- IPfilter [20] can also be used as local firewall to prevent
access to RPC services.
- It's free and works on older Solaris, not just 8.
- It doesn't have an RPC state based engine though (so
it can't filter on RPC program names or allow RPC to specific
destinations),
- but it can be used to allow all localhost RPC traffic
(enough for some RPC applications such as Disksuite or CDE) and deny all
remote traffic except, say, HTTP or whatever service is provided to
remote hosts.
- Use Wietse Venema's rpcbind, which provides
tcp wrapper-like access control and logging. Rpcbind is a
"directory" service that's used to locate a service (by RPC name
or by RPC number). Since it is not used to mediate the connection to the
service, it cannot provide access control to the actual RPC programs. A
port scanner can detect active RPC services and unless the kernel is
adapted to filter such connections it's impossible to prevent others from
accessing them.
Summary of features (extract from the README):
-
host access control on IP addresses. The local host is considered authorized.
Host access control requires the libwrap.a library that comes with recent tcp
wrapper implementations.
- requests that are forwarded by the rpcbind process will be forwarded through an unprivileged port.
- the rpcbind process refuses to forward requests to rpc daemons that do (or should) verify the origin of the request: at present, the list includes most of the calls to the NFS mountd/nfsd daemons and the NIS daemons.
- the rpcbind process refuses REMOTE requests sent to high-numbered UDP ports (instead of TCP or UDP ports 111). High-numbered ports are opened by the rpcbind server as a side effect of other activity. These ports could be abused to bypass packet filtering restrictions. See the advisory (and addendum) onwww.secnet.com
- requests that are forwarded by the rpcbind process will be forwarded through an unprivileged port.
- the rpcbind process refuses to forward requests to rpc daemons that do (or should) verify the origin of the request: at present, the list includes most of the calls to the NFS mountd/nfsd daemons and the NIS daemons.
- the rpcbind process refuses REMOTE requests sent to high-numbered UDP ports (instead of TCP or UDP ports 111). High-numbered ports are opened by the rpcbind server as a side effect of other activity. These ports could be abused to bypass packet filtering restrictions. See the advisory (and addendum) onwww.secnet.com
- It is based on the Solaris 2.3 sources for rpcbind,
which were made publicly available by Sun in 1994. A code review was also
conducted (by Jean Chouanard) on the differences with Solaris 2.7's
RPCBIND, the differences were minimal.
- The additional logging is useful. If RPC is restricted
to localhost, and 'rpcinfo -p' is attempted from another host, the
following is logged:
Aug 4 14:55:15 myserver rpcbind: refused connect from 160.97.24.221 to dump()
9. Logging, root cron entries
Syslog logging: I
replace Suns syslog.conf and that installed by Jass, with my own [3] - that enables more logging than the default and saves logs
in /var/adm/messages. More details below.
I also disabled the
Solaris log pruning and other lines in the root cron. I've written a
script /secure/weekly [3] which includes the weekly entries listed below and can be
run on both loghost and client, with a cron entry like:
50 23 * * 6 sh /secure/weekly >/dev/null
50 23 * * 6 sh /secure/weekly >/dev/null
Syslog configuration:
Syslog client: Designate one machine as the loghost (in
/etc/hosts).
·
Test that logging to the server works correctly:
logger -p auth.warn "test of syslog"
and check that it appears in the server logs.
logger -p auth.warn "test of syslog"
and check that it appears in the server logs.
·
If you would like a copy of logs to be kept locally, as well as
remotely, uncomment the line in /etc/syslog.conf:
*.err;auth.info;kern.debug /var/adm/messages
*.err;auth.info;kern.debug /var/adm/messages
·
If syslog does not work as expected, read the commented example
and tips in syslog.conf.
Syslog server or
"loghost":
·
Give the loghost a whopping great disk for logs.
·
If you want to use my syslog.conf for servers that splits up the
logs into one file per facility in /var/log, then:
Backup
old syslog config:
mv /etc/syslog.conf /etc/syslog.conf.orig$$
mv /etc/syslog.conf /etc/syslog.conf.orig$$
·
Jass will start syslog with the "-t" option, so it will
not accept syslog connections from other hosts. So, to run a central syslog
server, remove the '-t' option to the syslogd startup line in /etc/init.d/syslog and
create the logs if they don't yet exist, for example:
·
## Syslog server by Sean
·
for log in alertlog authlog cronlog daemonlog kernlog local0log
local2log
·
local5log lprlog maillog newslog userlog ; do
·
if [ ! -f /var/log/$log ];
then
·
/usr/bin/cp /dev/null
/var/log/$log
·
/usr/bin/chmod 0644 /var/log/$log
·
fi
·
done
·
/usr/sbin/syslogd >/dev/msglog 2>&1 &;
## end Sean's edits
·
Restart syslog:
kill -1 `cat /etc/syslog.pid`
kill -1 `cat /etc/syslog.pid`
·
Use rotate_log [3] to prune and compress logs, add root cron entries (note that
/secure/weekly includes all this):
## 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 local0log
55 23 * * 6 /secure/rotate_log -n 40 local2log
55 23 * * 6 /secure/rotate_log -n 40 local5log
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
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 local0log
55 23 * * 6 /secure/rotate_log -n 40 local2log
55 23 * * 6 /secure/rotate_log -n 40 local5log
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
Add a root cron entry
for cleaning of other local logs on both workstations and servers (note that
/secure/weekly also includes this)
# 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
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
Add a root cron entry
for Yearly cleaning of login entries
## 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
0 0 31 12 * /secure/wtrim.pl wtmp 20
0 0 31 12 * /secure/wtrim.pl wtmpx 20
Other 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). See
also the section Time Synchronisation.
## Synchronise the time:
0 * * * * /usr/bin/rdate YOURTIMEHOST >/dev/null 2>&1
## Synchronise the time with NTP
#0 * * * * ntpdate YOURTIMEHOST1 YOURTIMEHOST2 >/dev/null 2>&1
## Synchronise the time:
0 * * * * /usr/bin/rdate YOURTIMEHOST >/dev/null 2>&1
## Synchronise the time with NTP
#0 * * * * ntpdate YOURTIMEHOST1 YOURTIMEHOST2 >/dev/null 2>&1
Consider installing a
script to check that important daemons are running. For example, install
monitor_processes.pl [3] and add a root cron entry:
## Check that important
processes are running during office hours:
0,30 8-19 * * 1-5 /secure/monitor_processes.pl sshd httpd
0,30 8-19 * * 1-5 /secure/monitor_processes.pl sshd httpd
Documentation:
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
15.10.01 sb New install of Solaris8 and tools according to hardening guidelines
EOF
cat > /etc/mods <<EOF
15.10.01 sb New install of Solaris8 and tools according to hardening guidelines
EOF
Files which have the
SUID bit set (an "s" where the execute bit for the owner/group is
shown in 'ls' listings) allow the user executing the program to assume the
identity/group of the owner of the program. This is typically used to allow
normal users to access certain function typically only allowed to root, for
example binding to low ports, mounting a floppy disk, etc. The problem is
that historically, many security weakness have been found in such programs
allowing attackers with local accounts to become root by exploiting buffer over
flows, race conditions etc.
• Solaris has many
"SUID root" binaries and each one presents a risk, so when hardening
systems it is advisable to disable as many SUID program as possible.
• The purpose of this section is to provide a brief overview of the subject, a list of documents and scripts for disabling SUID files is provided.
• See [8] for SUID references and further reading.
• The purpose of this section is to provide a brief overview of the subject, a list of documents and scripts for disabling SUID files is provided.
• See [8] for SUID references and further reading.
What SUID files are on
the system?
The find command can be
used to list all SUID files:
find / -perm -u+s -ls
find / -perm -u+s -ls
or all SGID files:
find / -perm -g+s -ls
find / -perm -g+s -ls
How should we handle
SUID files? Possible courses of action, in order of preference, are:
·
Remove the package containing the offending file
·
Disable the program (e.g. chmod 000 FILENAME)
·
The SUID bit can be removed (e.g. chmod ug-s FILENAME)
Restrict the file to a
group of users (first remove world access: "chmod o-rwx", then allow
a group "chgrp ·
MYGROUP MYFILE") .
What SUID files need to
be limited?
·
One suggestion for paranoid systems is to disable all except
'pt_chmod', 'utmp_update' and 'su'.
·
Before removing SUID bits, we make a backup of all SUID files so
that we can also go back and restore the previous state.
tar cvf /opt/suid_backups.tar `find / -type f \( -perm -u+s -o -perm -g+s \) -print`
This file may be 14MB or more, compression reduces the size significantly:
gzip /opt/suid_backups.tar
[These suid files can be minimized via a Jumpstart finish script, see Jass Tips]
tar cvf /opt/suid_backups.tar `find / -type f \( -perm -u+s -o -perm -g+s \) -print`
This file may be 14MB or more, compression reduces the size significantly:
gzip /opt/suid_backups.tar
[These suid files can be minimized via a Jumpstart finish script, see Jass Tips]
·
Specific examples on SUID limiting are presented below which
reduce the number of SUID/SGID files from about 80 to 9. These were tested on
both Solaris 8 and 7, on a DMZ server. Note that Solaris 8 has less SUID files
than Solaris 7.
1.
Tools like uucp are almost never needed. If possible, remove the
SUNWbnuu package or disable the SUID bits.
pkgrm SUNWbnuu
chmod ug-s /usr/bin/cu /usr/bin/uu* /usr/lib/uucp/*
pkgrm SUNWbnuu
chmod ug-s /usr/bin/cu /usr/bin/uu* /usr/lib/uucp/*
2.
Another often unused suite of tools is kcms (Kodak Color
Management System), so either remove or disable:
pkgrm SUNWkcspf SUNWkcspx SUNWkcspg SUNWkcsrt;
chmod ug-s /usr/openwin/bin/kcms*
pkgrm SUNWkcspf SUNWkcspx SUNWkcspg SUNWkcsrt;
chmod ug-s /usr/openwin/bin/kcms*
3.
If no printer is needed:
chmod ug-s /usr/lib/lp/bin/netpr /usr/sbin/lpmove /usr/bin/lp /usr/bin/lpset /usr/bin/lpstat /usr/bin/cancel /etc/lp/alerts/printer
chmod ug-s /usr/lib/lp/bin/netpr /usr/sbin/lpmove /usr/bin/lp /usr/bin/lpset /usr/bin/lpstat /usr/bin/cancel /etc/lp/alerts/printer
4.
Only allow root to use ancient r* commands, since you only use SSH
(right?):
chmod ug-s /usr/bin/rcp /usr/bin/rlogin /usr/bin/rsh
chmod ug-s /usr/bin/rcp /usr/bin/rlogin /usr/bin/rsh
5.
Only allow root to sniff the network, use rdist or list processes:
chmod ug-s /usr/sbin/snoop /usr/sbin/devinfo /bin/rdist /usr/bin/netstat /usr/local/bin/top /usr/local/bin/*/top /usr/sbin/traceroute /usr/local/bin/lsof /usr/bin/*/ps /usr/ucb/*/ps /usr/sbin/*/whodo /usr/bin/*/uptime /usr/bin/*/w
Note: 'ps' doesn't really need SUID on Solaris 2.5 and later (which have /proc), performance of the 'ps' command will be slightly reduced due to lack of caching.
chmod ug-s /usr/sbin/snoop /usr/sbin/devinfo /bin/rdist /usr/bin/netstat /usr/local/bin/top /usr/local/bin/*/top /usr/sbin/traceroute /usr/local/bin/lsof /usr/bin/*/ps /usr/ucb/*/ps /usr/sbin/*/whodo /usr/bin/*/uptime /usr/bin/*/w
Note: 'ps' doesn't really need SUID on Solaris 2.5 and later (which have /proc), performance of the 'ps' command will be slightly reduced due to lack of caching.
6.
dump or restore only
need SUID for the archaic 'rmt/rsh' remote backups, so drop it.
chmod ug-s /usr/lib/fs/ufs/ufsdump /usr/lib/fs/ufs/ufsrestore
You might only allow root to use these anyway? In which case they can be further restricted with 'chmod 700'.
chmod ug-s /usr/lib/fs/ufs/ufsdump /usr/lib/fs/ufs/ufsrestore
You might only allow root to use these anyway? In which case they can be further restricted with 'chmod 700'.
7.
Disable YP, NIS+ SUID tools unless you need them:
chmod ug-s /usr/bin/chkey
chmod ug-s /usr/bin/chkey
8.
If only root uses cron or at, then
restrict them:
chmod ug-s /usr/bin/at /usr/bin/atq /usr/bin/atrm /usr/bin/crontab
chmod ug-s /usr/bin/at /usr/bin/atq /usr/bin/atrm /usr/bin/crontab
9.
If only root uses the serial line (for tty consoles):
chmod ug-s /usr/bin/tip
chmod ug-s /usr/bin/tip
10.
If only the root account administers the system:
chmod ug-s /usr/bin/admintool /usr/lib/fs/ufs/quota /usr/bin/fdformat /usr/bin/eject /usr/bin/volcheck /usr/bin/volrmmount /usr/bin/rmformat /usr/platform/*/sbin/eeprom /usr/sbin/wall
chmod ug-s /usr/sbin/arp /usr/bin/write /usr/sbin/sacadm /usr/sbin/*/sysdef /usr/sbin/*/prtconf /usr/platform/*/sbin/prtdiag* /usr/sbin/*/swap
chmod ug-s /usr/bin/admintool /usr/lib/fs/ufs/quota /usr/bin/fdformat /usr/bin/eject /usr/bin/volcheck /usr/bin/volrmmount /usr/bin/rmformat /usr/platform/*/sbin/eeprom /usr/sbin/wall
chmod ug-s /usr/sbin/arp /usr/bin/write /usr/sbin/sacadm /usr/sbin/*/sysdef /usr/sbin/*/prtconf /usr/platform/*/sbin/prtdiag* /usr/sbin/*/swap
11.
If we don't use Openwindows and CDE, for example on servers:
chmod ug-s /usr/dt/bin/* /usr/openwin/*/*
chmod ug-s /usr/dt/bin/* /usr/openwin/*/*
12.
Sendmail: Hosts which are not email relays or servers don't need
it to be SUID:
chmod u-s /usr/lib/sendmail
chmod u-s /usr/lib/sendmail
13.
If only root needs to manage devices
chmod u-s /usr/sbin/allocate /usr/sbin/mkdevalloc /usr/sbin/mkdevmaps /usr/sbin/list_devices /usr/sbin/deallocate
chmod u-s /usr/sbin/allocate /usr/sbin/mkdevalloc /usr/sbin/mkdevmaps /usr/sbin/list_devices /usr/sbin/deallocate
14.
If only root needs to set power management:
chmod ug-s /usr/sbin/pmconfig
chmod ug-s /usr/sbin/pmconfig
15.
If the Solaris8 project feature is not used, 'newtask' does not
need SUID:
chmod ug-s /usr/bin/newtask
chmod ug-s /usr/bin/newtask
16.
Only root manages quotas (Solaris 7 and younger)
chmod ug-s /usr/lib/fs/ufs/quota
chmod ug-s /usr/lib/fs/ufs/quota
17.
If users don't need to change group identification:
chmod ug-s /usr/bin/newgrp
chmod ug-s /usr/bin/newgrp
18.
Only allow root to query IPC (inter process communication) status.
To check if IPC is used on your system, run: ipcs
chmod ug-s /usr/*/bin/*/ipcs /usr/bin/*/ipcs
chmod ug-s /usr/*/bin/*/ipcs /usr/bin/*/ipcs
After
appling the above commands on a Solaris 7 or 8 "user bundle" install,
the list of SUIDs left is reduced to the following:
find / -type f \( -perm -u+s -o -perm -g+s \) -ls
find / -type f \( -perm -u+s -o -perm -g+s \) -ls
SUID
files:
/usr/lib/pt_chmod /usr/lib/utmp_update /usr/bin/login /usr/bin/passwd /usr/bin/pfexec /usr/bin/su /usr/sbin/ping /opt/local/bin/ssh
/usr/lib/pt_chmod /usr/lib/utmp_update /usr/bin/login /usr/bin/passwd /usr/bin/pfexec /usr/bin/su /usr/sbin/ping /opt/local/bin/ssh
SGID
files:
/usr/bin/mail /usr/bin/mailx
Note: You'll also find that /usr/bin/yppasswd /usr/bin/nispasswd are SUID, but they are links to /usr/bin/passwd, so removing the SUID bits will stop normal users from changing their local passwords!
/usr/bin/mail /usr/bin/mailx
Note: You'll also find that /usr/bin/yppasswd /usr/bin/nispasswd are SUID, but they are links to /usr/bin/passwd, so removing the SUID bits will stop normal users from changing their local passwords!
Some auditing ideas:
- We could check that all SUID files on the system are in
the package database and haven't been changed:
> find / -perm -u+s -exec pkgchk -p {} \; | more
The package database only uses "checksums" (not hashes/signatures) and could easily be modified by an attacker, so don't trust the package commands as 'proof' that binaries are non modified, consider it rather an indication. - Or we could list all SUID files, with details of what
packages they belong to:
> find / -perm -u+s -exec pkgchk -l -p {} \; | more
Further reading:
- Reg Quinton explains [8] each
Solaris SUID file and recommends settings, together with an appropriate
script that can be customised. The recommended settings are for
"medium" security systems.
- See [8] for
SUID references and further reading.
More file permissions
tightening:
chmod o-rx
/etc/security #Not needed
for Solaris8 or later
chmod 400 /.shosts /etc/sshd_config /etc/ssh_known_hosts
chmod 400 /.shosts /etc/sshd_config /etc/ssh_known_hosts
To Do:
It would be useful to
have packages that reset the SUID files for examples situations such as Bastion
Hosts (high), multi-user servers (medium), workstations (low). The packages
would also correct the pkg database so that 'pkgchk -n' would not report
permissions errors after the SUID files had been adapted.
11. Install an Integrity Checker: e.g. Tripwire
You should regularly
check the integrity of files on the system, to be assured that they have not
been maliciously modified. Solaris provides "pkgchk -n" which checks
the package databases against the size, permissions and checksums of actually
installed files. This is useful and recommended, however checksums can be
fooled and the package database can itself be manipulated, so it is no
protection against the clever attacker (or the script Kiddie with a clever
rootkit). What is required, is a file integrity checker that uses secure
(one-way) hashing algorithms.
Which is why the Yassp
Tarball installs tripwire in /secure/tripwire. Tripwire uses
several secure hashing algorithms (and in it's commercial form, provides
cryptographic signing of it's database).
At this stage of the
installation, it is recommended to take a snapshot of the files on the newly
configured system, i.e. initialise tripwire's database and then run regular
checks to monitor for changes. If possible, keep the master database on another
machine, offline or on write-once media.
What options do we have
for integrity checking?
- Tripwire [5]:
There are both free and commercial versions (which costs ~$500.-/host).
- The free version can be tricky to get working
correctly and has a few bugs. Source code is provided. It may crash on
very large disks. This is the version included with Yassp.
- The commercial version is a bit pricey, reports are
verbose (you'll need filter scripts - V2.2.1 is better in this regard,
then again 2.2.1 is buggier than 2.0.1), more configuration examples
should be provided. It is more stable than the free version, also runs on
RH Linux and NT and offers enhanced security by cryptographic signing of
policy and configuration files. Support (even when paid for) is not
great.
- Neither version supports the use of regular
expressions when defining policy rules. e.g. you can't specify a rule for
"/home/*/www/cgi-bin" files, that would work even when new
directories are added under /home.
- Tripwire was released as OpenSource for Linux (but not
Solaris) in October 2000.
- A good mix is to use the commercial version on secured
central host, which then runs the free version remotely via SSH on all
other hosts (see trip_host.sh notes below).
- PGP can also be used, by signing files to be protected
(creating lots of signature files), then writing a script to check the
validity of signatures. This will not catch permission, link, inode or
modify date changes though.
- MD5 signatures (one way hashes that are more secure
than non-unique CRC checksums) could be used in a similar way, but the
list of MD5 signatures should not be stored on the system being monitored,
unless it is PGP signed or encrypted.
- Aide is
a new GPL tripwire replacement [12] that looks interesting, I've not had a chance to
test it so far.
An example using the
free Tripwire Version 1.2 (bundled with Yassp):
- Use the Yassp installed version in
/secure/tripwire/tripwire with an example configuration tw.config [3],
or pick up the sources and compile.
- Adapt /secure/tripwire/tw.config for your site, if
needed.
- Next, the "initial state" of the system needs
to be saved:
cd /secure/tripwire; ./tripwire -i 2 -initialise -c tw.config
This will create a new file database (which may take 5-15 minutes). Lots of warnings like "No such file or directory" may appear, just ignore them.
Note: we run tripwire with the "-i 2" option to increase speed (it disables one checking algorithm, snerfu, but SHA1 and MD5 are still used).
Copy the newly created database (in /secure/tripwire/databases) to a floppy or another machine where it is safe (encrypt it if possible). This backup of the tripwire database will be useful for forensics, if the machine is ever attacked or suspected of being modified. - The checking can be run each day from cron, or manually
via:
./tripwire -i 2 -c tw.config - To tell Tripwire that (changes to) files or entire
directory trees are OK:
tripwire -update [/file1 /file2 /patch3....] - Improvements:
- The tripwire database can saved on the same machine,
but compress and encrypt or sign it with a strong encryption tool (like
PGP).
- For increased security and automated checking of
several systems from one trusted host, copy tripwire and it's database
and run it remotely at regular intervals using SSH. Delete the tripwire
database on the target after checking.
- This makes it difficult for an attacker to know that
tripwire is being used to check the system. In addition, immediately
update the tripwire database, so that only differences are reported by
successive runs.
- See the sample script trip_host.sh for doing exactly this and filtering all those
annoying "No such file or directory" warnings. It must be run
from the 'master' host which has an SSH trust to the target.
To
run the first time:
/secure/tripwire/trip_host.sh -init HOST
Each time after that:
/secure/tripwire/trip_host.sh -check HOST
/secure/tripwire/trip_host.sh -init HOST
Each time after that:
/secure/tripwire/trip_host.sh -check HOST
To
automate for many hosts, this script is then called from another script for
each host that needs to be monitored. See the sample script trip_all. This script also assumes that the commercial tripwire is used on
the central trusted host (only). The commercial tripwire allows signing of the
tripwire database, which makes it more secure.
- Regularly copy the configuration and database to floppy
disk or write-one media, in a crisis it will be very useful.
Depending on the
function of the server, applications such as ftpd, BIND, proxies, etc. are
installed at this point.
Hardening of specific
applications like ftp, DNS, Email and also general application tips are
discussed in a separate document [16].
13. Going live
Preparing to go live
1.
You probably won't need CD-ROMs or floppies anymore, so disable
the volume manager in /etc/yassp.conf (if it was still enabled, which it not by
default).
If you do need to mount a CD in the future, start vold manually and check for new devices:
drvconfig; disks; vold &; volcheck; df -k
If you do need to mount a CD in the future, start vold manually and check for new devices:
drvconfig; disks; vold &; volcheck; df -k
2.
If partitions such as /opt or /usr had to be mounted read-write
during the application install/testing, consider mounting them read-only now.
3.
Reinitialise tripwire (or equivalent integrity checker).
4.
Backup the system to two tapes, one offsite.
5.
Run a network scan on the system, to ensure that only expected
services are visible. A commercial tool such as ISSor a free one
like Nessus, nmap, Satan/Saint/Sara should do the
job. Print out the results and archive.
6.
If possible, have additional people do the final testing, just in
case something was forgotten.
7.
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.
Going Live
Connect to the live
network. 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?
The following activities
should take place hourly, daily, weekly or monthly, depending on how critical
the system is:
- Check the status of patches with Sun's Patchdiag,
update as needed. Be very wary of kernel patches (test on a non-production
machine).
- Check all logs for errors and unusual activity: syslog
(/var/adm/messages or /var/log/*log, depending on syslog.conf),
/var/cron/log, last, /var/adm/sulog, /var/adm/loginlog, application/server
logs.
- Write scripts to report if critical daemons die, or if
important systems cannot be pinged.
- Run tripwire (or equivalent integrity checker).
- Be regularly informed of new vulnerabilities and
security issues, either by subscribing directly to CERT, CIAC [18]and the vendor security lists (Sun, Microsoft, etc.)
and/or subscribing to newsletters such as those on SecurityFocus or
SANS [19].
The primary goal behind
the development of the Solaris Security Toolkit ("Jass")
was to simplify and automate the process of securing Solaris systems through
JumpStart or in a standalone mode. It implements the recommendations in Sun's
BluePrints security articles. Jass is Sun's answer to Yassp and Titan, and has
evolved into a capable, interesting, Solaris hardening tool.
"The Solaris
Security Toolkit is a tool designed to assist in creation and deployment of
secured Solaris Operating Environment systems. The Toolkit is comprised of a
set of scripts and directories implementing the recommendations made in the Sun
BluePrints OnLine program.
These scripts can be executed on Solaris systems through the JumpStart technology or directly from the command line. The Toolkit includes scripts to harden, patch, and minimize Solaris Operating Environment systems. Sun does not support the Toolkit."
These scripts can be executed on Solaris systems through the JumpStart technology or directly from the command line. The Toolkit includes scripts to harden, patch, and minimize Solaris Operating Environment systems. Sun does not support the Toolkit."
Summary of changes since
version 0.2 (November 2000) -> v0.3:
- Undo capability: This option, -u instructs the program
that a previous run of the Toolkit is to be removed. Because the
jass-execute program is used to access the undo feature, this feature is
only available in standalone mode and not in JumpStart mode
- Updated framework: The Toolkit variable,
JASS_CONFIG_DIR, has been renamed to JASS_HOME_DIR to provide a clearer
meaning as to its use. The JASS_HOME_DIR is defined as the directory
location in which the Toolkit is installed. The SCRIPTS* and FILES*
variables now use the JASS_ prefix (i.e., JASS_SCRIPTS and JASS_FILES) for
consistency. SUNWjass is now a reserved name for the Toolkit software
package format distribution. The Toolkit is now available in this format,
as well as in the original compressed tar format. The same source is
distributed in both distributions. Administrators can also now make their
own packages using the supplied make-pkg script.
A new configuration file, finish.init, has been added to handle all finish script configuration variables. These variables still can be overridden by the user in the user.init file. This file was heavily commented to explain each variable, its impact, and its use in finish scripts. - Changes to profiles
- New driver scripts
- Changes to driver scripts
- New + changed finish scripts
- New file templates: sendmail, c2 auditing
- Miscellaneous changes
- The license is still quite tight: you can use freely
for you own private or corporate, but cannot distribute or publish
derivative works
.
We start off with an
example of running Jass on a new Solaris 8 workstation installed with a 'user
bundle'. An example log of the output is [1]
First we install Jass:
pkgadd SUNWjass-0.3.8.pkg
pkgadd SUNWjass-0.3.8.pkg
Copy over FixModes.tar.Z
to /opt/SUNWjass/Packages, so FixModes will be run as part of the Jass
installation.
Then we run the default
Jass hardening for standalone use:
/opt/SUNWjass/jass-execute -d hardening.driver
/opt/SUNWjass/jass-execute -d hardening.driver
On rebooting we find:
- Although inetd is running, no services are available in
inetd.conf.
- Sendmail is left running is queue mode (will deliver
but not accept remote emails), which is fine.
- The following daemons are left running because they're
not considered risky (they don't listen on any network ports). Personally,
I would prefer to stop every daemon that is not strictly necessary:
root 230 1 0 10:18:21 ? 0:00 /usr/sbin/nscd
root 240 1 0 10:18:22 ? 0:00 /usr/lib/utmpd
root 43 1 0 10:17:59 ? 0:00 /usr/lib/devfsadm/devfseventd
root 45 1 0 10:18:00 ? 0:00 /usr/lib/devfsadm/devfsadmd - BSM auditing is enabled. I have mixed feelings about
this due to the patches need to make it work, logs it generates, and the
problems with root crontabs. It does however create the 'root.au' file.
See also [22].
Next we try the 'undo'
feature which allows us to go back to the configuration before Jass was run. It
very nicely asks us which 'Jass run' we would like to undo:
/opt/SUNWjass/jass-execute
-u
The undo seems to work
fine, except for BSM auditing which is not cleanly removed, see also the undo
log [1]. Jass can be run several times, and the undo can remove the
effects of each previous run or all runs. Nice.
- Jass can be customised to meet you needs, but if you
use the standard hardening.driver, some extra daemons are left running that may not be
needed on some systems: devfseventd, devfsadmd, utmpd, nscd. They do not
listen to any network ports though and so pose less risk.
- The classic fix-modes tool for tightening file permissions and SSH for
secure login must be manually added, or, copy it to the Jass Packages directory
before running Jass, then Jass will run it for you.
- Options like nosuid, noatime or logging are not added
to /etc/vfstab
- The number of suid or sgid files are not reduced.
- Tools such as tripwire, tocsin, Venema's rpcbind / tcpd
are not bundled (but it shouldn't be too difficult to add them).
- Note: the hardening-jumpstart.driver is an example script for actual hardening of
a Jumpstart server (for example, it allows rpc and nfs to
run) and is not a general hardening setup.
- Stable, good quality, modular, sources available, can
automatically install patches and tools such as 'fix-modes' and SSH.
- Can be re-applied after new patches installed.
- Both package format and tarball, script to make custom
packages.
- Multiple level undo feature - a track of activity is
kept in /var/opt/SUNWjass/run.
There are scripts whose actions that can't be undone though: enable-bsm.fin, install-fix-modes.fin, install-jass.fin, install-openssh. fin, install-recommended-patches.fin and install-strong-permissions.fin. - Useful logs are kept of what has been done in
/var/opt/SUNWjass/run.
- Works standalone or with Jumpstart. In Jumpstart mode
it really excels, making Jumpstart more flexible and easier to use.
- An auditing mode can be used to verify some security
points on an existing system:
/opt/SUNWjass/jass-execute -d audit.driver
- The negative issues raised in the section How good is the Jass hardening?
- The license 'free', but quite tight: you can use freely
for your own private or corporate use, but cannot distribute or publish
derivative works.
- Casper Dik's 'fix-modes' script for improving file
permissions is not bundled with Jass, although a script exists for
installing it. Why not make a tarball that includes Jass and some key
tools such as fix-modes and SSH? the same applies to md5.
- Documentation error: Jass can install recommended
patches, if they are in /opt/SUNWjass/Patches when run. This is not
mentioned in the quickstart Guide (v0.31).
- There is no central configuration file (like Yassp's /etc/yassp.conf), where "boot time"
security settings (such asumask or which daemons are started)
can be personalised to suit the needs of a specific system. With Jass,
these must be set beforehand by editing the scripts and re-running Jass.
- New daemons are often added to Solaris point releases,
Jass will have to be updated for each of these. Jass won't catch
application daemons either.
- Issues with v0.30:
- There is no variable to pass '-nosave' to
the install_cluster command for patch installation (fixed in v0.31: Add
JASS_REC_PATCH_OPTIONS="-o -d" to user.init).
- BSM auditing is enabled by default, but it can be
disabled by commenting out the BSM line inDrivers/hardening.driver.
- Syslog is configured to log everything locally in /var/adm/messages,
strangely no forwarding to loghost is done if this alias
is defined.
- Solaris Intel packages are not available.
- JASS_FILES
- Files are only installed from the Files directory if
they are listed in the JASS_FILES variable in Driver/hardening.driver. It
would be useful if all files in the Files directory were copied would
adapting the scripts, but then again, perhaps it's preferable to copy
only specific files to specific hosts depending on architecture, hostname
etc?
- If you list a directory in JASS_FILES, and it has
subdirectories, files will not be copied correctly, landing in the wrong
level of the tree. Workaround: specify each file exactly for now.
- Default router is not set automatically
(most subnets use a fixed number for all routers, e.g. '.1').
- Root's GECOS field is not set. It would be useful if it
was set to 'root at HOSTNAME', with HOSTNAME set accordingly.
Summary
Jass is an interesting
tool, well worth checking out. The fact that is sponsored (although not
supported) by Sun, has most of the features of other hardening packages and is
under constant improvement, should ensure it's elevation to a quasi standard.
The following are
improvements/ideas that you may find useful to Jass in your environment.
Example scripts can be found here. We assume the main driver used is hardening.driver.
1.
If a patch bundle is copied to /opt/SUNWjass/Patches (or
/jumpstart/Patches), they are automatically installed.
In v0.30, it is useful to adapt the script Finish/install-recommended-patches.fin so that 'install_cluster' is called with the '-nosave' option. On a new installs, I don't see the point in saving old patches and tying up tens of megabytes of space.
In v0.31 add JASS_REC_PATCH_OPTIONS="-o -d" to user.init
In v0.30, it is useful to adapt the script Finish/install-recommended-patches.fin so that 'install_cluster' is called with the '-nosave' option. On a new installs, I don't see the point in saving old patches and tying up tens of megabytes of space.
In v0.31 add JASS_REC_PATCH_OPTIONS="-o -d" to user.init
2.
Accounting and BSM auditing are enabled by default in v0.31 and
v035, which I don't recommend. They can de disabled by commenting the lines
'enable-bsm.fin' and 'enable-process-accounting.fin' inDrivers/hardening.driver.
3.
Before running Jass, copy md5.tar.Z and FixModes.tar.Z to /opt/SUNWjass/Packages to ensure they are installed when Jass is run.
4.
Scripts can be added to disable other daemons. For example to
disable the nscd daemon (which may not be needed in all
environments), add a new script to Finish/disable-nscd.fin which
contains:
echo
"Disabling nscd startup and shutdown scripts"
echo ""
if [ "${JASS_KILL_SCRIPT_DISABLE}" = "1" ]; then
disable_rc_file ${JASS_ROOT_DIR}/etc/rcS.d K40nscd
disable_rc_file ${JASS_ROOT_DIR}/etc/rc0.d K40nscd
disable_rc_file ${JASS_ROOT_DIR}/etc/rc1.d K40nscd
fi
disable_rc_file ${JASS_ROOT_DIR}/etc/rc2.d S76nscd
echo ""
if [ "${JASS_KILL_SCRIPT_DISABLE}" = "1" ]; then
disable_rc_file ${JASS_ROOT_DIR}/etc/rcS.d K40nscd
disable_rc_file ${JASS_ROOT_DIR}/etc/rc0.d K40nscd
disable_rc_file ${JASS_ROOT_DIR}/etc/rc1.d K40nscd
fi
disable_rc_file ${JASS_ROOT_DIR}/etc/rc2.d S76nscd
Then
we add disable-nscd.fin to the JASS_SCRIPTS section of Drivers/hardening.driver,
to activate the above script..
5.
We can set the default router automatically (to A.B.C.1)
by adding a file Finish/set-defaultrouter.fin, that contains the
following. A line containing set-defaultrouter.fin also needs
to be added to Drivers/hardening.driver.
#
Get IP address, chop off the host part and add ".1"
inet=`ifconfig -a | grep inet | egrep -v "127.0.0.1" | awk '{print $2}'`
#echo $inet
router=`echo $inet | awk -F'.' '{print $1 "." $2 "." $3 ".1"}'`
#echo $router
echo $router >> /a/etc/defaultrouter
inet=`ifconfig -a | grep inet | egrep -v "127.0.0.1" | awk '{print $2}'`
#echo $inet
router=`echo $inet | awk -F'.' '{print $1 "." $2 "." $3 ".1"}'`
#echo $router
echo $router >> /a/etc/defaultrouter
6.
Jass will replace some files on the system, the new versions are
found in the Files subdirectory. Depending on your
preferences, you may wish to tweak some files, such as:
.cshrc,
.login - improve the path + prompt, reduce umask and add some aliases.
etc/syslog.conf - log to a central loghost and locally (see syslog.conf).
etc/motd, etc/issue, etc/default/ftpd, etc/default/telnetd - warning banners
etc/nsswitch.conf - add dns to host lookups or add NIS or NIS+
etc/syslog.conf - log to a central loghost and locally (see syslog.conf).
etc/motd, etc/issue, etc/default/ftpd, etc/default/telnetd - warning banners
etc/nsswitch.conf - add dns to host lookups or add NIS or NIS+
7.
If you use DNS and the client setup is the same for your jumpstart
hosts, then copy a template /etc/resolv.conf into /jumpstart/Files/etc and then
add '/etc/resolv.conf' to $JASS_FILES in Drivers/hardening.driver.
8.
This method can be used to add any other files that need to be
copied over during Jumpstart installation.
In addition, files that depend on hostname ('uname -n') and architecture ('uname -r') can be defined, which allow for a jumpstart customised for specific hosts, e.g.
In addition, files that depend on hostname ('uname -n') and architecture ('uname -r') can be defined, which allow for a jumpstart customised for specific hosts, e.g.
/etc/resolv.conf.$HOSTNAME
/etc/resolv.conf.$OS
/etc/resolv.conf.$OS
9.
To remove the numerous suid/sgid files (see the section limiting SUID Files), a file Finish/remove-suid.fin can be created and added to Drivers/hardening.driver.
10.
The Drivers/user.init was created with some
custom settings, to tailor behaviour for this system (for instance sendmail is
configured for queuing and not as an smtp server, /tmp can only take up 200MB
of swap space, daemons won't create world readable files, etc.
#
user.init
# sb, 02.Oct.01
JASS_AGING_MAXWEEKS="26"
JASS_AGING_WARNWEEKS="1"
JASS_AGING_MINWEEKS="0"
JASS_LOGIN_RETRIES="5"
JASS_PASS_LENGTH="6"
JASS_SENDMAIL_MODE="\"\""
JASS_TMPFS_SIZE="500m"
JASS_UMASK="027"
JASS_SHELL_DISABLE="/sbin/noshell"
JASS_CRON_LOG_SIZE="20480";
# sb, 02.Oct.01
JASS_AGING_MAXWEEKS="26"
JASS_AGING_WARNWEEKS="1"
JASS_AGING_MINWEEKS="0"
JASS_LOGIN_RETRIES="5"
JASS_PASS_LENGTH="6"
JASS_SENDMAIL_MODE="\"\""
JASS_TMPFS_SIZE="500m"
JASS_UMASK="027"
JASS_SHELL_DISABLE="/sbin/noshell"
JASS_CRON_LOG_SIZE="20480";
##
When used with Jumpstart:
JASS_ROOT_PASSWORD="xxxsomethingxxencryptedxxxx"
SERVER="17.17.17.2"
JASS_PACKAGE_MOUNT="${SERVER}:/jumpstart/Packages";
JASS_PATCH_MOUNT="${SERVER}:/jumpstart/Patches";
JASS_ROOT_PASSWORD="xxxsomethingxxencryptedxxxx"
SERVER="17.17.17.2"
JASS_PACKAGE_MOUNT="${SERVER}:/jumpstart/Packages";
JASS_PATCH_MOUNT="${SERVER}:/jumpstart/Patches";
##
v0.3.1
## Don't save files replaced by patches:
JASS_REC_PATCH_OPTIONS="-o -d"
## Don't save files replaced by patches:
JASS_REC_PATCH_OPTIONS="-o -d"
11.
The default terminal, TERM is set to vt100 in /etc/.login by Finish/set-term,
which is fine for servers managed by the serial console, but less useful for
Workstations, or servers when a GUI is console is necessary (of course avoiding
a GUI console is recommend for security). To disable the TERM setting, comment
the set-term line inDrivers/hardening.driver.
12.
Sun recommend that if you change hardening.driver (or
other Jass scripts), it is best to copy it toxyz_hardening.driver and
run this new driver (where 'xyz' would be an abbreviation of your company or
department name). In this way, when you install new Jass versions, they can
fearlessly overwrite the default scripts and you can use 'diff' to check for
changes.
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.
There are many more issues than just those above, we address some more advanced
topics in this section:
- EEPROM security
options, or protecting the Console::
- On high availability servers where the console is
exposed, switch on security which requires a password to be entered each
time the EEPROM prompt is accessed.
a) This should be used with care, as forgetting the password can render a machine useless.
b) This password is needed for each reboot (so console access is needed for rebooting)
c) This has the additional benefit of preventing a DoS attack: if an attacker does penetrate the machine at some stage later in it's life, he cannot set a random password and hence render the host useless until the NVRAM has been replaced.
eeprom security-mode=command - The Stop-A keyboard sequence can be disabled by
setting KEYBOARD_ABORT to disable in /etc/default/kbd. Of course
"STOP-A; sync" won't work anymore which can be a major
inconvenience, so it's suggested only for physically insecure
environments.
- If managing a console via serial cable, an alternate
BREAK signal can be set up to prevent terminal power cycles causing a
stop of the console and to allow the break signal to be sent from
terminal emulators that cannot send a BREAK signal properly (e.g.
HyperTerminal). STOP-A behaviour from a graphical console will not be
affected by this setting.
The change is available as follows:
2.5.1 or lower: upgrade to 2.6 or better
2.6: requires patch 105924-10 or later
7: requires patch 107589-02 or later
8: functionality is already integrated.
To enable the new break signal (which is <RETURN> <TILDE> <CONTROL-B>), edit /etc/default/kbd and set KEYBOARD_ABORT=alternate. (Make sure Tilde works correctly on your keyboard first!). - Time
Synchronisation:
• If you think you might have to produce evidence in court, use NTP to synchronise time, not rdate. Prosecutions have failed because, on busy servers, a few seconds difference could be used to insist that there is a doubt about the identity of a session. (This happened to a bank in Australia trying to prosecute an Internal Attacker).
• If using NTP, either get a cheap radio clock (if you are near an appropriate transmitter - e.g. the Stuttgart transmitter in Germany), or setup a dedicated bastion host as a 2nd stratum NTP server, which uses three 1st stratum sources.
• Setup the firewall filter to allow only NTP from the bastion NTP server to the three 1st stratums and allow Intranet hosts to query the bastion.
• Other hosts can synchronise to the NTP servers via a simple cron command, they don't have to run the ntp daemon. This is my favourite way of using NTP clients, due to it's simplicity and inherent security.
/usr/sbin/ntpdate -s ntp1 ntp2 ntp3
• NTP can also be setup for higher security by configuring DES+MD5 authentication keys on server and client, seeman xntpd.
• Sun published a 'blueprint' on NTP in August 2001, that covers most issues:
http://www.sun.com/blueprints/0801/NTPpt2.html - Use Jumpstart: for installing large numbers of hosts,
or to be able to quickly produce a new hardened host (perhaps after a
failure). Jumpstart is not much easier to setup and customise with Jass.
- If you are using multiple network interfaces, you may
want to use a different MAC address for each of them. By default, Solaris
will use the same MAC addresses for all the network interfaces connected
to the same box (It will use the MAC address which is burnt in the EEPROM
motherboard). If you want each network interfaces to use its own MAC
address, type:
eeprom local-mac-address\?=true - Logging:
- in addition to centralised syslogs, you might like to
keep an additional local copy - in case the syslog server goes down or is
subjected to a denial of service attack. Make sure /var is a separate
filesystem if you use local logging, to avoid root being filled and the
system stopping.
- There are several improved syslog daemons [17] .
- Intrusion detection:
- Regular logfile analysis can be implemented with
customer scripts or tools such as logcheck and swatch [6].
- Integrity checkers: see section above.
- Tocsin: Doug Hughes (Doug.Hughes@Eng.Auburn.edu) wrote tocsin,
a "featherweight network intrusion detection system" back in
1996. It is a free tool that listens for network scans. Tocsin only needs
to be installed once per subnet, unless switches are used i.e. all nodes
do not see all traffic. It uses DLPI [see note1] kernel
level packet filtering and runs out of the box on SunOS and Solaris to
catch port and stealth scans (SYN, FIN, ACK, Xmas, RST, etc). Alert
messages are logged to syslog 'auth', startup and shutdown messages are
logged to 'daemon'.
In
August 2000, tocsin was significantly improved and version
2.1.1.2 released:
• fixed log file permissions
• new tcp or udp options (:t or :u) per service
• ported to Solaris 8 sparc/Intel
• new common package for Solaris sparc/Intel
• change UID to nobody after binding to the network
• new man page and startup file 'S70tocsin' added
• New options: -T tcp only, -D destination network only, -O log IP options, -I invert port matching filter conditions.
• fixed log file permissions
• new tcp or udp options (:t or :u) per service
• ported to Solaris 8 sparc/Intel
• new common package for Solaris sparc/Intel
• change UID to nobody after binding to the network
• new man page and startup file 'S70tocsin' added
• New options: -T tcp only, -D destination network only, -O log IP options, -I invert port matching filter conditions.
This
amazing little tool (it's only 20kB) is simple, but works quite well. The new
options allow significant reduction of false positives. For this article, it
was tested on Solaris 2.7-2.8/sparc and Solaris 2.8/Intel, but it should run on
Solaris 2.6 and possible 2.5.1 also.
tocsin can be downloaded in source form (tocsin.tar.gz), or a Solaris package (AUBtocsin), from [4].
tocsin can be downloaded in source form (tocsin.tar.gz), or a Solaris package (AUBtocsin), from [4].
Recommendation:
Install one Tocsin per subnet, or on several sensitive hosts if switches rather
than hubs are used, since all subnet traffic cannot be monitored by one Tocsin
daemon.
Note1: DLPI is the Datalink
Provider Interface (a standard based on ISO 8886 and 8802 for Streams based
kernel implementations of packet filtering)
- I have written a perl script monitor_socket.pl [3] that listens to a list of sockets and notifies
by email and syslog if a connection is received. It was originally
written to detect Sybase and Satan connection attempts. Tocsin above,
is a superior solution by far though.
- SSH notes: See www.boran.com/security/sp/ssh-part2.html for a discussion to how to compile and make
packages for Sun.
Configure
an appropriate /etc/ssh_config file (see also [7]), so that access is restricted to named hosts with known public
keys (/etc/ssh_known_hosts) and rhosts authentication is disabled. Avoid
trusts. Only allow specific users and hosts to access SSH. Deny daemon accounts
access.
- Boot disk backup: Minimum downtime and prevention of data-loss is
important for most servers. The traditional solution is to use a RAID box
to cover for disk failures. However, if the root /usr /var filesystems are
on RAID and the raid controller goes, you have a problem (unless you have
a fully redundant raid). I've been caught out twice over the last years by
failed fibre channels and controllers and I now use RAID for data disks,
put system files on a "normal" disk and mirror to an identical
disk each night. If the boot disk dies, boot from the second disk.
The script mirror_boot.sh has been developed to do just that, coldmirroring20010306.html
- C2 auditing/BSM: Solaris contains an audit trail feature called Basic
Security Module (BSM). This can be useful for tracking commands executed
by users. See also [22].
- Headless x86: It is possible to get PCs to use the serial port A
(COM1) as their consoles. On Solaris 8:
eeprom ttya-ignore-cd=true
eeprom input-device=ttya
eeprom output-device=ttya
However the keyboard must be left attached (my test Compaq PC did not have a BIOS option to disable the keyboard).
See also Question 6.20 on www.sun.pmbc.com/faq/6.html and aa11.cjb.net/sun_managers/2000/01/msg00326.html - Versioning: It's a good idea to keep previous versions of
configuration files, to allow rollback and have an audit trail. This is
called versioning. It is especially important when several
administrators manage a host, changes are frequent, etc. Versioning can
also be used with Jumpstart scripts and config files. Some sysadmins
use RCS (included in Yassp), some use CVS,
some copy the configuration file to file.DATE before hand, some do nothing
:).
Francisco Mancardi [fman@uyr.com.ar] has written a simple script that can be used to save a copy of a file or directory before doing modifications.
Saveit is a little tool to make a backup of config files before you change them. It saves a copy under /Backup.d/DATE/ and logs "who saved what file" in /Backup.d/log-DATE. The existing directory structure is preserved under the backup directory.
It's a simple, but useful version control tool for text files. e.g.
etc/[9]%
saveit vfstab
copying file vfstab ===> /Backup.d/20000707/etc/vfstab
etc/[61]% saveit vfstab
copying file vfstab ===> /Backup.d/20000707/etc/vfstab.13:37
etc/[10]% ls -l /Backup.d/20000707/etc/vfs*
-rw-r--r-- 1 root sys 386 Mar 14 08:31 /Backup.d/20000707/etc/vfstab
-rw-r--r-- 1 root sys 386 Mar 14 08:31 /Backup.d/20000707/etc/vfstab.13:37
etc/[11]% tail /Backup.d/log-20000707
----------------------------------
Backup base directory /Backup.d
Backup requested by root
Date (dd/mm/aaaa) 07-07-2000
Time 11:36
/etc/vfstab
--------------------------------------------------------------
Backup base directory /Backup.d
Backup requested by root
Date (dd/mm/aaaa) 07-07-2000
Time 13:37
/etc/vfstab
copying file vfstab ===> /Backup.d/20000707/etc/vfstab
etc/[61]% saveit vfstab
copying file vfstab ===> /Backup.d/20000707/etc/vfstab.13:37
etc/[10]% ls -l /Backup.d/20000707/etc/vfs*
-rw-r--r-- 1 root sys 386 Mar 14 08:31 /Backup.d/20000707/etc/vfstab
-rw-r--r-- 1 root sys 386 Mar 14 08:31 /Backup.d/20000707/etc/vfstab.13:37
etc/[11]% tail /Backup.d/log-20000707
----------------------------------
Backup base directory /Backup.d
Backup requested by root
Date (dd/mm/aaaa) 07-07-2000
Time 11:36
/etc/vfstab
--------------------------------------------------------------
Backup base directory /Backup.d
Backup requested by root
Date (dd/mm/aaaa) 07-07-2000
Time 13:37
/etc/vfstab
The
advantage of this tool are: simplicity and no clogging up the current directory
with old versions of files, rcs directories etc. The script can be
downloaded [3].
No comments:
Post a Comment