毫无疑问,密码策略是需要审计的。如果接受审计,系统管理员需要用专门的报告和清单证明自己的策略是合适的。

David Tansley, 系统管理员, Ace Europe

//ibm.com/developerworks/i/p-dtansley.jpgDavid Tansley 是一位自由作家。他有 15 年 UNIX 系统管理经验,最近 8 年使用 AIX。他喜欢打羽毛球和观赏一级方程式赛车,但是最喜欢与妻子一起开着 GSA 摩托车旅行。


developerWorks 投稿作者

2010 年 11 月 18 日

简介

密码策略是确保通过密码身份验证过程保护账户的机制。系统管理员负责应用密码策略的规则,他们应该确保使用的密码不会被外人轻易地推测出来。应该在所有活跃的用户账户上设置密码策略。

密码策略的组成部分之一是检查密码到期日期和访问限制。这让系统管理员可以检查用户的密码策略中是否有不一致的地方,并采取相应措施。一般来说,通常以特别的方式检查密码策略,但是最好的方法是生成所有用户的报告。通常,要考虑的因素包括每个用户最后一次修改密码的时间、密码应该到期的时间和密码标志。密码策略是常见的审计报告需求。

本文并不讨论如何保护 AIX 或如何实现安全策略,而是讨论与密码策略相关的应该注意的属性。


密码策略概述

密码策略用来确保用户访问的系统的安全性。从本质上说,这意味着密码不是容易猜测出的,应该经常修改。当用户设置自己的密码时,会对他们施加某些规则;这些规则应该应用于所有用户,但是应用程序的所有者例外。我们来看一个基本的密码策略,它限制密码的组成。在 /etc/security/user 文件中可以找到用户账户属性,比如系统默认的或用户特有的属性。

我建议健全的密码策略至少应该包含以下规则:

在登录时,用户可以三次尝试输入正确的密码,如果到了这个次数,就锁定账户。

loginretries	3

从最后一次修改密码开始,要过多久(周数)用户才能再次修改密码?

minage 1

过多久(周数)之后用户必须修改密码?

maxage  5

在密码到期之前,应该提前几天通知用户(到期之前每天都通知)?

pwdwarntime 5

在超过 maxage 之后用户可以在几周内修改密码?在这里,-1 表示当到达 maxage 时用户必须马上修改密码。

maxexpired -1

密码中使用的最小字母字符数量。

minalpha 1

密码中使用的最小非字母字符数量。

minother 1

密码中的最小字符数量。

minlen  8

由于在前一个密码中存在而不能在新密码中使用的最小字符数量。

mindiff 2

在新密码中不能重复的字符数量。

maxrepeats 2

要经过几周才能重用以前的密码?

histexpire 26

应用程序所有者账户应该是密码策略规则的惟一例外。尤其是,他们的密码可以设置为永远不到期,还可以增加锁定账户之前尝试输入密码的次数。原因很简单:如果生产环境中的应用程序或接口被锁定了,就会影响业务。应该手工管理这些账户的属性。通常可以修改以下属性:

maxage=0
loginretries=10

应该安排修改密码的时间表,在应用程序关闭时修改密码。

如果需要以更清楚的格式向安全经理报告信息,实现密码策略会非常费时间,尤其是在处理大型企业网络时。清单 1 中的 user_defaults 脚本以可读性更好的格式提供这些信息。首先,它提取系统默认设置,然后列出 /etc/security/user 中包含的具有非系统默认属性设置的每个账户。如果属性没有系统默认值,就显示消息 '**No Defaults Set'。按照这种格式,很容易看出哪些属性有系统默认值。可以在每个远程主机上运行此脚本,然后通过对比系统默认值检查主机之间是否有差异。通过查看用户账户覆盖系统默认设置的情况,就可以判断用户的属性集对于实现的安全策略是否合法有效。

清单 1. user_defaults
#!/bin/sh
# user_defaults

get_defaults()
{
# get listing of defaults entry in /etc/security/user and present

grep -p -w "default:"
 /etc/security/user| grep -v "*"|grep -v "default:"|grep -v "\"" >/tmp/defaults.tmp
# the sed '/ //g , is a <CTRL-V> then hit the tab key
sed '/^$/d;s/ //g' /tmp/defaults.tmp >/tmp/hold.tmp && \
mv /tmp/hold.tmp /tmp/defaults.tmp

IFS="="
echo "Default Attributes of /etc/security/user"
echo "Key Value
==========================="
cat /tmp/dt | while read key value
 do
 if [ "$value" = "" ] || [ "$value" = " " ]
 then
 value=" **No Default Set"
 fi
printf "%-15s %-15s\n" "$key" "$value"
done
}

get_users()
# get list of attributes that override the defaults and present
{
echo "\nUser Defined Attributes
-----------------------------"
> users.tmp
list=""
# the sed '/ /g , is a <CTRL-V> then hit the tab key
list=$(grep ":" /etc/security/user | grep -v default| grep -v "*" |sed 's/\:/ /g')
for users in $list
 do
 echo "[$users]"
 grep -p -w "$users:"
 /etc/security/user|grep -v "*"|sed '/^$/d;s/ / /g'|sed '1d'>users.tmp
 cat users.tmp | while read line 
 do
 
 key=$( echo $line | awk -F= '{print $1}')
 value=$(echo $line |awk -F= '{print $2}')
 
 printf "%-15s %-15s\n" "$key" "$value"
 done
echo "-----------------------"
done
}

savedIFS="$IFS"
get_defaults
IFS="$savedIFS"
get_users

user_defaults 脚本的典型输出像下面这样:

清单 2. user_defaults 脚本的典型输出
Default Attributes of /etc/security/user
Key              Value
===========================
admin            false
login            true
su               true
daemon           true
rlogin           true
sugroups         NONE
admgroups        **No Default Set
ttys             ALL
auth1            SYSTEM
auth2            NONE
tpath            nosak
umask            022
expires          0
logintimes       **No Default Set
pwdwarntime      0
account_locked   false
loginretries     3
histexpire       26
histsize         15
minage           1
maxage           5
maxexpired       -1
minalpha         1
minother         1
minlen           0
mindiff          0
maxrepeats       8
dictionlist      **No Default Set
pwdchecks        **No Default Set

User Defined Attributes
-----------------------------
[root]
admin            true
SYSTEM           "compat"
registry         files
loginretries     0
account_locked   false
sugroups         admin,sysadmin
-----------------------
[daemon]
admin            true
expires          0101000070
-----------------------      
[ukflag]
admin            false
sugroups         !fire,!cloud,earth
-----------------------
[testme]
admin            false
-----------------------
[john]
admin            false
-----------------------
[peter]
admin            false
-----------------------
[jane]
admin            false
-----------------------
[plutt]
admin            false
maxage           1
-----------------------
[spoll]
admin            false
maxage           4
-----------------------

pwdadm 标志

pwdadm 标志让系统管理员能够控制和查看用户的密码特性。尽管可以用这个命令完成其他任务,但这是它的主要用途。基本格式是:

pwdadm -f <FLAGS> <user>

其中的标志是:

  • NOCHECK:用户在设置密码时不需要遵守密码策略。这意味着不限制密码长度或重复字符。
  • ADMIN:表示只有根用户才能修改密码信息。
  • ADMCHG:如果设置了这个标志,那么当用户下一次登录时,会提示用户修改密码。这优先于任何 maxage 设置。
pwdadm -c <user>

上面的示例清除以前设置的所有 pwdadm 标志。

pwdadm -q <user>

上面的示例查询 pwdadm 标志,报告设置的所有标志和最后一次修改密码的时间(如果已经设置了密码的话)。

现在给出使用 pwdadm 的示例。首先,查询 pwdadm 以查看设置的标志。在这个示例中,查询用户 alpha:

# pwdadm -q alpha
alpha:
        lastupdate = 1267374936

在上面的输出中,可以通过 lastupdate 条目看出用户 alpha 已经设置了密码。如果 lastupdate 不存在,就说明没有设置过密码。

现在,我们来设置这个用户的 ADMCHK 标志:

# pwdadm -f ADMCHG alpha

通过查询 pwdadm 再次检查标志:

# pwdadm -q alpha
alpha:
        lastupdate = 1267374936
        flags = ADMCHG

现在,清除所有标志:

# pwdadm -c alpha

检查标志是否已经清除了:

# pwdadm -q alpha
alpha:
        lastupdate = 1267374936

修改用户属性

要想对密码或登录属性进行全局修改,应该编辑 /etc/security/user 文件。

在默认小节中,修改希望全局实现的属性的默认值。使用 chuser 命令修改单独的用户账户。例如,可以使用以下命令把用户 charlie 的 maxage 改为三周:

# chuser maxage=3 charlie
# lsuser -a maxage charlie
charlie maxage=3

还可以列出用户的所有属性:

# lsuser -f charlie
charlie:
        id=211
        pgrp=staff
        groups=staff
        home=/home/charlie
        shell=/usr/bin/ksh
        gecos=charlie.suppt
        login=true
	…..

密码什么时候到期

当用户登录时,如果他们的密码即将到期,就会显示警告。但是,除非用户很守纪律,他们通常会忽视这一警告,直到密码真的到期时才会修改密码。如果是这样,肯定会有一些用户多次尝试用旧密码登录,直到超过 loginretries 允许的次数,导致账户锁定。这意味着他们要联系服务人员,要求解除账户锁定,然后才能修改密码。作为预防措施,您可以判断密码到期时间并向用户发警告电子邮件。与登录之后屏幕上出现的消息相比,用户很可能更重视警告电子邮件。对于本地身份验证,使用 pwdadmlsuser 命令显示属性,判断下一次修改密码的时间或密码到期时间。

正如前面指出的,密码的到期时间由 maxage 属性控制。例如:

maxage=0 意味着永远不到期

maxage=2 意味着两周后到期

AIX(UNIX® 和 Linux®)按纪元格式存储以秒为单位的时间,所以首先必须知道一周有多少秒,因为 maxage 以周为单位确定密码到期时间。

一天有 86400 秒,乘以 7 得到 604800。所以一周有 604800 秒。

下面需要使用 pwdadm 命令,这个命令查询 /etc/security/passwd 文件。这个文件包含用户最后一次修改密码的时间(以秒为单位的值)。直接查询此文件或使用 pwdadm 命令会返回相同的结果。现在,我们来查询用户 spoll:

# grep -p "spoll:" /etc/security/passwd
spoll:
        password = EvqNjMMwJzXnc
        lastupdate = 1274003127
        flags =       ADMCHG

# pwdadm -q spoll
spoll:
        lastupdate = 1274003127
        flags = ADMCHG

在上面的输出中可以看到以秒为单位的 lastupdate 值。这就是最后一次修改密码的时间:

1274003127

接下来,使用 lsuser 或直接查询 /etc/security/user 文件,查明用户 spoll 的密码到期之前的周数:

# grep -p "spoll:" /etc/security/user
spoll:
        admin = false
        maxage = 4

# lsuser -a maxage spoll
spoll maxage=4

在上面的输出中可以看到密码到期之前的周数是 4。

下一步是把密码到期前的周数(在这里是 4)乘以每周的秒数:

604800 * 4 
# expr 604800 \* 4
2419200

接下来,需要把以秒为单位的 maxage 值 (604800 * 4) 与最后一次修改密码的时间相加:

2419200 +   1274003127
# expr 2419200 + 1274003127
1276422327

现在,可以把时间由 UNIX 纪元以来的秒数转换为更有意义的时间形式。可以使用不同的工具,本文使用 gawk 和 strftime 函数:

# gawk 'BEGIN {print strftime("%c",'1276422327')}'
Sun Jun 13 10:45:27 BST 2010

这会提供下一次密码到期的时间。

现在知道了用户 spoll 最后一次修改密码的时间(来自 pwdadm 命令):

# gawk 'BEGIN {print strftime("%c",'1274003127')}'
Sun May 16 10:45:27 BST 2010

和到期时间:

Sun Jun 13 10:45:27 BST 2010

现在可以判断密码什么时候到期。可以方便地循环遍历所有用户并生成报告。生成报告(尤其是在接受审计时)可以避免逐一提取信息的繁琐任务,节省大量时间。生成报告之后,可以通过打印或电子邮件把报告提交给安全管理员审查。根据我的经验,审计员愿意看到包含所需的所有属性的报告,而不是专门的屏幕图。报告还可以提醒系统管理员确保在所有服务器上以标准方式实现密码策略。可以通过查看报告发现不同用户的密码策略之间不一致的地方。

在理想情况下,报告至少应该包含每个用户的以下密码属性:

  • maxage
  • pwdadm 标志集
  • 最后一次修改密码的日期
  • 下一次修改密码的日期

清单 4 中的脚本会生成这样的登录密码属性报告。执行这个脚本时,会生成用户的密码属性报告。在我的系统上产生的输出见 清单 3。仔细看一下清单 3,它包含 5 列:

  • User:实际用户
  • Change weeks:下一次应该修改密码之前的周数(maxage 值)
  • Last change password:最后一次修改密码的日期
  • Flags:pwdadm 标志集
  • Next change password:下一次应该修改密码的日期
清单 3. next_pwch 命令
# next_pwch1
user  change           last change            flags         next change
       weeks           password                             password
root     0  Sun Feb 21 09:44:59 GMT 2010
daemon   0  password never set
charlie  0  Sun Feb 28 16:35:36 GMT 2010
foxtrot  5  Sat Feb 20 19:25:48 GMT 2010            Sat Mar 27 19:25:48 GMT 2010
kilo     5  Mon May 17 09:38:57 BST 2010 NOCHECK    Mon Jun 21 09:38:57 BST 2010
xray     0  Sun Feb 28 16:42:20 GMT 2010
jane     0  password never set
plutt    1  Sat Apr 24 20:21:17 BST 2010           Sat May  1 20:21:17 BST 2010
spoll    4  Sun May 16 10:45:27 BST 2010           Sun Jun 13 10:45:27 BST 2010
foxtrot  5  Sat Feb 20 19:25:48 GMT 2010 ADMCHG    Sat Mar 27 19:25:48 GMT 2010

清单 3 显示我系统上的用户。我可以通过这个报告了解到以下情况:

  • 用户 daemon 和 jane 没有设置过初始密码。
  • 用户 root、charlie 和 xray 没有 next change password 条目;这是因为账户上设置了 maxage=0(密码永远不到期)。
  • pwdadm NOCHECK 标志表明,用户 kilo 不必遵守密码规则。
  • 用户 foxtrot 的账户上设置了 pwdadm ADMCHG 标志。这意味着他在下一次登录时必须修改密码。

很容易修改此脚本以包含 rlogin、login、su 等其他用户属性。

清单 4. next_pwch
!/bin/sh
# next_pwch
# display date of next passwd change

# maxage value is in number of weeks
# secs in a day is:86400 ..so
secs_in_week=604800
 
log=/home/dxtans/next_pwch.log
>$log
myhost=`hostname`
mydate=`date +"%d-%m-%y"`
 echo " Date: $mydate" >>$log
 
 echo "Local Password Expiry $myhost">>$log
list=$(lsuser -a registry ALL|grep -w files| awk '{print $1}')
  
echo "user  change           last change            flags         next change"
echo "       weeks           password                             password"
 
for user in $list
do
wks_before_ch=$(lsuser -a maxage $user | awk -F '=' '{print $2}')
 
 
 if [ "$wks_before_ch" = "" ]
  then
   # krb5 / ldap /limbo"
   expire="??"
  else
   expire=$wks_before_ch
 fi
 
last_ch_pw=$(pwdadm -q $user | grep last | awk '{print $3}')
# echo "last pw change : $last_ch_pw"
  if [ "$last_ch_pw" = "" ]
   then
    passset="password never set"
else
last_ch_pw_conv=$(gawk 'BEGIN {print strftime("%c",'$last_ch_pw')}')
 last_pw_ch=$last_ch_pw_conv
 passset=$last_pw_ch
total_secs=$(expr $secs_in_week \* $wks_before_ch)
#echo "total secs: $total_secs"
 
# weeks + last pw change
date_to_ch=`expr $total_secs + $last_ch_pw`
 
pw_flags=$(pwdadm -q $user | grep flags | awk '{print $3}')
 pw_flags=$pw_flags
 
# now convert to normal
next_pw_ch=$(gawk 'BEGIN {print strftime("%c",'$date_to_ch')}')
fi
 
#echo "..$user..$wks_before_ch..$passset"
  if [ "$wks_before_ch" = "0" ]
  then
  next_pw_ch=""
 else
  next_pw_ch=$next_pw_ch
fi
 
if [ "$passset" = "password never set" ]
 then
  #echo "..$user.."
    next_pw_ch=""
 fi
printf "%-8s %-2s %-28s %-10s%-28s\n" 
 "$user" "$expire" "$passset" "$pw_flags" "$next_pw_ch"
 
done

结束语

生成用户安全属性报告有助于判断和识别密码或安全策略中是否有不一致的地方。如果您控制许多远程主机,最好从部署服务器通过 SSH 运行本文中提供的脚本,然后把生成的报告发送给系统管理员。

参考资料

学习

  • 关于 pwdadm 命令和 /etc/security/user 文件 的更多信息。
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=588002
ArticleTitle=密码到期
publish-date=11182010