Zimbra: различия между версиями
Vovan (обсуждение | вклад) (→Интеграция) |
Vovan (обсуждение | вклад) (→Интеграция) |
||
Строка 381: | Строка 381: | ||
Сервер должен запускаться на хосте с zimbra под суперпользователем. | Сервер должен запускаться на хосте с zimbra под суперпользователем. | ||
− | Пример внешней системы, которая может быть клиентом описанного в этом разделе сервера, | + | Пример внешней системы, которая может быть клиентом описанного в этом разделе сервера, описан [[ Pam#.D0.97.D0.B0.D0.BF.D1.83.D1.81.D1.82.D0.B8.D1.82.D1.8C_.D1.81.D1.86.D0.B5.D0.BD.D0.B0.D1.80.D0.B8.D0.B9_.D0.BF.D1.80.D0.B8_.D0.B2.D1.85.D0.BE.D0.B4.D0.B5_.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D1.82.D0.B5.D0.BB.D1.8F_.D0.B2_GNU.2FLinux_.D1.81_.D0.BF.D0.B5.D1.80.D0.B5.D0.B4.D0.B0.D1.87.D0.B5.D0.B9_.D0.B2_.D0.BD.D0.B5.D0.B3.D0.BE_.D0.BB.D0.BE.D0.B3.D0.B8.D0.BD.D0.B0_.D0.B8_.D0.BF.D0.B0.D1.80.D0.BE.D0.BB.D1.8F | здесь]] |
==Создаём каталог для сервера интеграции== | ==Создаём каталог для сервера интеграции== |
Версия 09:31, 26 декабря 2023
URL: | https://mail.nntc.nnov.ru |
---|---|
Платформа: | Zimbra |
Сервер: | apve3/vestacp |
IP-адрес: | 192.168.10.151 |
Открытые порты: | 443TCP (Web-интерфейс) |
Содержание
Настройка доступа к контактам через Thunderbird
Данная инструкция проверялась на Ubuntu 20.04.
- Скачать и установить дополнение CardBook в Thunderbird. Можно найти через менеджер дополнений и установить оттуда же.
- Открыть окно CardBook (кнопка находится в правом верхнем углу окна Thunderbird.)
- Правой кнопкой мыши кликнуть на список адресных книг в левой части экрана и выбрать из меню "Новая адресная книга" ("New Address Book".)
- В открывшемся окне выбрат тип адресной книги "Remote".
- Выбрать тип адресной книги "CardDAV". В настройках подключения указать URL следующего вида:
https://mail.nntc.nnov.ru/dav/<user-name>@nntc.nnov.ru/Contacts/
- Ввести имя пользователя почты и пароль.
bind
cat << 'EOF' > /etc/bind/named.conf.options options { directory "/var/cache/bind"; // forward only; // If there is a firewall between you and nameservers you want // to talk to, you may need to fix the firewall to allow multiple // ports to talk. See http://www.kb.cert.org/vuls/id/800113 // If your ISP provided one or more IP addresses for stable // nameservers, you probably want to use them as forwarders. // Uncomment the following block, and insert the addresses replacing // the all-0's placeholder. forwarders { 8.8.8.8; }; //======================================================================== // If BIND logs error messages about the root key being expired, // you will need to update your keys. See https://www.isc.org/bind-keys //======================================================================== dnssec-validation no; listen-on-v6 { any; }; }; EOF
echo 'include "/etc/bind/qwe.rty.ru_zones.conf";' >> /etc/bind/named.conf
cat << 'EOF' > /etc/bind/qwe.rty.ru_zones.conf zone "qwe.rty.ru" { type master; file "/etc/bind/zone_qwe.rty.ru"; }; EOF
cat << 'EOF' > /etc/bind/zone_qwe.rty.ru $ORIGIN qwe.rty.ru. $TTL 86400 @ IN SOA ns1.qwe.rty.ru. root.qwe.rty.ru. ( 2023013110; Serial 3600 ; Refresh 900 ; Retry 604800 ; Expire 86400 ; Minimum ) ; IN NS ns1.qwe.rty.ru. @ IN A 192.168.10.51 ns1 IN A 192.168.10.51 ns2 IN A 192.168.10.51 www IN CNAME @ ;mail IN CNAME @ mail IN A 192.168.10.51 @ IN MX 10 mail mail IN MX 10 mail @ IN TXT "v=spf1 a mx ip4:89.109.54.20 ~all" _dmarc IN TXT "v=DMARC1; p=quarantine" 2B2943B4-A15F-11ED-BFE7-22BC155843E7._domainkey 300 IN TXT ( "v=DKIM1; k=rsa;" "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoGbExU/BhOyVqPnwz80o1NKVTkH9zPvo4x6Qs5+MuZsWH+fk5lpKxtrhiD+3+sjzpMZBSXmJ5JEefqW+0dByQrATJY91ynYzY3hOFdhLvkptNisNiycdFT5u3lT4PxfXG/GB8CVvX88OXXjXuD3zAL2cbs+u+AsY2a+85D/5L1/SPxqvUOi1B1o0Lsk9e4shZTLlIH/0NKF9yE" "3ECAsAJiHhV3GJZbytTBR8lAHb7UCBgqI1/2tOB2gaCfXKOoJ4shcCEjrlzGT6C6c7I7J0i4UMRgv446EMK7/Ddynmu7SisiOXnl06J38GKtLp36PHtOZYhOJWc0ke0ap9+7YQMQIDAQAB" ) EOF
systemctl stop systemd-resolved systemctl disable systemd-resolved
Настройка dkim, spf, dmark
Источник: https://habr.com/ru/company/Zextras/blog/339296/
dkim
Добавляем dkim к домену
/opt/zimbra/libexec/zmdkimkeyutil -a -d nntc.nnov.ru
В ответ получаем текст типа такого
DKIM Data added to LDAP for domain nntc.nnov.ru with selector 1774E6C4-60E2-11ED-9312-806B2F1CB351 Public signature to enter into DNS: 1774E6C4-60E2-11ED-9312-806B2F1CB351._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvoJiPVvchkOXgMRcxHTMTlkmFIk5BLkHqbY7htxDCRD7Pnwchktcdg7HAWd7SMgdJeSylo221GKKrx/f1nOYp0naBcRzPXi9R3a/a3fsY94indUuI1JnwrL3RCoCl4TkTSAP4VGP9hcTcf1ms6u2mbKuiKgdaKeXieXInIhg+KasYm9hnFTMX8I+mZOjvwbOQETpmxrXUW8Uo9" "I87BJDBMF5Wb2u6Mr0KaoCjpie9Y89YwXGID6Ofor1Rg2qra507oNIPnFFhKI6KacBMS1kQTESgJ0AJxvyjuc+fKGcmA+sh2rzYLlRulvGu4mBsZkKJuLP0iuZgymPS1oB0PA5WQIDAQAB" ) ; ----- DKIM key 1774E6C4-60E2-11ED-9312-806B2F1CB351 for nntc.nnov.ru
Далее идём в настройки DNS записей для домена nntc.nnov.ru и добавляем такую TXT запись в настройках домена.
В случае с настройками днс сервера типа bind9 запись будет выглядеть примерно так. Если интерфейс настройки другой, то бездумно копировать этот текст не надо. Надо копировать - подумав! :-)
1774E6C4-60E2-11ED-9312-806B2F1CB351._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvoJiPVvchkOXgMRcxHTMTlkmFIk5BLkHqbY7htxDCRD7Pnwchktcdg7HAWd7SMgdJeSylo221GKKrx/f1nOYp0naBcRzPXi9R3a/a3fsY94indUuI1JnwrL3RCoCl4TkTSAP4VGP9hcTcf1ms6u2mbKuiKgdaKeXieXInIhg+KasYm9hnFTMX8I+mZOjvwbOQETpmxrXUW8Uo9" "I87BJDBMF5Wb2u6Mr0KaoCjpie9Y89YwXGID6Ofor1Rg2qra507oNIPnFFhKI6KacBMS1kQTESgJ0AJxvyjuc+fKGcmA+sh2rzYLlRulvGu4mBsZkKJuLP0iuZgymPS1oB0PA5WQIDAQAB" ) ; ----- DKIM key 1774E6C4-60E2-11ED-9312-806B2F1CB351 for nntc.nnov.ru
Проверяем
host -t txt 1774E6C4-60E2-11ED-9312-806B2F1CB351._domainkey.nntc.nnov.ru
В ответ должен прийти тот текст, который является значением для TXT зоны 1774E6C4-60E2-11ED-9312-806B2F1CB351._domainkey.nntc.nnov.ru, добавленной выше где-то там на сервере, который обслуживает днс зону
Формируем команду для проверки ключа в зимбре.
/opt/zimbra/common/sbin/opendkim-testkey -d nntc.nnov.ru -s 1774E6C4-60E2-11ED-9312-806B2F1CB351 -x /opt/zimbra/conf/opendkim.conf
Если в ответ не прилетает текста с ошибками, значит всё настроено верно, скорее всего. Но нужно убедиться, выполнив проверку на стороннем сервисе. Например здесь: https://www.mail-tester.com
Ещё важный момент: Если на самой зимбре настроен внутренний днс сервер на bind9, то в зону nntc.nnov.ru необходимо также добавить выше описанную TXT запись.
spf
В нашем случае для spf нужно сделать такую TXT запись для домена nntc.nnov.ru
v=spf1 a mx ip4:89.109.54.20 ~all
dmark
В нашем случае для dmark нужно сделать такую TXT запись для домена _dmarc.nntc.nnov.ru
v=DMARC1; p=quarantine
Итог
В итоге зона DNS сервера должна иметь такие настройки, которые представлены ниже в формате конфига для сервера bind9
$ORIGIN nntc.nnov.ru. $TTL 86400 @ IN SOA ns1.nntc.nnov.ru. root.nntc.nnov.ru. ( 2022111004 ; Serial 3600 ; Refresh 900 ; Retry 604800 ; Expire 86400 ; Minimum ) ; IN NS ns1.nntc.nnov.ru. @ IN A 192.168.10.51 ns1 IN A 192.168.10.51 ns2 IN A 192.168.10.51 www IN CNAME @ ;mail IN CNAME @ mail IN A 192.168.10.51 @ IN MX 10 mail mail IN MX 10 mail @ IN TXT "v=spf1 a mx ip4:89.109.54.20 ~all" _dmarc IN TXT "v=DMARC1; p=quarantine" 1774E6C4-60E2-11ED-9312-806B2F1CB351._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvoJiPVvchkOXgMRcxHTMTlkmFIk5BLkHqbY7htxDCRD7Pnwchktcdg7HAWd7SMgdJeSylo221GKKrx/f1nOYp0naBcRzPXi9R3a/a3fsY94indUuI1JnwrL3RCoCl4TkTSAP4VGP9hcTcf1ms6u2mbKuiKgdaKeXieXInIhg+KasYm9hnFTMX8I+mZOjvwbOQETpmxrXUW8Uo9" "I87BJDBMF5Wb2u6Mr0KaoCjpie9Y89YwXGID6Ofor1Rg2qra507oNIPnFFhKI6KacBMS1kQTESgJ0AJxvyjuc+fKGcmA+sh2rzYLlRulvGu4mBsZkKJuLP0iuZgymPS1oB0PA5WQIDAQAB" ) ; ----- DKIM key 1774E6C4-60E2-11ED-9312-806B2F1CB351 for nntc.nnov.ru
Фиксы
Переименовать
su - zimbra /opt/zimbra/libexec/zmsetservername -n nntc.nnov.ru
Предотвратить попадания писем в спам для внутренних ящиков
zmprov ms `zmhostname` zimbraAmavisOriginatingBypassSA TRUE zmamavisdctl restart
Создать spam,ham and quarantine accounts
http://docs.zimbra.com/docs/os/6.0.2/administration_guide/A_app-command-line.13.3.html
Get the previous account names from the global configuration:
su - zimbra zmprov -l gacf zimbraAmavisQuarantineAccount zimbraSpamIsSpamAccount zimbraSpamIsNotSpamAccount
Now recreate the account using the name obtained in the previous step: Spam Account:
zmprov ca <spam-account@example.com> <PASSWORD> amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE description 'System account for spam training.'
Ham Account:
zmprov ca <ham-account@example.com> <PASSWORD> amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE description 'System account for Non-Spam (Ham) training.'
Quarantine Account:
zmprov ca <virus-quarantine-account@example.com> <PASSWORD> amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE zimbraMailMessageLifetime 30d description 'System account for Anti-virus quarantine.'
Steps to create new spam, ham and quarantine accounts
apt install binutils
The above recreates existing accounts. If there is a need to recreate accounts with a random name, like spam.<random number> and ham.<random number>, follow these steps.
First create spam, ham and quarantine accounts with random passwords and add a random string in account name.:
zmprov ca spam.`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`@example.com "`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`" amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE description 'System account for spam training.'
zmprov ca ham.`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`@example.com "`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`" amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE description 'System account for Non-Spam (Ham) training.'
zmprov ca virus-quarantine.`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`@example.com "`strings /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c10`" amavisBypassSpamChecks TRUE zimbraAttachmentsIndexingEnabled FALSE zimbraIsSystemAccount TRUE zimbraIsSystemResource TRUE zimbraHideInGal TRUE zimbraMailMessageLifetime 30d description 'System account for Anti-virus quarantine.'
Get the new account names:
zmprov -l gaa | egrep -i 'spam|ham|virus-quarantine'
Now add these to the global configuration, and restart for the changes to take effect:
zmprov mcf zimbraSpamIsSpamAccount <spam-account@example.com> zimbraSpamIsNotSpamAccount <ham-account@example.com> zimbraAmavisQuarantineAccount <virus-quarantine-account@example.com>
zmcontrol restart
Note: Replace example.com with the actual primary domain name.
Улучшить параметры получения писем
https://habr.com/ru/company/Zextras/blog/436304/
В файле
/opt/zimbra/conf/opendkim.conf.in
выставить параметры
On-NoSignature reject Mode sv
перезапустить сервис
su - zimbra zmopendkimctl restart
Скрипты
Получить список ящиков в файл
su zimbra - zmaccts | grep "@" | awk '{print $1}' > accounts.txt
Резервное копирование
cat << 'EOF' > /opt/export-boxes.sh #!/bin/bash dest="/mnt/backup" for i in $(cat accounts.txt); do mailbox="$i" stamp="$(date +%Y_%m_%d__%H_%M_%S)" destfile="${dest}/${mailbox}_${stamp}".tar echo "now backup mbox $mailbox to $destfile" /opt/zimbra/bin/zmmailbox -z -t 0 -m "${mailbox}" getRestURL -u "https://mail.nntc.nnov.ru" "//?fmt=tar" > ${destfile} echo "done. Next..." echo "" done EOF
Восстановление из резервных копий
cat << 'EOF' > /opt/import-boxes.sh #!/bin/bash dest="/mnt/backup" for i in $(cat accounts.txt); do mailbox="$i" stamp="$(date +%Y_%m_%d__%H_%M_%S)" destfile="${dest}/${mailbox}_${stamp}".tar echo "now backup mbox $mailbox to $destfile" /opt/zimbra/bin/zmmailbox -z -t 0 -m "${mailbox}" getRestURL -u "https://mail.nntc.nnov.ru" "//?fmt=tar" > ${destfile} echo "done. Next..." echo "" done EOF
Сменить всем пароли
cat << 'EOF' > /opt/passwd-boxes.sh #!/bin/bash out="accounts.pwd" rm ${out} for ACCOUNT in `cat accounts.txt`; do PASS=`pwgen -s 12 1` echo $ACCOUNT #su - zimbra -c "zmprov sp $ACCOUNT NewGenerated42Password"; #su - zimbra -c "zmprov ma $ACCOUNT zimbraPasswordMustChange TRUE"; echo "${ACCOUNT} ${PASS}" >> ${out} done exit 0 EOF
Интеграция
В этом разделе представлен пример небольшого сервера для интеграции с zimbra. Сервер представляет из себя HTTP сервис, принимающий POST запрос с логином и паролем от внешней системы.
Сервер написан на nodejs, поэтому для его функционирования необходимо поставить пакет nodejs
apt-get install nodejs
Общий смысл работы сервера:
1. Принять POST запрос от внешней системы
2. Распознать в запросе корректно присланные логин и пароль
3. Добавить к логину домен почтового аккаунта (настраивается в файле скрипта /opt/zimbra_sync/exec.sh)
4. Проверить существования аккаунта в zimbra средствами zmprov
5. Если аккаунт существует, то поменять ему пароль
6. Если аккаунт не существует, то создать новый аккаунт и установить для него пароль
Сервер должен запускаться на хосте с zimbra под суперпользователем.
Пример внешней системы, которая может быть клиентом описанного в этом разделе сервера, описан здесь
Создаём каталог для сервера интеграции
mkdir /opt/zimbra_sync
Создаём файлы сервера на nodejs и скрипт, который будет выполняться при обращении к серверу
Сам сервер
cat << 'EOF' > /opt/zimbra_sync/app.js const http = require('http'); const spawn = require('child_process').spawn; const path = require('path'); const server = http.createServer((req, res) => { if (req.method === 'POST' && req.url === '/') { let data = ''; req.on('data', (chunk) => { data += chunk; }); req.on('end', () => { try { const { login, password } = JSON.parse(data); if (!login || !password) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Missing login or password in the request body.' })); return; } const scriptPath=`/opt/zimbra_sync/exec.sh`; const process = spawn(scriptPath, [login, password]); process.on('close', (code) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ exitCode: code })); }); process.on('error', (error) => { res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: `Error while executing the process: ${error.message}` })); }); } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(error)); } }); } else { res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Not Found' })); } }); const port = 65432; const host = '0.0.0.0'; server.listen(port, host, () => { console.log(`zimbra_sync server listen http://${host}:${port}`); }); EOF
Скрипт
cat << 'EOF' > /opt/zimbra_sync/exec.sh #!/bin/bash login="$1" password="$2" email_domain='yourdomain.com' function is_account_exist(){ su - zimbra -c "zmprov GetAccount \"${1}\" > /dev/null" echo $? } mailbox="${login}@${email_domain}" check=`is_account_exist "${mailbox}"` if [ $check -eq 0 ]; then # set password echo "update password for exist account" su - zimbra -c "zmprov sp ${mailbox} ${password}"; su - zimbra -c "zmprov ma ${mailbox} zimbraPasswordMustChange FALSE"; else echo "create account and set password" # create account su - zimbra -c "zmprov ca ${mailbox} ${password}"; # set password su - zimbra -c "zmprov sp ${mailbox} ${password}"; su - zimbra -c "zmprov ma ${mailbox} zimbraPasswordMustChange FALSE"; fi exit 0 EOF
chmod +x /opt/zimbra_sync/exec.sh
Создаём сервис systemd и включаем его
cat << 'EOF' > /etc/systemd/system/zimbra_sync.service [Unit] Description=zimbra_sync Requires=network-online.target After=network-online.target [Service] Restart=always RestartSec=3 WorkingDirectory=/opt/zimbra_sync/ ExecStart=/usr/bin/node app.js User=root Group=root [Install] WantedBy=multi-user.target EOF
systemctl daemon-reload
systemctl enable --now zimbra_sync