Kolaborasi Pengguna Zimbra Collaboration Active Directory Berbasiskan OSE

1. Latar Belakang


Saat mengkonfigurasi server zimbra, saya menemui masalah sinkronisasi pengguna dengan grup di Active Directory (AD). Jika kami membuat pengguna baru dalam AD, maka itu biasanya ditambahkan, tetapi jika kami membuat akses ke server mail berdasarkan grup, maka untuk pertama kalinya semua pengguna disinkronkan. Tapi kemudian, perubahan dalam grup tidak mempengaruhi perubahan pada pengguna server email zimbra.

Apa yang tidak suka dalam artikel ini adalah penggunaan skrip PowerShell (mengapa, jika ada ldapsearch) dan penggunaan konstan utilitas zmprov, dan ketika sejumlah besar pengguna disinkronkan, skrip berjalan untuk waktu yang lama

2. Sumber data


Server OS: CentOS 7
Bahasa skrip: bash
domain Zimbra: test.ru
Server Zimbra: zimbra.test.local
Domain Direktori Aktif: test.local
Grup AD untuk akses ke surat: surat

Seorang pengguna mungkin memiliki surat berbeda dari loginnya, surat seperti itu tambahkan ke AD di bidang email dan gunakan untuk membuat alias di zimbra (misalnya, Vasya Pupkin masuk ke sistem menggunakan nama pengguna vasia, tetapi email harus dikirim dan diterima sebagai pengguna v.pupkin@test.ru)

3. Skema skrip


  1. Simpan ke file pengguna AD yang termasuk dalam grup email
  2. Kami menyimpan semua pengguna zimbra dengan semua atribut ke file
  3. Kami membagi file dengan daftar semua pengguna zimbra ke dalam format file: nama file - login pengguna, konten - atribut pengguna
  4. Kami menghapus dari daftar akun sistem zimbra pengguna (admin, gal, antivirus)
  5. Bandingkan daftar pengguna AD dan zimbra
  6. Buat file dengan perintah untuk menambah, menghapus (dalam kasus saya, memblokir pengguna), menyinkronkan dan membuat alias
  7. Terapkan tindakan ini dalam zimbra (satu panggilan ke zmprov)
  8. Kirim laporan ke administrator melalui surat (jika Anda memiliki sesuatu untuk dikirim)
  9. Hapus file dan direktori sementara

4. Sinkronisasi skrip


Script memiliki dua mode operasi - ini diluncurkan tanpa parameter, maka hanya memblokir dan menambahkan pengguna akan berfungsi. Dan mulai dengan parameter "semua", maka semua pengguna grup email dalam AD akan disinkronkan.

Juga perlu memperhatikan penggunaan utilitas decoding base64 dalam fungsi sinkronisasi, itu harus digunakan untuk bidang AD di mana karakter Rusia digunakan.

Script itu sendiri:
#!/bin/bash
#
#1.  
#
#1.1  
#   
path="/mnt/zimbra/user-sync"
# 
timestamp=`date +%F-%H-%M`
#   
tmp_dir=$path/tmp
#      zimbra
zim_us=$tmp_dir/zim-us
#   
log_dir=$path/log
# -
log=$log_dir/grouplog_$timestamp.txt
#      
usname=$tmp_dir/usname
#          zmprov
zmcmdfile=$tmp_dir/zmcmdfile
#        AD 
userfil=$tmp_dir/userfil
# 
mutt="/usr/bin/mutt"

#
#1.2   zimbra
#  Zimbra
domain="test.ru"
#   zmprov
zmprov="/opt/zimbra/bin/zmprov"
#
#1.3    AD  LDAP
#LDAP search
ldapsearch=/opt/zimbra/common/bin/ldapsearch
#    ( ,   (   ))
ldap_server="ldap://test.local:389"
# OU 
basedn="DC=test,DC=local"
#      AD  LDAP
binddn="CN=zimbra,CN=Users,DC=test,DC=local"
bindpw="qwe123" #user password 
#  -     mail
filter="(memberof=cn=mail,cn=users,dc=test,dc=local)"
#    (,             )
fields="sAMAccountName mail description displayName givenName cn sn department title"
#  

# 

# 
#   
function err_log()
{
if [ $1 -eq 0 ]; then
		#echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]"
		#echo
		echo $2" [Ok]"  >> $log
	else
		#echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]"
		#echo
		echo  $2" [Fail]" >> $log
	fi
}

#  
function if_path ()
{
	#      
	if [ ! -d $1 ]; then
	#   
	echo "  $1..." >> $log
	mkdir -p $1
	err_log $? "  $1"
	
else
	echo "  $1 " >> $log	
fi
}

#      AD
function search_users_AD()
{
	echo "     AD..." >> $log
	$ldapsearch -x -o ldif-wrap=no -H $ldap_server -D $binddn -w $bindpw -b $basedn $filter $fields | 
	grep sAMAccountName | 
	egrep -v '^#|^$' | 
	awk '{print $2}' |
	sort > $usname.ad
	echo "Found () "`cat $usname.ad | wc -l`" Group in AD (  AD)" >> $log
}

function all_user_attr_zimbra()
{
	#        
	$zmprov -l gaa -v $domain > $usname.gaa
	#         
	cd $zim_us
	#      ,     
	csplit $usname.gaa --prefix='user.' --suffix-format='%03d.zim' --elide-empty-files -s /"# name"/ '{*}'

	#   .      zimbra  
	for i in $( ls $zim_us )
	do
		nam=`grep "# name" $zim_us/$i | awk '{ print $3}' | sed 's/@.*//g'`
		mv -f $zim_us/$i $zim_us/$nam
	done
	cd $path
}

#      zimbra 
function search_user_zimbra()
{
	echo "    zimbra..." >> $log
	ls $zim_us | sort > $usname.tem
	#    .  $path/system.acc    
	diff -u -i $usname.tem $path/system.acc  | sed 1,3d | grep ^- | cut -c 2- | sort > $usname.zim
	#rm -f $usname.tem
	echo "Found () "`cat $usname.zim | wc -l`" Group in Zimbra (  Zimbra)" >> $log
	
}

#    (   
function diff_user_list()
{
	diff -u -i $usname.zim $usname.ad | sed 1,3d | sed '/@.*/d' > $usname.diff
}

# 
function adduser()
{
#    	
adddif=`grep ^+ $usname.diff | sed '1!d'`
	if [ -n $adddif ];
	then
		for addus in $( grep ^+ $usname.diff | cut -c 2- )
		do
			#       zimbra (  - ,  - )
                        ifclos=`grep "zimbraAccountStatus:" $zim_us/$addus | awk '{print $2}' | cut -c -1`
			if [ $ifclos = "c" ];
			then
				echo "ma $addus@$domain zimbraAccountStatus active" >> $zmcmdfile
				echo " $addus " >> $tmp_dir/send.txt
				if [ $addus != "" ];
				then
					sync_one_user $addus
				fi
			else
				#123456 -  ,    .   ,         AD
				echo "ca $addus@$domain 123456" >> $zmcmdfile
				echo " $addus " >> $tmp_dir/send.txt
				if [ $addus != "" ];
				then
					sync_one_user $addus
				fi
			fi
		done
		
	fi
}

#   
function block_user()
{
	deldif==`grep ^- $usname.diff | sed '1!d'`
	if [ -n $deldif ];
	then
		for delus in $( grep ^- $usname.diff | cut -c 2- )
		do
			#zimbraAccountStatus closed
			if [ $delus != "" ];
			then
				ifclos=`grep "zimbraAccountStatus:" $zim_us/$delus | awk '{print $2}'`
				if [ "$ifclos" != "closed" ];
				then
					echo "user closed - $delus"
					echo "ma $delus@$domain zimbraAccountStatus closed" >> $zmcmdfile
					echo " $delus !     !" >> $tmp_dir/send.txt
					echo $delus >> $path/close.1
					cat $path/close.1 | sort > $path/close.diff
					echo "$delus" 
				fi
			fi
		done
	fi
}

#   
function ifattr()
{
	if1char=`echo $2 | cut -c -1`
	if [[ -n $2 && $if1char != "" ]];
	#if [ $2 != "" ];
	then 
	    #echo $2
	    echo -n " $1 \"$2\""  >> $zmcmdfile
	fi
}

#  
function sync_one_user()
{
	echo "  $1..." >> $log
	$ldapsearch -x -o ldif-wrap=no -H $ldap_server -D $binddn -w $bindpw -b $basedn "(sAMAccountName=$1)" $fields > $userfil/$1.ad
	
	#   
	echo -n  "ma "$1 >> $zmcmdfile
	
	#samacc=`grep "sAMAccountName:" $userfil/$1 | awk '{print $2}'`  
		
	description=`grep "description:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}'`
	#echo $description
	ifattr "description" "$description"
		
	displayName=`grep "displayName:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}' | base64 -d`
	ifattr "displayName" "$displayName"
	
	givenName=`grep "givenName:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}' | base64 -d`
	ifattr "givenName" "$givenName"
	
	cn=`grep "cn:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}'`
	ifattr "cn" "$cn"
	
	sn=`grep "sn:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}' | base64 -d`
	ifattr "sn" "$sn"
	
	department=`grep "department:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}' | base64 -d`
	ifattr "company" "$department"
	
	title=`grep "title:" $userfil/$1.ad | awk '{split ($0, a, ": "); print a[2]}' | base64 -d`
	ifattr "title" "$title"
	
	#    
	echo >> $zmcmdfile
	# 
	mailnew=`grep "mail:" $userfil/$1.ad | awk '{print $2}'`
	if [ "$mailnew" != "" ];
	then 
	# [ -n $mailnew ] 
	#    echo $2
		#    
		#${1,,} -      
		useralias=`grep "zimbraMailAlias:" $zim_us/${1,,} | awk '{print $2}'`
	    if [ $useralias != $mailnew ];
		then
			echo "aaa \"$1@$domain\" \"$mailnew\""  >> $zmcmdfile
		fi
	fi
	#ifattr "mail" $mailnew
#	echo $mailnew
	echo "  $1 " >> $tmp_dir/send.txt 
	
#	echo " $1 - $atrruser"
	
	#echo "Found () "`cat $usname.ad | wc -l`" Group in AD (  AD)" >> $log
}


# 
date +%F-%H-%M
#2.  
#  
if_path $path
#  
if_path $tmp_dir
# -
if_path $log_dir
#   
if_path $userfil
#    
if_path $zim_us

#         zmprov
:> $zmcmdfile
#    
:> $tmp_dir/send.txt
#3.     AD 
search_users_AD

#4.    zimbra 
all_user_attr_zimbra
#  ()
search_user_zimbra

#5.    
diff_user_list
# 
block_user
#    
adduser

#tckb    "all"  ,        mail AD
if [[ -n $1 && $1 = "all" ]];
then
	for us in $(cat $usname.ad );
	do
	#	echo $us
		sync_one_user $us
	done
fi
#      zmprov  
$zmprov -f $zmcmdfile
#       
cat $zmcmdfile >> $log
#     (  )
if [ -s $tmp_dir/send.txt ];
then
	$mutt  -s "   $timestamp" admins@test.ru -a $log < $tmp_dir/send.txt
fi

#    
rm -R -f $tmp_dir


5. Kesimpulan


Secara umum, skrip ternyata cukup cepat, utilitas zmprov hanya digunakan dua kali, seluruh utilitas dan fungsi bekerja lebih cepat.

6. Referensi


Saat membuat artikel ini, ide dan artikel digunakan:

1. Andrey Sysoev
2. DruGoeDeLo
3. Komentar saya pada artikel 1) dengan skrip untuk menyinkronkan milis

All Articles