要件
- LDAP に格納されているアカウントの証明書の有効期限をチェックしたい
- スクリプトは cron で定期的に実行したい
- 有効期限が切れて、一定期間経ったアカウントはチェック対象外としたい
- 使用可能ライブラリは、
ldapsearch
,openssl
,ShellScript
。ライブラリ追加不可。 - LDAP は
anonymous
バインド可能
実行環境
- Red Hat 4.4.7-16
- OpenSSL 1.0.1e-fips 11 Feb 2013
- ldapsearch 2.4.40
ソースコード
CertCheck.sh
#!/bin/sh
#set -x
# カレントディレクトリで作業する
cd `dirname $0`
# 接続先(外部引数)
LDAPHOST="ldaps://hogehoge:636"
# 検索ベースDN(サーバーリスト)
BASEDN="ou=servers,ou=pki,o=Hoge"
# 全件処理対象リスト
ALL_LIST_TXT=all.txt
# 証明書ファイル
CERT_FILE_TXT=cert.txt
# 結果ファイル
RESULT_TXT=result.txt
# 有効期限日数(この日数以内に証明書が切れる場合は処理対象)
EXPIRATION_DATES=60
# 期限切れ無視日数(この日数をすぎた証明書は無視)
EXPIRED_DATES=30
# 事前準備 ------------
if [ -f $CERT_FILE_TXT ]
then
rm -f $CERT_FILE_TXT
fi
if [ -f $RESULT_TXT ]
then
rm -f $RESULT_TXT
fi
if [ -f $ALL_LIST_TXT ]
then
rm -f $ALL_LIST_TXT
fi
# チェック対象全件リスト生成 ------------
/usr/bin/ldapsearch -LLL -H $LDAPHOST -x -b $BASEDN "(cn=*)" cn > $ALL_LIST_TXT
# チェック対象全件リストから証明書をファイル保存 ------------
while read line
do
# 全件リストのうち、cnをチェック
if echo $line | grep "cn:" >/dev/null ; then
echo "cn: $line"
# 属性名(4文字より前)は除去して変数として保持
CVAR=(cn="${line:4}")
# 証明書バイナリだけを別ファイルとして保存(tmp以下に出来る)
# -LLL print responses in LDIF format without comments
# and version
# -H URI LDAP Uniform Resource Identifier(s)
# -x Simple authentication
# -b basedn base dn for search
# -u include User Friendly entry names in the output
# -t write binary values to files in temporary directory
/usr/bin/ldapsearch -LLL -H $LDAPHOST -x -b $BASEDN -u -t "($CVAR)" "usercertificate;binary"
fi
done < $ALL_LIST_TXT
# 終わったら、証明書のバイナリを作業フォルダに移動 ------------
mv "/tmp/ldapsearch-usercertificate;binary-"* ./
# 証明書一件ずつ有効期限チェック ------------
for file in `\find . -maxdepth 1 -name 'ldapsearch-usercertificate;binary-*'`; do
echo $file ----------------
# 証明書の中身をder形式で読み出し、ファイルに出力(上書きで1件だけ)
# x509 - 署名済み証明書
# -in arg - input file - default stdin
# -text - print the certificate in text form
# -inform arg - input format - default PEM (one of DER, NET or PEM)
openssl x509 -in $file -text -inform der > $CERT_FILE_TXT
# 出力したファイルの中身をチェック
while read line; do
#echo $line
# 有効期限日
if echo $line | grep "Not After" >/dev/null ; then
# 属性名は除外
notafter=${line:12}
fi
# Subject
if echo $line | grep "Subject" >/dev/null; then
# 属性名は除外
subject=${line:9}
echo $notafter
echo $subject
# 有効期限の秒数を取得
notafter_second=`date -d "$notafter" '+%s'`
# 指定日数後の秒数を取得
nextdate_second=`date -d "$EXPIRATION_DATES days" '+%s'`
# 期限切れ日数後の秒数を取得
expireddate_second=`date -d "-$EXPIRED_DATES days" '+%s'`
# 本日の秒数を取得
now_second=`date '+%s'`
# echo notafter_second: $notafter_second
# echo nextdate_second: $nextdate_second
# echo now_second: $now_second
# echo expireddate_second: $expireddate_second
if [ $nextdate_second -ge $notafter_second ] && [ $expireddate_second -le $notafter_second ] ; then
# 有効期限が指定日数後以下(指定日数以内に期限が切れる)場合
# かつ、期限切れで指定日数以降ではない場合
echo $subject >> $RESULT_TXT
echo 有効期限: $notafter >> $RESULT_TXT
diff=`expr \( $notafter_second - $now_second \) / \( 60 \* 60 \* 24 \)`
# echo diff: $diff
echo 残り日数: $diff >> $RESULT_TXT
echo "" >> $RESULT_TXT
fi
# subjectが取れたら終了
break
fi
done < $CERT_FILE_TXT
# 終わったら証明書削除
rm -f $file
done
# 後始末 ------------
if [ -f $CERT_FILE_TXT ]
then
rm $CERT_FILE_TXT
fi
if [ -f $ALL_LIST_TXT ]
then
rm $ALL_LIST_TXT
fi