Zimbra: различия между версиями
Vovan (обсуждение | вклад) (→spf) |
Vovan (обсуждение | вклад) (→Интеграция) |
||
(не показано 25 промежуточных версий этого же участника) | |||
Строка 22: | Строка 22: | ||
* Ввести имя пользователя почты и пароль. | * Ввести имя пользователя почты и пароль. | ||
+ | |||
+ | =bind= | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | echo 'include "/etc/bind/qwe.rty.ru_zones.conf";' >> /etc/bind/named.conf | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/bind/qwe.rty.ru_zones.conf | ||
+ | zone "qwe.rty.ru" { | ||
+ | type master; | ||
+ | file "/etc/bind/zone_qwe.rty.ru"; | ||
+ | }; | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | systemctl stop systemd-resolved | ||
+ | systemctl disable systemd-resolved | ||
= Настройка dkim, spf, dmark= | = Настройка dkim, spf, dmark= | ||
Строка 79: | Строка 159: | ||
v=DMARC1; p=quarantine | v=DMARC1; p=quarantine | ||
+ | |||
+ | ==Итог== | ||
+ | |||
+ | В итоге зона DNS сервера должна иметь такие настройки, которые представлены ниже в формате конфига для сервера bind9 | ||
+ | |||
+ | <pre> | ||
+ | $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 | ||
+ | </pre> | ||
+ | |||
+ | =Фиксы= | ||
+ | |||
+ | ==Переименовать== | ||
+ | |||
+ | 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 | ||
+ | |||
+ | ==Резервное копирование== | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | ==Восстановление из резервных копий== | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | ==Сменить всем пароли== | ||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | =Интеграция= | ||
+ | |||
+ | В этом разделе представлен пример небольшого сервера для интеграции с zimbra. Сервер представляет из себя HTTP сервис, принимающий POST запрос с логином и паролем от внешней системы. | ||
+ | |||
+ | Сервер написан на nodejs, поэтому для его функционирования необходимо поставить пакет nodejs | ||
+ | |||
+ | apt-get install nodejs | ||
+ | |||
+ | Общий смысл работы сервера: | ||
+ | |||
+ | 1. Принять POST запрос от внешней системы | ||
+ | |||
+ | 2. Распознать в запросе корректно присланные логин и пароль | ||
+ | |||
+ | 3. Добавить к логину домен почтового аккаунта (настраивается в файле скрипта /opt/zimbra_sync/exec.sh) | ||
+ | |||
+ | 4. Проверить существования аккаунта в zimbra средствами zmprov | ||
+ | |||
+ | 5. Если аккаунт существует, то поменять ему пароль | ||
+ | |||
+ | 6. Если аккаунт не существует, то создать новый аккаунт и установить для него пароль | ||
+ | |||
+ | Сервер должен запускаться на хосте с 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 | здесь]] | ||
+ | |||
+ | ==Создаём каталог для сервера интеграции== | ||
+ | |||
+ | mkdir /opt/zimbra_sync | ||
+ | |||
+ | ==Создаём файлы сервера на nodejs и скрипт, который будет выполняться при обращении к серверу== | ||
+ | |||
+ | ===Сам сервер=== | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | ===Скрипт=== | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | chmod +x /opt/zimbra_sync/exec.sh | ||
+ | |||
+ | ==Создаём сервис systemd и включаем его== | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | |||
+ | systemctl daemon-reload | ||
+ | |||
+ | systemctl enable --now zimbra_sync | ||
+ | |||
+ | =Установка сертификатов= | ||
+ | |||
+ | https://habr.com/ru/companies/Zextras/articles/341996/ |
Текущая версия на 15:39, 31 октября 2024
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