Tuesday Sep 28, 2004
Today's topic is short and sweet: password history. For those who are not aware, the concept
of password history is to prevent users from repeatedly selecting the same (set) of passwords
over and over again (within some fixed time window). The actual time window will depend on
the configuration of the system.
Often, password history is used in combination with password composition rules and password aging.
For example, an organization may prohibit user's from selecting a password that is defined in
some dictionary list or one that does not meet some minimum set of composition requirements.
Further, the same organization may also mandate that user's must change their password every
ninety days (but no sooner than one week after the last successful change). The goal here is to
require users to select strong passwords, change them regularly and limit their future reuse.
Without password history, what would stop a user from repeatedly selecting the same password
(or small set of passwords - or even just rotating between two valid passwords) at each password
expiration event?
Password history helps to solve this issue by enforcing a policy that says that a user may not
reuse any of the last n passwords (where n is defined by the organization). So,
for example, by setting both password history and aging settings appropriately, an organization
could prevent the reuse of passwords for a significant period of time.
So, let's talk about specifics. New to Solaris 10 is the HISTORY parameter in the
/etc/default/passwd file.
This new parameter specifies the number of passwords that will be remembered - and consequently
compared against a user's new password to see if it had been used before. By default, password
history is disabled. If you want to enable password history then you must uncomment the
HISTORY parameter and assign it a value. This value will indicate the number of
passwords that the system should remember. This parameter can take values ranging from 0 to
26. For example:
# grep "^HISTORY=" /etc/default/passwd
HISTORY=10
In this example, password history has been enabled and a user's last ten passwords will be
remembered. So, if I user attempts to re-use a password that is in their history, the
change will be denied and the user will be presented with the following message:
$ passwd gmb
Enter existing login password:
New Password:
passwd: Password in history list.
Please try again
New Password:
Once password aging has been enabled, it can be disabled by setting the HISTORY
parameter to 0 or by commenting it out in the /etc/default/passwd file. Once this is
done, all users' prior password history will be discarded at the next password change
by any user. Note that this is a very important point. When password history is
disabled, the entire password history database will be discarded upon the next password
change event by any user on the system.
In my previous posts I have tried to highlight global changes versus settings that
can be applied to individual users. In the case of password history, it can only be
defined on a global basis. There are no per-user settings for this feature.
Now that I have covered the basics of enabling, configuring and disabling password
history, one last question may still be nagging at you - where is the password history
database kept? The password history database is stored in the /etc/security/passhistory
file. This file is an implementation artifact of the password history feature and is
not meant to be modified by end users. This file has the following ownership and
permissions:
-r-------- 1 root root 47 Sep 28 22:21 /etc/security/passhistory
Those curious enough to poke around this file will find that it contains a list of
users (one per line) as well as their last n password hashes separated by a
colon. For example, the above file has the following contents:
# cat /etc/security/passhistory
gmb:TRltRapbB7Eek:l5rXbTq1EJ7bQ:yEB668aaGv5z6:LgbM3LpCsERlA:
What is really cool about how password history is implemented in Solaris 10 is that it
will work as you change your default password encryption algorithm using the flexible
crypt mechanism (introduced in Solaris 9). For example, after
changing my password encryption algorithm from the Solaris default to Blowfish, this
is what happens:
# grep "^HISTORY=" /etc/default/passwd
HISTORY=10
# grep "^CRYPT_DEFAULT=" /etc/security/policy.conf
CRYPT_DEFAULT=__unix__
# cat /etc/security/passhistory
gmb:aMPK0ug.Syoag:Lp145TNOHmdlM:
# grep "^CRYPT_DEFAULT=" /etc/security/policy.conf
CRYPT_DEFAULT=2a
# grep "^2a" /etc/security/crypt.conf
2a crypt_bsdbf.so.1
# passwd gmb
New Password:
Re-enter new Password:
passwd: password successfully changed for gmb
# cat /etc/security/passhistory
gmb:$2a$04$A.vGapPSCtbmXj3B9hYK..7fkgJqpg3YKXFoOt1T.YLBk0xw5p9E.:aMPK0ug.Syoag:Lp145TNOHmdlM:
First, I verified that I was using the default password encryption algorithm ("__unix__").
I used the passwd(1) command twice (not shown) to define passwords for the gmb account.
Those password hashes were recorded in the /etc/security/passhistory file. I then
changed the default password encryption algoritm to Blowfish ("2a") and changed the
password for the gmb account once more. Each time I changed the password, I
used a new, unique password.
Now we are ready for the real test. I will try to select each of the three passwords that
are in my password history. Two of the passwords are currently stored in default ("__unix__")
format and the other is stored in Blowfish format.
$ passwd gmb
Enter existing login password:
New Password:
passwd: Password in history list.
Please try again
New Password:
passwd: Password in history list.
Please try again New Password:
passwd: Password in history list.
Permission denied
As you can see, in each case, the password was recognized as having been in my
password history. So, it doesn't matter if you simply use the default password
algorithm or select another. This functionality will still just work. Don't
you just love it!
Well, this one ran a little longer than I had originally thought, but I hope that
you found it interesting nonetheless. Check back soon for another installment of
lesser known and/or publicized security enhancements to the Solaris 10 OS. I still
have a bunch lined up for you!
Let me know what you think of this series of articles as well as ideas for future
updates. Take care!
Technorati Tag:
OpenSolaris
Solaris
security
Monday Sep 27, 2004
The topic for this article is the Solaris 10
Reduced Networking Software Group (also commonly known as the Solaris 10 Reduced Networking Meta Cluster).
This software group is new and joins the five existing software groups available in Solaris today: Core,
End User, Developer, Entire and Entire + OEM software groups. The Reduced Networking Software Group is
positioned as a subset of Core and represents the smallest amount of Solaris that can or should be installed
and have a working and supported system. Note that for support reasons, it is not advised to remove
packages installed by the Reduced Networking Software Group.
To install the Reduced Networking Software Group, simply select it from the list when doing a graphical
installation. If you are using JumpStart, then you should use the cluster keyword with the new
value SUNWCrnet. The following is a sample JumpStart profile that uses the Reduced Networking
Software Group. This profile was also used to build the system used as an example in this article.
install_type initial_install
cluster SUNWCrnet
partitioning explicit
filesys rootdisk.s1 768 swap
filesys rootdisk.s0 free /
system_type standalone
During the installation process, you will see messages similar to the following:
Processing profile
- Selecting cluster (SUNWCrnet)
- Selecting all disks
- Configuring boot device
- Using disk (c0t0d0) for "rootdisk"
- Configuring swap (c0t0d0s1)
- Configuring / (c0t0d0s0)
One thing that may draw your attention is the following install-time message:
Verifying space allocation
- Total software size: 152.67 Mbytes
Yes, it's true - the size of this installation is just a little over 150-Mbytes.
Note that this size is based on the build of Solaris 10 that I was using and will
certainly change before Solaris 10 is finalized, but I did want to mention it as
an example of how small a Solaris installation can be. By leveraging the Reduced
Networking Software Group, you are providing yourself with a solid foundation on
which to deploy a minimized platform. So, let's see what we have...
# df -k
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c0t0d0s0 7929156 164697 7685168 3% /
/devices 0 0 0 0% /devices
ctfs 0 0 0 0% /system/contract
proc 0 0 0 0% /proc
mnttab 0 0 0 0% /etc/mnttab
swap 956144 224 955920 1% /etc/svc/volatile
objfs 0 0 0 0% /system/object
fd 0 0 0 0% /dev/fd
swap 955928 8 955920 1% /var/run
swap 955920 0 955920 0% /tmp
By the time all is said and done, the installed system is up to 161M. At
present, this accounted for about 81 packages. This default configuration
includes 28 set-uid programs and 11 set-gid programs. This is all much
less than what is typically installed on most systems today. As noted
above, this will certainly change before Solaris 10 is finalized, so don't
hold me to those
exact numbers. :-)
What is actually running on this system by default on this system? To
answer this question, we look at the output of ps -aef:
# ps -aef
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 21:52:19 ? 0:06 sched
root 1 0 0 21:52:22 ? 0:00 /sbin/init
root 2 0 0 21:52:22 ? 0:00 pageout
root 3 0 0 21:52:22 ? 0:01 fsflush
root 432 376 0 22:31:05 console 0:00 ps -aef
root 7 1 0 21:52:24 ? 0:03 /lib/svc/bin/svc.startd
root 9 1 0 21:52:24 ? 0:16 svc.configd
root 394 385 0 22:00:00 ? 0:00 /usr/lib/saf/ttymon
daemon 335 1 0 21:53:40 ? 0:00 /usr/sbin/rpcbind
root 340 1 0 21:53:40 ? 0:00 /usr/sbin/keyserv
daemon 279 1 0 21:53:27 ? 0:00 /usr/lib/crypto/kcfd
root 376 7 0 21:59:59 console 0:00 -sh
root 278 1 0 21:53:26 ? 0:00 /usr/sbin/nscd
root 79 1 0 21:52:46 ? 0:00 /usr/lib/sysevent/syseventd
root 411 1 0 22:00:03 ? 0:00 /usr/lib/fm/fmd/fmd
root 367 1 0 21:59:58 ? 0:00 /usr/lib/utmpd
root 385 7 0 22:00:00 ? 0:00 /usr/lib/saf/sac -t 300
root 389 1 0 22:00:00 ? 0:00 /usr/sbin/syslogd
root 395 1 0 22:00:00 ? 0:00 /usr/lib/inet/inetd start
root 397 1 0 22:00:00 ? 0:00 /usr/sbin/cron
As you can see, really only the bare minimum. This is also confirmed by our
look at those network ports that are in use as reported by netstat -an:
# netstat -an
UDP: IPv4
Local Address Remote Address State
-------------------- -------------------- -------
*.111 Idle
*.* Unbound
*.32772 Idle
*.514 Idle
*.* Unbound
TCP: IPv4
Local Address Remote Address Swind Send-Q Rwind Recv-Q State
-------------------- -------------------- ----- ------ ----- ------ -------
*.* *.* 0 0 49152 0 IDLE
*.111 *.* 0 0 49152 0 LISTEN
*.* *.* 0 0 49152 0 IDLE
TCP: IPv6
Local Address Remote Address Swind Send-Q Rwind Recv-Q State If
--------------------------------- --------------------------------- ----- ------ ----- ------ ----------- -----
*.* *.* 0 0 49152 0 IDLE
SCTP:
Local Address Remote Address Swind Send-Q Rwind Recv-Q StrsI/O State
------------------------------- ------------------------------- ------ ------ ------ ------ ------- -----------
0.0.0.0 0.0.0.0 0 0 102400 0 32/32 CLOSED
Active UNIX domain sockets
Address Type Vnode Conn Local Addr Remote Addr
30001307e08 stream-ord 30001292a80 00000000 /var/run/.inetd.uds
As you can see, only a handful of ports are actually open by default on a system
installed using the Reduced Networking Software Group. The ports open in the above
example belonged to the rpcbind process (ports TCP/111, UDP/111, and UDP/32772)
and the syslogd process (UDP/514). If you did not want these services
running, you can disable them with the following commands:
# svcadm disable network/rpc/bind
# svcadm disable system/system-log
Alternatively, you could have also configured rpcbind to use TCP Wrappers by running the following commands:
# svccfg
svc:> select network/rpc/bind
svc:/network/rpc/bind> setprop config/enable_tcpwrappers = true
svc:/network/rpc/bind> quit
# svcadm restart network/rpc/bind:default
Certainly, you would then need to configure your TCP Wrappers hosts.allow(4)
and hosts.deny(4) files accordingly. For syslogd, you could also have
set the LOG_FROM_REMOTE parameter in the
/etc/default/syslogd file to NO. This would have caused the syslogd
process to not listen for incoming connections from remote hosts.
But I digress...
Now, since only 150-Mbytes of software was installed, it should come as no shock
to you that there is a lot of other software that was not installed. This is why
the Reduced Networking Software Group is a foundation for minimization. You
will need to add any software packages (either manually or by defining them in
your JumpStart installation profile) that you need for applications, services,
management or support.
For example, let's look for some common programs and services to see what happens:
# echo $PATH
/usr/sbin:/usr/bin
# which telnet
no telnet in /usr/sbin /usr/bin
# which ftp
no ftp in /usr/sbin /usr/bin
# which rcp
no rcp in /usr/sbin /usr/bin
# which rsh
no rsh in /usr/sbin /usr/bin
# which ssh
no ssh in /usr/sbin /usr/bin
# which mount
/usr/sbin/mount
# mount -F nfs -o ro 10.1.1.100:/export/disk1 /mnt
mount: Operation not applicable to FSType nfs
# truss
truss: not found
# snoop
snoop: not found
As you can see, the Reduced Networking Software Group does not come with very much! It
is precisely this reason however why it will help customers wishing to build minimal
configurations. By providing a solid, core set of packages, customers are free to take
an additive approach to building minimal systems by simply adding in those packages that
they want or need. This approach is much improved from the typical method employed today
that requires users to remove unnecessary software packages - as this approach was prone
to error and often raised problems for the supportability of such configurations.
Since I believe that many people will want to have Secure Shell in their default configuration,
I did want to provide the JumpStart installation profile entries that would help. If you
would like Secure Shell (but do not care about tunnelling X11 connections), then you can use
the following profile:
install_type initial_install
cluster SUNWCrnet
cluster SUNWCssh add
package SUNWgss add
partitioning explicit
filesys rootdisk.s1 768 swap
filesys rootdisk.s0 free /
system_type standalone
Well, that's all for now. Check back soon for another installment of lesser known and/or
publicized security enhancements to the Solaris 10 OS. I still have a bunch lined up for
you! Let me know what you think of this series of articles as well as ideas for future
updates. Take care!
Technorati Tag:
OpenSolaris
Solaris
security
Friday Sep 24, 2004
This entry is a continuation of my list of lesser known and/or publicized security enhancements to the Solaris 10 OS. In this update,
I will be talking about how to restrict the output of the ps(1)
command such that users can only see processes that they own. This is a very useful capability especially for ISPs and other
organizations that do not want to allow users to see what other users are doing.
This new feature would not have been possible without the introduction of process privileges into the Solaris 10 OS. For a great overview
of process privileges, see Casper Dik's blog entry
on this topic. Be sure to read his article to get a more in depth understanding of process privileges.
So, before we begin, let's see what the output of ps -aef might look like for an average user (in this case, gmb):
$ ps -aef
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 Sep 23 ? 0:07 sched
root 1 0 0 Sep 23 ? 0:01 /sbin/init
root 2 0 0 Sep 23 ? 0:00 pageout
root 3 0 0 Sep 23 ? 2:31 fsflush
root 393 1 0 Sep 23 ? 0:00 /usr/sbin/auditd
root 7 1 0 Sep 23 ? 0:11 /lib/svc/bin/svc.startd
root 9 1 0 Sep 23 ? 0:19 svc.configd
root 176 1 0 Sep 23 ? 0:00 /usr/sbin/syslogd
root 64 1 0 Sep 23 ? 0:00 /usr/sbin/nscd
daemon 91 1 0 Sep 23 ? 0:02 kcfd
root 170 1 0 Sep 23 ? 0:01 /usr/lib/utmpd
gmb 1795 1792 0 22:17:26 pts/1 0:00 -sh
root 1527 7 0 00:53:24 console 0:00 /usr/bin/login
root 82 1 0 Sep 23 ? 0:00 /usr/lib/sysevent/syseventd
smmsp 334 1 0 Sep 23 ? 0:00 /usr/lib/sendmail -Ac -q15m
daemon 137 1 0 Sep 23 ? 0:06 /usr/sbin/rpcbind
root 84 1 0 Sep 23 ? 0:00 /usr/lib/picl/picld
root 1601 1527 0 07:36:19 console 0:00 -sh
root 181 1 0 Sep 23 ? 0:04 /usr/lib/inet/inetd start
root 281 1 0 Sep 23 ? 0:00 /usr/lib/nfs/mountd
root 187 1 0 Sep 23 ? 0:00 /usr/sbin/cron
root 1402 1 0 00:26:14 ? 0:00 /usr/lib/ssh/sshd
daemon 289 1 0 Sep 23 ? 0:00 /usr/lib/nfs/nfsd
daemon 264 1 0 Sep 23 ? 0:00 /usr/lib/nfs/statd
root 303 1 0 Sep 23 ? 0:00 /usr/lib/fm/fmd/fmd
daemon 268 1 0 Sep 23 ? 0:00 /usr/lib/nfs/lockd
root 291 1 0 Sep 23 ? 0:00 /usr/lib/autofs/automountd
gmb 1799 1795 0 22:17:28 pts/1 0:00 ps -aef
root 1789 181 1 22:17:19 ? 0:00 /usr/sbin/in.telnetd
root 1792 1789 1 22:17:19 pts/1 0:00 login -p -h 10.1.1.100 -d /dev/pts/1
root 335 1 0 Sep 23 ? 0:06 /usr/lib/sendmail -bd -q15m
daemon 296 1 0 Sep 23 ? 0:00 /usr/lib/nfs/nfsmapid
As you can see, the gmb user can see not only his processes but also those of the
root, daemon, and smmsp accounts. We can change this behavior either
globally or on a per-user basis. Just as we discussed in the Solaris
10 Account Lockout entry, we can use user-specific changes to force a subset of users
to comply with some policy or use the user-specific changes to make exceptions for those
users. The flexibility of this format allows it to be adapted quite easily to the needs
of many organizations.
For our first example, we will illustrate how the global change can be made. So do this,
we must edit the
/etc/security/policy.conf file, uncomment the PRIV_DEFAULT entry and set its value
as follows:
PRIV_DEFAULT=basic,!proc_info
For those not familiar with the proc_info privilege, you can find more information
about it using the ppriv(1)
command:
# ppriv -l -v proc_info
proc_info
Allows a process to examine the status of processes other
than those it can send signals to. Processes which cannot
be examined cannot be seen in /proc and appear not to exist.
This is all that you need to do to globally configure your Solaris 10 system so that users
will only be able to see processes that they own. Note that this will obviously not
apply to root who by default has all privileges or to other users or processes that
have been explicitly given the proc_info privilege. Regardless, it is still a very
quick and effective way to limit what processes users may see.
Returning to the gmb account example, I re-login to the system and again
run the ps -aef command, but this time I receive different results:
$ ssh -l gmb sampleHost
gmb@sampleHost's password:
Last login: Fri Sep 24 22:25:18 2004 from 10.1.1.100
Sun Microsystems Inc. SunOS 5.10 s10_67 May 2004
$ ps -aef
UID PID PPID C STIME TTY TIME CMD
gmb 1823 1819 0 22:30:17 pts/1 0:00 ps -aef
gmb 1819 1815 0 22:30:14 pts/1 0:00 -sh
$
As you can see, the gmb user may now only see his own processes. Way cool.
Next, to illustrate the per-user configuration ability, I will leave this global
configuration in place and use the per-user configuration ability to allow the
gmb user to view processes owned by other users. This is just an example
of how exceptions can be implemented. The same process could be used to enable
this feature for just a user or subset of users on the system.
To accomplish this task, we go back to the
user_attr(4) file. In this file, we will modify the existing entry for the
gmb user (or create one if one had not already been there). The following
example illustrates the change that needs to be made. Specifically you need to
add the defaultpriv entry to specify the default list of privileges that
will be available to this user. By modifying this parameter, you
will change the default set of privileges available to a user (by either adding
or removing privileges as needed.) In this case, we are returning the user's
default set of privileges to basic from basic,!proc_info.
gmb::::lock_after_retries=no;defaultpriv=basic
So, let's see if this really works. In the following example, we will confirm
the configuration of the system, login to the system as the
gmb user, and run the ps -aef command to verify that the gmb user can
see processes owned by other users.
# grep "^PRIV_DEFAULT=" /etc/security/policy.conf
PRIV_DEFAULT=basic,!proc_info
# grep "^gmb:" /etc/user_attr
gmb::::lock_after_retries=no;defaultpriv=basic
# ssh -l gmb localhost
Password:
Last login: Fri Sep 24 22:37:55 2004 from 10.1.1.100
Sun Microsystems Inc. SunOS 5.10 s10_67 May 2004
$ id -a
uid=100(gmb) gid=1(other) groups=1(other)
$ ps -aef
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 Sep 23 ? 0:07 sched
root 1 0 0 Sep 23 ? 0:01 /sbin/init
root 2 0 0 Sep 23 ? 0:00 pageout
root 3 0 0 Sep 23 ? 2:33 fsflush
root 393 1 0 Sep 23 ? 0:00 /usr/sbin/auditd
root 7 1 0 Sep 23 ? 0:11 /lib/svc/bin/svc.startd
root 9 1 0 Sep 23 ? 0:19 svc.configd
root 176 1 0 Sep 23 ? 0:00 /usr/sbin/syslogd
root 64 1 0 Sep 23 ? 0:00 /usr/sbin/nscd
daemon 91 1 0 Sep 23 ? 0:02 kcfd
root 170 1 0 Sep 23 ? 0:01 /usr/lib/utmpd
root 1900 1402 7 22:42:05 ? 0:02 /usr/lib/ssh/sshd
root 1527 7 0 00:53:24 console 0:00 /usr/bin/login
root 82 1 0 Sep 23 ? 0:00 /usr/lib/sysevent/syseventd
smmsp 334 1 0 Sep 23 ? 0:00 /usr/lib/sendmail -Ac -q15m
daemon 137 1 0 Sep 23 ? 0:06 /usr/sbin/rpcbind
root 84 1 0 Sep 23 ? 0:00 /usr/lib/picl/picld
root 1601 1527 0 07:36:19 console 0:00 -sh
root 181 1 0 Sep 23 ? 0:04 /usr/lib/inet/inetd start
root 281 1 0 Sep 23 ? 0:00 /usr/lib/nfs/mountd
root 187 1 0 Sep 23 ? 0:00 /usr/sbin/cron
root 1402 1 0 00:26:14 ? 0:00 /usr/lib/ssh/sshd
daemon 289 1 0 Sep 23 ? 0:00 /usr/lib/nfs/nfsd
daemon 264 1 0 Sep 23 ? 0:00 /usr/lib/nfs/statd
root 303 1 0 Sep 23 ? 0:00 /usr/lib/fm/fmd/fmd
daemon 268 1 0 Sep 23 ? 0:00 /usr/lib/nfs/lockd
root 291 1 0 Sep 23 ? 0:00 /usr/lib/autofs/automountd
gmb 1912 1908 0 22:42:12 pts/1 0:00 ps -aef
root 335 1 0 Sep 23 ? 0:06 /usr/lib/sendmail -bd -q15m
daemon 296 1 0 Sep 23 ? 0:00 /usr/lib/nfs/nfsmapid
gmb 1908 1900 0 22:42:10 pts/1 0:00 -sh
root 1899 1601 6 22:42:05 console 0:02 ssh -l gmb localhost
It worked! That was pretty easy, right? This is just one very small example of how you can
use process privileges in your daily lives. I will try to add more interesting examples of
practical uses for process privileges in the future.
Before ending, I do want to highlight
that while these examples focused on the ps(1) command - other process related commands
will also be impacted such as ptree(1), pcred(1), pmap(1), psig(1),
etc. Further, as a user running without the proc_info privilege, you will not even be
able to see other processes in the /proc directory:
$ id -a
uid=101(foo) gid=1(other) groups=1(other)
$ ppriv $$
1915: -sh
flags =
E: basic,!proc_info
I: basic,!proc_info
P: basic,!proc_info
L: all
$ ls -l /proc
total 4
dr-x--x--x 5 foo other 832 Sep 24 22:52 1915
dr-x--x--x 5 foo other 832 Sep 24 22:56 1932
I hope you enjoyed this
article and please watch this space for new discussion of Solaris 10 security features.
Take care and have a great weekend.
Technorati Tag:
OpenSolaris
Solaris
security
Thursday Sep 23, 2004
The next item of my list of lesser known and/or publicized security
enhancements to the Solaris 10 OS is account lockout. Account lockout
is the ability of a system or service to administratively lock an
account after that account has suffered "n" consecutive failed
authentication attempts. Very often "n" is three hence the "three
strikes" reference.
Recall from yesterday's entry on
non-login and locked accounts that there is in fact a difference.
Locked accounts are not able to access any system services whether
interactively or through the use of delayed execution mechanisms such
as cron(1M). So, when an account is locked out using this capability,
only a system administrator is able to re-enable the account, using
the passwd(1) command with the "-u" option.
Account lockout can be enabled in one of two ways. The first way will
enable account lockout globally for all users. The second method will
all more granular control of which users will or will not be subject
to account lockout policy. Note that the account lockout capability
will only apply to accounts local to the system. We will look
at both in a little more detail below.
Before we look at how to enable or disable the account lockout policy,
let's first take a look at how you configure the number of consecutive,
failed authentication attempts that will serve as your line in the sand.
Any number of consecutive, failed attempts beyond the number selected
will result in the account being locked. This number is based on the
RETRIES parameter in the /etc/default/login file. By default,
this parameter is set to 5. You can certainly customize this
parameter based on your local needs and policy. By default, the
Solaris Security Toolkit
will set the RETRIES parameter to 3.
Now that we know how to define how many consecutive, unsuccessful
authentication attempts we will allow, let's take a look at how you
can enable the account lockout policy globally. This policy can be
altered using the LOCK_AFTER_RETRIES variable in the
/etc/security/policy.conf file. Just as it sounds, if you set this
parameter to YES, then the account lockout policy is enabled
for all users on the system (unless there is a user override which
we will talk about in a minute). By default, this parameter is set
to NO which means that account lockout is not enabled.
So, let's try a simple example. First, I created a test account
called gmb. Next, I set the LOCK_AFTER_RETRIES parameter
in /etc/security/policy.conf to YES. To see, how this feature
works, I attempted to authenticate to a system (and failed) using three
different services:(1) TELNET, (2) FTP and (3) RLOGIN. I failed the
login attempt for each of these services (in turn) twice with the
exception of RLOGIN since after the fifth failed attempt the account
was locked. I ran this test from the system's console so that the
log messages could be injected into the output stream to give you
a better idea of what was happening. Here is the actual log of the
test that was run:
# telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
login: gmb
Password:
Login incorrect
login: gmb
Password:
Login incorrect
login:
Connection to localhost closed by foreign host.
# ftp localhost
Connected to localhost.
220 sampleHost FTP server ready.
Name (localhost:root): gmb
331 Password required for gmb.
Password:
530 Login incorrect.
Login failed.
ftp> user gmb
331 Password required for gmb.
Password:
530 Login incorrect.
Login failed.
ftp> quit 221 Goodbye.
# rlogin -l gmb localhost Password:
Sep 23 23:23:47 sampleHost login: Excessive (5) login failures for gmb: locking account. Login incorrect
login:
As you can see, after the fifth attempt, the gmb account was locked. This
can also be verified by looking at the shadow(4) file entry for that account:
# grep "^gmb:" /etc/shadow
gmb:*LK*R12OfCMPngtJQ:12685::::::5
You can see that the account has been locked and that a record of the number of
failures is available in the last column. From the
shadow(4) manual page, the last field (called "flag") stores the failed login count in the low order four
bits while reserving the remainder for future use. This means that you can also
look at individual shadow(4) entries and see how many consecutive failed
authentication attempts have been made per user. For example, you could do
the following to see how many users have had failed authentication attempts
since their last successful login:
# awk -F: '$NF >= 1 { print; }' /etc/shadow
gmb:*LK*R12OfCMPngtJQ:12685::::::5
foo:02YZb5ZaMrcrk:12685::::::2
bar:XF0Ggjq1c6tYQ:12685::::::1
baz:.VxOG4ytNE8es:12685::::::3
If a user who has had failed authentication attempts is finally able to
successfully login to the system, that user will be presented with a
message like:
# telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
login: baz
Password:
Warning: 3 failed login attempts since last successful login.
Last login: Thu Sep 23 23:36:44 from localhost
This warning message is available for interactive login services (not
FTP) and is very helpful in providing warning to users who may
not have been responsible for the failed authentication attempts.
It is important that you educate your users to not simply ignore
these messages as they could be a symptom of an ongoing attack
on their account.
Also, note that once a user has successfully authenticated to a
system, the failed login count is reset:
# grep "^baz" /etc/shadow
baz:.VxOG4ytNE8es:12685::::::
Note that the use of alternate authentication mechanisms such as
rhosts or Secure Shell public key authentication will not reset
the failed login count even on successful login. Should an account
be locked however (either administratively or through the account
lockout facility), the account would no longer be accessible even
when using these alternate authentication methods. For example:
# grep gmb /etc/shadow
gmb:*LK*R12OfCMPngtJQ:12685::::::
# rsh -l gmb localhost /bin/finger
account expired
or for Secure Shell...
# ssh -l gmb -i /export/home/gmb/.ssh/id_dsa localhost
Enter passphrase for key '/export/home/gmb/.ssh/id_dsa':
Sep 24 00:34:59 sampleHost sshd[1504]: Failed publickey for gmb from 127.0.0.1 port 32801 ssh2
Password:
The second way in which account lockout can be configured is per-user
in the /etc/user_attr file. Each user listed in the /etc/user_attr
file can have an attribute defined called lock_after_retries.
For a description of the format of this file, see the
user_attr(4) manual page. By default, this value is set to no.
To configure account lockout for a specific user, simply add the
lock_after_retries attribute with a value of yes. For
example, let's assume you have an entry for user gmb:
gmb::::type=normal;profiles=FOO Security Management;roles=secadm
To enable account lockout, you simple change the above line to:
gmb::::type=normal;profiles=FOO Security Management;roles=secadm;lock_after_retries=yes
Let's take another view on this. Let's assume that the account lockout
policy has been enabled globally using the method described above. You
can then configure some users to be immune to this policy using this
user-specific override. For example, if the LOCK_AFTER_RETRIES
parameter was set to YES in /etc/security/policy.conf, but you
did not want the policy to apply to the gmb account, then you
only need to make sure that the /etc/user_attr file contains an entry
for the gmb account that sets the lock_after_retries
attribute to no as in:
gmb::::lock_after_retries=no
Here is an example of how this works. I will attempt to access the gmb
account with an invalid password five times using TELNET. In contrast
to the above example, the account should not be locked and no account
locked message should be generated. First, let's confirm we have our
system configured correctly for this test:
# grep "^gmb:" /etc/shadow
gmb:h8HsRoqrne1oQ:12685::::::::::
# grep "^gmb:" /etc/user_attr
gmb::::lock_after_retries=no
# grep "^LOCK_AFTER_RETRIES=" /etc/security/policy.conf
LOCK_AFTER_RETRIES=YES
Now, let's see if the account actually gets locked after 5 failed
authentication attempts.
# telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
login: gmb
Password:
Login incorrect
login: gmb
Password:
Login incorrect
login: gmb
Password:
Login incorrect
login: gmb
Password:
Login incorrect
login: gmb
Password:
Login incorrect
Sep 23 23:51:46 sampleHost login: REPEATED LOGIN FAILURES ON /dev/pts/1 FROM localhost, gmb
Connection to localhost closed by foreign host.
# grep "^gmb:" /etc/shadow
gmb:h8HsRoqrne1oQ:12685::::::
Just as expected, the gmb account is immune from the account lockout
policy that applies to other users on the system. This is in fact what is
implemented by default for the root account. That is, even if account
lockout is enabled globally (which is not the default), the root account is
still immune from being locked out. This is done to prevent a malicious user
from locking the root account out of the system. If you would like
this policy to apply to the root account, then simply change the value
of the lock_after_retries parameter to yes in the /etc/user_attr
file.
This concludes another installment. As always, I hope you find this information
useful in understanding how some of the new Solaris 10 security enhancements
work and how they can be applied to solve real-world problems in your environment.
Technorati Tag:
OpenSolaris
Solaris
security
Tuesday Sep 21, 2004
Today's entry will focus on enhancements to the passwd(1) command
to better support the distinction between locked and non-login
accounts. Specifically, we will be looking at the new -u and
-N options to the passwd(1) command as well as how they relate
to the much older -l option. These new capabilities will help
administrators obtain better control over how their accounts are
accessed and how they can in fact manage those accounts. In the past,
some of the interfaces discussed below could only be achieved through
manual editing of password files. The addition of these new command
line options provides a much safer option for administrators to use.
While the distinction between non-login and locked accounts has existed
in Solaris for many years, it became more pronounced in Solaris 9 where
the semantics of locked accounts were more rigidly enforced.
Many customers noticed, for example, that locked accounts could no longer
execute jobs using cron(1M). This problem was exacerbated by the fact
that many commonly referenced security recommendation guides tell users
to lock all of the accounts to which interactive access was not needed
(which is most of the default accounts). When this was done, cron jobs
for accounts such as "sys" (used for collecting system activity records)
stopped working. This problem highlighted the intended difference between
non-login and locked accounts and the need for additional interfaces
to control them.
For those not already aware, a non-login account is one that must
exist on the system (to provide a UID for example) but should not
be allowed to login to a system interactively. That is, while
a non-login account may be able to leverage delayed execution
mechanism such as cron(1M), they cannot access the system using
login(1), telnet(1) ftp(1), ssh(1), etc. Accounts that are
non-login will have the token NP as their password. You can
also identify non-login accounts using the passwd(1) command:
# passwd -s daemon
daemon NL
# grep "^daemon:" /etc/shadow
daemon:NP:6445::::::
In this case, the daemon account has been configured as
a non-login account.
A locked account on the other hand is one that is not permitted
to access the system in any way - it is locked. A locked account
differs from one marked as non-login in that locked accounts
are not permitted to use delayed execution methods like cron(1M).
Locked accounts are those whose password string has the prefix
*LK*. Further, you can identify locked accounts using the
passwd(1) command:
# passwd -s listen
listen LK
# grep "^listen:" /etc/shadow
listen:*LK*:::::::
In this case, the listen account has been locked.
Here is a practical example. In this case, I will add a new
account gmb to the system. By default, new accounts
created using useradd(1M) are locked. After assigning a new
password, I will demonstrate the use and result of the new
-N and -u options to the passwd(1) command in
addition to the -l option which has been around for ever.
First, let's create a test account called gmb. You
will notice that by default the account will be locked.
# useradd -d /export/home/gmb gmb
# passwd -s gmb
gmb LK
Next, a password will be assigned to the gmb account
in the usual way using the passwd(1) command...
# passwd gmb
New Password:
Re-enter new Password:
passwd: password successfully changed for gmb
# passwd -s gmb
gmb PS
# grep "^gmb:" /etc/shadow
gmb:Onk28eSYhYJ8s:12683::::::
You will notice that the "passwd -s" command now returns the
keyword PS for "password set". If the account did not have
a password defined, the keyword NP (for "no password") would
have been returned.
Now that we have a password, let's lock the account and see
what happens to the password string in /etc/shadow as well as
to the output of "passwd -s":
# passwd -l gmb
passwd: password information changed for gmb
# passwd -s gmb
gmb LK
# grep "^gmb:" /etc/shadow
gmb:*LK*Onk28eSYhYJ8s:12683::::::
You will notice that the account was in fact locked, but what
is new in Solaris 10 is that the password string is not replaced
with the "*LK*" value. Instead, a "*LK*" string prefix is prepended
to the password so that the original value can be kept if desired.
The great thing about this is that it does not depend on the password
algorithm used. With the addition of flexible crypt in Solaris 9,
you can replace the default crypt algorithm with either others
provided by default in Solaris or one of your own and this new
locking mechanism will still just work.
To unlock a locked account, you just use the new "-u" option to
the passwd(1) command:
# passwd -u gmb
passwd: password information changed for gmb
# passwd -s gmb
gmb PS
# grep "^gmb:" /etc/shadow
gmb:Onk28eSYhYJ8s:12683::::::
The account is now unlocked and the "*LK*" prefix has been removed
from the user's password string. The last thing that we will look
at today is how you create a non-login account. To do this, simply
use the "-N" option to the password command:
# passwd -N gmb
passwd: password information changed for gmb
# passwd -s gmb
gmb NL
# grep "^gmb:" /etc/shadow
gmb:NP:12683::::::
You will notice that the user's original password has been removed
and replaced with the string "NP". This account is now a non-login
account and the original password has been discarded. You will not
be able to login to this account, but the account will be able to
make use of delayed execution facilities. To re-enable an account
for interactive logins, simply reassign a password to the account
using the passwd(1) command.
That's all for this installment. I hope you find this kind of
information useful. In future installments, I will continue to
highlight some of the lesser known enhancements that contribute to
Solaris security in the hopes of raising awareness and their use.
Technorati Tag:
OpenSolaris
Solaris
security
Tuesday Sep 21, 2004
It has been a while since my last update. It has certainly not
been for lack of interest, however. Over the next few entries,
I would like to talk about some of the lesser noted security
enhancements that will be available in Solaris 10. Many of
these enhancements are certainly minor when compared to
N1 Grid
Containers (zones),
Service Management Facility (smf), and process privileges, but these enhancements
nonetheless will help Solaris system and security administrators
in their daily jobs - managing their systems and complying
with their security policies.
Kenneth,
Thank you so much for you...
Kevin,
Thank you very much for y...
I discovered this blog from "the clingan zone" blo...
Luis,
Thank you very much for yo...