顯示具有 帳號管理 標籤的文章。 顯示所有文章
顯示具有 帳號管理 標籤的文章。 顯示所有文章

2010年12月13日

[Shell Script] 批次修改使用者的密碼有效期限 - V2

之前寫過一篇[Shell Script] 批次修改使用者的密碼有效期限 - V1,當時是自己寫了一個有點囉唆的 shell script 來處理這樣的需求,最麻煩的問題是「如何判斷哪些帳號是使用者帳號」,過濾 /etc/passwd 檔案有以下困難:

  1. 在 RHEL 系統中,通常使用者帳號的 uid 是從 500 開始,但是在 Solaris 系統中是從 100 開始。
  2. 上次寫的:加強過濾 /etc/passwd 檔案時使用的 regular expression,雖然目前實務上接觸到的主機還不至於帳號多到 uid > 600 或者更高,但可以當作一個練習 regular expression 的機會。<--相當麻煩
最近又要去修改使用者密碼的到期日(每三個月就要做一次),因為不想再跑這個很麻煩的 script,因此研究出一個更方便的指令,主要是以 echo -e 搭配 xargs 來完成。

要設定「密碼有效期為90天」以及「密碼到期前30天警告」可使用以下指令:

echo -e "account1\naccount2" | xargs -i chage -M 90 -W 30 {}

echo 加上 -e 參數後會讓兩個帳號間的「\n」換行字元生效(不加 -e 的話 xargs 會收到「account1\naccount2」這個完整的字串),再搭配 xargs -i 的置換效果({}會被置換成透過 pipeline 接收的字元),上面一行指令相當於下面兩行指令:

chage -M 90 -W 30 account1
chage -M 90 -W 30 account2


這樣的寫法的彈性在於,要 echo 哪些帳號出來完全可以自由控制,不用考慮不同系統中 uid 的起始數字不同,也不用考慮例外狀況。


在我管的系統中每個 OS 中的帳號都類似(大概是5~8個),透過 xargs 可以把 5~8 行指令濃縮成一行執行,非常省事。

接下來的幾個指令就依樣畫葫蘆:

  • 檢查上述指令是否生效:echo -e "account1\naccount2" | xargs -i chage -l {}
  • 設定最後一次變更密碼的日期:echo -e "account1\naccount2" | xargs -i chage -d YYYY-MM-DD {}
  • 在 Unix 系統(e.g., Solaris)上設定密碼90天到期、到期30天前提醒:echo -e "account1\naccount2" | xargs -i passwd -x 90 -w 30 {}(Solaris預設沒有 chage 指令)

xargs 真的是非常好用,下一篇再來介紹怎樣用 find、sed 搭配 xargs 來批次修改 awstats 統計資料檔(純文字檔)的內容。

參考:[2010-03-17] [Shell Script] 批次修改使用者的密碼有效期限 - V1



2010年3月17日

[Shell Script] 批次修改使用者的密碼有效期限 - V1

最近公司在做資訊稽核,其中有一塊牽涉到主機上的帳號管理。根據公司的資安規範,每個使用者帳號 (系統內建帳號除外) 必須符合以下限制:
  1. 密碼長度不得小於6個字元
  2. 密碼有效期為90天 (也就是每90天就要變更一次密碼的意思)
  3. 不得使用三代以內的密碼
  4. 密碼不得與帳號相同
除了第四點是系統內建,不需要調整設定以外,其餘幾項都需要調整系統設定 (Solaris 只要修改系統內建的設定檔即可;針對第1和第3項要求,Linux 則必須要使用 PAM 模組的設定來達成,下次再撰文說明),本文先針對第二點進行說明。
要設定「密碼有效期為90天」並不困難,不管在 Solaris / Linux 上都只要透過 passwd 指令或者 chage 指令即可完成,但由於我覺得 chage 指令很容易使用,查詢所得的結果也很容易閱讀,所以這次就以 chage 來實作。
有關 chage 指令的用法,除了參考鳥哥的網站,也可以直接下 man chage 指令來查詢內建的 man page,我用的指令如下:
chage -I 1 M 90 -W 30 [username] chage -d 2010-03-17 [username]
(第二個指令是為了避免設定好第一個指令以後,所有系統上 90 天內不曾修改密碼的使用者下次登入系統時都要重新設定密碼,因此把「最後一次修改密碼」的日期改為今天)
設定完畢之後,再下 chage –l [username] 指令 (英文的 l) 即可查詢該使用者的帳號狀態。
OK, 既然 chage 指令這麼簡單,那本文有甚麼好講的呢?如果只需要在單一主機上對少數幾個帳號作如此的設定,當然是直接下幾個指令就搞定,問題是這次需要修改的主機超過 50 台,每台主機上面又有一大堆帳號,真要這樣下指令的話會瘋掉!(而且還有第1和第3項要求要作到,那又是另外兩行 Perl 程式) 所以我就把這些機械化的動作寫成一個 script 啦!
第一步:詢問使用者 chage -d 要使用的日期參數:
echo “set Last password change day (YYYY-MM-DD): “ read lDays #把使用者輸入的參數存到 $lDays 變數中
接下來判斷使用者輸入的字串是否符合 YYYY-MM-DD 的格式:
syntaxOK=`echo $lDays | perl –ne ‘print “OK” if /^\d{4}-\d{2}-\d{2}/’` (`` 是 backtick,不是單引號哦~)
if [ "$syntaxOK" != "OK" ]; then    echo "Wrong syntax! Usage: YYYY-MM-DD"    exit fi
這裡用 perl 來寫 regular expression 會比用 shell script 簡單很多,shell script 要這樣寫 (因為沒有支援 \d 這樣的表示法,而且也不支援 {4} 的寫法):
syntaxOK=`echo $lDays | grep "^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$"`
神奇的是用 perl 的話不用加上「$」來限制結尾要是 2 個數字,就自然可以判斷出「1111-11-111」是不符合 pattern 的,但是用 shell script 中的 grep 的話就要 (用 egrep 還是要加上「$」)。
第二步:列出系統中所有的使用者,除了系統內建帳號以外:
我參考的是 Listing all users on the system 一文,但是在 awk 的主程式中加上 regular expression 的判斷:
for name in $(awk 'BEGIN{FS=":"} { if($3 ~ /^5[0-9][0-9]/) {print $1}}' < "$PASSWORD_FILE" )
利用這個 pattern 可以過濾出第三欄 ($3) 的值是「5xx」(xx 為數字) 的資料,且印出第一欄 ($1)。
第三步:過濾 uid > 500 的帳號中,屬於系統帳號 or 給程式使用的帳號:
一般來說 uid < 500 的是保留給系統使用的帳號,但 uid > 500 的帳號中仍有可能存在單純給程式使用的帳號 (e.g., 給 FTP / scp 使用),因此需要進一步過濾。我的作法世新增一個 AccountExcluded.txt 檔案,以一行一個帳號的方式,將欲排除的帳號寫入這個檔案,接下來用一個迴圈就可以比對:
accountExcluded=`cat ./AccountExcluded.txt` excluded="0" for exclude in $accountExcluded do      if [ $name = $exclude ]; then             excluded="1"      fi done
第四步:執行 chage 指令
到了這個步驟才是整個 script 的核心,對於每個不在 AccountExcluded.txt 檔案中的帳號,只要在以上的迴圈中執行以下兩行即可:
chage -M 90 -W 30 $name chage -d $lDays $name
整個 script 其實就只有這樣而已,為了避免更動到系統帳號才額外加了一堆有的沒的程式碼 (為了寫 log 又另外加了一堆),在這次練習的過程中,發現還是寫 RegExp 最好玩 (awk 也很有趣),其他的程式碼都挺無聊的。
這個 script 未來還有很多可以 enhance 的地方,依照重要性由高到低排列:
  1. 在本機上登入所有需要修改的主機,將本機的 shell script 檔&設定檔複製到所有的主機上執行 (不然一台一台的登入也是很累人的)。將這個架構建立起來以後,未來有遇到類似要再每台主機上調整設定的需求,就可按照同樣的模式寫成一個 script 來執行。
  2. 加強 YYYY-MM-DD 的判斷,找找看有沒有轉換成 Date 之類型態的方式可用,順便避免 2/29 的問題。
  3. 把讀取兩次 /etc/passwd 的寫法改成只讀取一次,第一次讀出資料以後存到一個 array 裡面就好。
  4. 加強過濾 /etc/passwd 檔案時使用的 regular expression,雖然目前實務上接觸到的主機還不至於帳號多到 uid > 600 或者更高,但可以當作一個練習 regular expression 的機會。
有興趣參考完整原始碼的朋友請到這裡下載 (V1)。

參考:[2010-12-13] [Shell Script] 批次修改使用者的密碼有效期限 - V2

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D