비밀번호 정책은 어떤 계정이 비밀번호 인증 프로세스에 의해 보호되는지 확인하고 이를 강제 실행하는 메커니즘이다. 비밀번호 정책의 규칙을 적용하는 시스템 관리자는 사용되는 비밀번호를 외부인이 쉽게 결정하지 못하게 해야 한다. 비밀번호 정책은 모든 활성 사용자 계정에 적용되어야 한다.
비밀번호 정책의 한 부분은 검토를 위해 비밀번호 만료와 제한을 조사하는 것이다. 이를 통해 시스템 관리자는 사용자를 위해 자체적인 비밀번호 정책에 불일치 사항이 있는지 확인하여 필요하다면 이를 수정할 수 있다. 일반적으로, 이런 불일치 사항은 임시적 방법으로 고정되지만 모든 사용자에 대한 보고를 통해 수정하는 것이 최선의 방편이다. 대개의 경우 비밀번호를 마지막으로 변경한 시점, 비밀번호의 만료 시점 및 각 사용자에 대해 설정된 비밀번호 플래그와 같은 사항을 고려한다. 비밀번호 정책은 일반적으로 감사 보고 요구사항이다.
본 기사는 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' 메시지로 플래그 지정된다. 이 형식에서는 어떤 시스템 기본값이 구현되었는지 훨씬 쉽게 알 수 있다. 이 스크립트는 각 원격 호스트에서 실행할 수 있고, 시스템 기본값들을 서로 비교하여 호스트 간에 불일치 사항이 있는지 확인할 수 있다. 시스템 기본값의 사용자 대체를 살펴보면 사용자 세트에 대한 속성이 구현된 보안 정책에 따라 유효한지 결정할 수 있다.
#!/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 -f <FLAGS> <user> |
여기서 플래그는 다음과 같다.
NOCHECK
: 사용자가 비밀번호 설정 시 비밀번호 정책을 따를 필요가 없다. 이는 비밀번호 길이나 반복 문자에 아무런 제한이 없다는 뜻이다.ADMIN
: 루트 사용자만이 비밀번호 정보를 변경할 수 있음을 나타낸다.ADMCHG
: 이 플래그가 설정되어 있는 경우, 사용자가 다음에 로그인할 때 비밀번호를 변경하라는 메시지가 표시된다. 이는 모든maxage
설정을 대체한다.
pwdadm -c <user> |
위 예제와 같이 하면 이전에 설정된 모든 pwdadm
플래그가 지워진다.
pwdadm -q <user> |
위 예제에서는 pwdadm
플래그를 쿼리하고 설정된 플래그와 비밀번호가 마지막으로 변경된 시간을 모두 다시 보고한다(비밀번호가 설정된 경우).
pwdadm
사용 예제가 표시된다. 우선, pwdadm
을 쿼리하여 어떤 플래그가 설정되어 있는지 확인한다. 이 예제에서는 사용자 알파가 쿼리된다.
# pwdadm -q alpha alpha: lastupdate = 1267374936 |
이 출력 결과를 보면 사용자 알파에 lastupdate
항목에 의해 설정된 비밀번호가 있음을 알 수 있다. 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
를 3주로 변경하려면 다음과 같이 할 수 있다.
# 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
에서 허용하는 기간을 넘어 이전 비밀번호로 로그인하려는 사용자의 계정은 잠기게 된다. 이때는 지원 데스크에 연락하여 계정 잠금 해제를 요청한 후 비밀번호를 변경할 수 있다. 이런 일을 미연에 방지하려면 비밀번호 만기가 다가오는 시점을 결정하여 사용자에게 경고 이메일을 보낸다. 이렇게 이메일을 보내면 사용자가 로그인한 후 화면에 메시지가 표시될 때보다 더 주의를 기울일 가능성이 크기 때문이다. 로컬 인증의 경우, pwdadm
및 lsuser
명령을 사용하여 다음 비밀번호 변경 시점 또는 그 사용자의 비밀번호 만기를 확인하는 속성이 있다.
이 기사의 앞부분에서 설명한 바와 같이, 비밀번호 만기는 maxage 속성의 지배를 받는다. 예:
maxage=0
은 만기기 없다는 뜻이고,
maxage=2
는 2주가 지나면 만료된다는 뜻이다.
AIX(UNIX? 및 Linux?)는 에포크 형식의 시간을 초 단위로 저장하므로, 우선 1주일이 몇 초인지 확인해야 하며, 이것은 maxage
가 비밀번호 만기 사이의 시간이 주 수로 측정되는 방법을 나타낸 것이다.
하루는 86,400초이므로, 여기에 7을 곱하면 604,800초가 된다. 따라서 1주일은 604,800초이다.
다음으로 살펴봐야 할 명령은 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임을 알 수 있다.
다음으로, 1주일에 해당하는 초 수에 사용자 spoll의 비밀번호가 만료되기까지의 주 수를 곱한다. 이 경우에는 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 |
위 계산에 따라 다음 비밀번호 만기 시점을 알 수 있다.
현재 (pwdadm
명령에서) 사용자 spoll의 비밀번호가 마지막으로 변경된 시점을 알고 있다.
# 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: 다음으로 만료되는 비밀번호 변경 날짜
# 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 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는 다음 비밀번호 변경을 위한 항목이 없다. 이는 해당 계정에 대한
maxage=0
으로 인한 것이다(비밀번호가 만료되지 않음). - pwdadm NOCHECK 플래그에 의해 표시되는 것처럼, 사용자 kilo는 비밀번호 규칙을 준수하도록 강제되지 않는다.
- 사용자 foxtrot의 계정에 대해
pwdadm
ADMCHG 플래그가 설정되었다. 이는 foxtrot가 다음에 로그인할 때 자신의 비밀번호를 강제로 변경하게 될 것이라는 의미다.
rlogin, login, su
값과 같은 다른 사용자 속성을 포함하도록 이 스크립트를 손쉽게 수정할 수 있다.
!/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
에서 최적의 상태로 실행되어 시스템 관리자에게 보낼 보고서를 채운 다음 생성한다.
http://www.ibm.com/developerworks/kr/aix/library/au-password_expiry/index.html