Скрипт для добавления ACL Postfix

Thank you for reading this post, don't forget to subscribe!

Необ­хо­ди­мо было настро­ить огра­ни­че­ние для релея сле­ду­ю­щим образом:
несколь­ко сер­ве­ров с одним email мог­ли пере­сы­лать почту, для всех осталь­ных запретить.

Перед запус­ком скрип­та убе­ди­тесь, что в кон­це кон­фи­гу­ра­ци­он­но­го фай­ла postfix име­ет­ся запись:

smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_mail/mail_list, reject

cat skrip_permit_ip_and_mail_for_sending_email.sh

[codesyntax lang="bash" lines="no"]

[/codesyntax]

 

===========================================================================================

Ниже пред­став­лен поша­го­вый резуль­тат выпол­не­ния скрип­та, на каж­дом из этапов.
Исход­ный файл с наши­ми данными:

cat /etc/postfix/list_ip_mail
10.10.10.1 db@domain.ru
10.10.10.2 scaner@domain.ru
10.10.10.3 scaner@domain.ru
10.10.10.4 tb@domain.ru
10.10.10.5 scaner@domain.ru

После нуме­ру­ем и при­во­дим к виду:
cat /etc/postfix/list_ip_mail
1 10.10.10.1 db@domain.ru
2 10.10.10.2 scaner@domain.ru
3 10.10.10.3 scaner@domain.ru
4 10.10.10.4 tb@domain.ru
5 10.10.10.5 scaner@domain.ru

Созда­ём спи­сок с уни­каль­ны­ми поч­то­вы­ми адресами:
cat /etc/postfix/list_ip_mail | awk '{print $3}' | sort| uniq | grep -v ^$ > /etc/postfix/list_uniq_mail
cat /etc/postfix/list_uniq_mail
db@domain.ru
scaner@domain.ru
tb@domain.ru

созда­ём спи­сок где в стро­ке ука­за­ны ip и email (в слу­чае если для одно­го email ука­за­ны несколь­ко IP то стро­ка будет иметь вид "IP email newIP email)

for i in `cat /etc/postfix/list_uniq_mail`; do echo $(grep " $i" /etc/postfix/list_ip_mail | awk '{print $1="", $0}'); done > /etc/postfix/list_ip_mail_sovmestnij

cat /etc/postfix/list_ip_mail_sovmestnij
10.10.10.1 db@domain.ru
10.10.10.2 scaner@domain.ru 10.10.10.3 scaner@domain.ru 10.10.10.5 scaner@domain.ru
10.10.10.4 tb@domain.ru

for i in `cat /etc/postfix/list_ip_mail_sovmestnij | awk '{print $2}'`; do echo $(grep " $i" /etc/postfix/list_ip_mail_sovmestnij| sed "s/${i}//g") $i; done > /etc/postfix/ip_mail2

cat /etc/postfix/ip_mail2
10.10.10.1 db@domain.ru
10.10.10.2 10.10.10.3 10.10.10.5 scaner@domain.ru
10.10.10.4 tb@domain.ru

Нуме­ру­ем:
cat -n /etc/postfix/ip_mail2 > /etc/postfix/ip_mail
cat /etc/postfix/ip_mail
1 10.10.10.1 db@domain.ru
2 10.10.10.2 10.10.10.3 10.10.10.5 scaner@domain.ru
3 10.10.10.4 tb@domain.ru

# выпол­ня­ем в цик­ле сле­ду­ю­е­щее: смот­рим каж­дую стро­ку и содер­жи­мое всех столбцов(кроме пер­во­го столбца"номер" и послед­не­го столб­ца "поч­то­вый ящик") запи­сы­ва­ем в отдель­ный файл с име­нем пер­во­го столб­ца стро­ки (для это­го мы их нумеровали)

while read line; do
echo $(echo $line | awk '{print $1="", $NF="", $0}') > /etc/postfix/access_mail/access_ip$(echo $line | awk '{print $1}');
done < /etc/postfix/ip_mail

На дан­ном эта­пе созда­ют­ся сле­ду­ю­щие файлы:
cat /etc/postfix/access_mail/access_ip1
10.10.10.1

cat /etc/postfix/access_mail/access_ip2
10.10.10.2 10.10.10.3 10.10.10.5

cat /etc/postfix/access_mail/access_ip3
10.10.10.4

#дела­ем пере­нос строк внут­ри файла:
for i in `ls /etc/postfix/access_mail/access_ip*`; do sed -i 's/ /\n/g' $i; done

cat /etc/postfix/access_mail/access_ip2
10.10.10.2
10.10.10.3
10.10.10.5

#добав­ля­ем в кон­це каж­дой строй­ки ОК
for i in `ls /etc/postfix/access_mail/access_ip*`; do sed -i 's/$/ OK/' $i; done

cat /etc/postfix/access_mail/access_ip2
10.10.10.2 OK
10.10.10.3 OK
10.10.10.5 OK

# выпол­ня­ем в цик­ле сле­ду­ю­е­щее: смот­рим каж­дую стро­ку и содер­жи­мое послед­не­го столб­ца запи­сы­ва­ем в файл /etc/postfix/access_mail/mail_list
while read line; do
echo "$(echo $line | awk '{print $NF}') class_domain$(echo $line | awk '{print $1}')" >> /etc/postfix/access_mail/mail_list;
done < /etc/postfix/ip_mail

cat /etc/postfix/access_mail/mail_list
db@domain.ru class_domain1
scaner@domain.ru class_domain2
tb@domain.ru class_domain3

# Воз­вра­ща­ем /etc/postfix/list_ip_mail к пер­во­на­чаль­но­му виду ip mail т.е. уби­ра­ем нумерацию
cat /etc/postfix/list_ip_mail
10.10.10.1 db@domain.ru
10.10.10.2 scaner@domain.ru
10.10.10.3 scaner@domain.ru
10.10.10.4 tb@domain.ru
10.10.10.5 scaner@domain.ru

Выпол­ня­ем postmap для всех фай­лов в дирек­то­рии /etc/postfix/access_mail/
for i in `ls /etc/postfix/access_mail/`; do postmap /etc/postfix/access_mail/$i; done

Созда­ют­ся фай­лы с рас­ши­ре­ни­ем .db

# Отсе­ка­ем всё содер­жи­мое после smtpd_sender_restrictions из глав­но­е­го кон­фи­гу­ра­ци­он­но­го фай­ла postfix и созда­ём его резерв­ную копию
cat /etc/postfix/main.cf | grep -B 100000 ^smtpd_sender_restrictions > /etc/postfix/main.cf2
mv /etc/postfix/main.cf /etc/postfix/main.cf.BACK.`date +%d-%m-%Y-%R`
mv /etc/postfix/main.cf2 /etc/postfix/main.cf

ll /etc/postfix/main.cf.BACK.*
-rw-r--r-- 1 root root 5637 Jan 30 15:40 /etc/postfix/main.cf.BACK.31-01-2019-09:26

# Полу­ча­ем спи­сок клас­сов в одну стро­ку через запя­тую (tr -s '\r\n' ' ')-уби­ра­ет пере­вод строки
for i in `cat /etc/postfix/access_mail/mail_list | awk '{print $2}'`; do echo $i,| tr -s '\r\n' ' '; done > $p/spisok_vseh_classov_v_stroku

cat spisok_vseh_classov_v_stroku
class_domain1, class_domain2, class_domain3,

# Запи­сы­ва­ем в пере­мен­ную klassi спи­сок клас­сов через запя­пую. (sed 's/ //' уби­ра­ем про­бе­лы) (sed 's/,$//' - уби­ра­ем послед­нюю запятую)
klassi=`cat $p/spisok_vseh_classov_v_stroku | sed 's/ //g' | sed 's/,$//'`

# запи­сы­ва­ем клас­сы в кон­фиг файл
echo "smtpd_restriction_classes = $klassi" >> /etc/postfix/main.cf

cat /etc/postfix/main.cf | tail -2
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_mail/mail_list, reject
smtpd_restriction_classes = class_domain1,class_domain2,class_domain3

# Добав­ля­ем клас­сы в кон­фиг файл postfix
for i in `cat -n /etc/postfix/access_mail/mail_list | awk '{print $1}'`; do echo "class_domain$i = check_client_access hash:/etc/postfix/access_mail/access_ip$i, reject"; done >> /etc/postfix/main.cf

cat /etc/postfix/main.cf | tail -5

smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access_mail/mail_list, reject
smtpd_restriction_classes = class_domain1,class_domain2,class_domain3
class_domain1 = check_client_access hash:/etc/postfix/access_mail/access_ip1, reject
class_domain2 = check_client_access hash:/etc/postfix/access_mail/access_ip2, reject
class_domain3 = check_client_access hash:/etc/postfix/access_mail/access_ip3, reject