<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.cless.pro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cless</id>
	<title>Wiki - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.cless.pro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cless"/>
	<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Cless"/>
	<updated>2026-10-22T21:25:08Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.36.2</generator>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=HDD._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B8%D1%82%D1%8C_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BB%D0%B8_%D0%9D%D0%95%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_(%D0%B1%D0%B5%D0%B7_%D0%9E%D0%A1)_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB_ext4_(%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D1%8B%D0%B9,_%D0%BD%D0%B5_LVM)_%D0%B2_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%88%D0%B8%D0%BD%D0%B5_%D1%81%D1%80%D0%B5%D0%B4%D1%8B_ESXi&amp;diff=1940</id>
		<title>HDD. Расширить Системный или НЕсистемный (без ОС) раздел ext4 (обычный, не LVM) в виртуальной машине среды ESXi</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=HDD._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B8%D1%82%D1%8C_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BB%D0%B8_%D0%9D%D0%95%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_(%D0%B1%D0%B5%D0%B7_%D0%9E%D0%A1)_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB_ext4_(%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D1%8B%D0%B9,_%D0%BD%D0%B5_LVM)_%D0%B2_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%88%D0%B8%D0%BD%D0%B5_%D1%81%D1%80%D0%B5%D0%B4%D1%8B_ESXi&amp;diff=1940"/>
		<updated>2026-04-02T10:04:22Z</updated>

		<summary type="html">&lt;p&gt;Cless: Cless переименовал страницу HDD. Расширить НЕсистемный (без ОС) раздел ext4 (обычный, не LVM) в виртуальной машине среды ESXi в HDD. Расширить Системный или НЕсистемный (без ОС) раздел ext4 (обычный, не LVM) в виртуальной машине среды ESXi без оставления перенаправления&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:HDD]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Системный диск =&lt;br /&gt;
РАСШИРЕНИЕ СИСТЕМНОГО РАЗДЕЛА /(root). НЕ LVM. ИСПОЛЬЗУЕМ growfs&lt;br /&gt;
&lt;br /&gt;
// dev/sda1&lt;br /&gt;
&lt;br /&gt;
=== До расширения ===&lt;br /&gt;
root@test1:~# df -h&lt;br /&gt;
&lt;br /&gt;
    Файловая система Размер Использовано  Дост Использовано% Cмонтировано в&lt;br /&gt;
&lt;br /&gt;
    udev               3,9G            0  3,9G            0% /dev&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M         9,1M  788M            2% /run&lt;br /&gt;
&lt;br /&gt;
    /dev/sda1           41G          37G  2,6G           94% /&lt;br /&gt;
&lt;br /&gt;
    tmpfs              3,9G         1,1M  3,9G            1% /dev/shm&lt;br /&gt;
&lt;br /&gt;
    tmpfs              5,0M            0  5,0M            0% /run/lock&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M            0  797M            0% /run/user/1005&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# lsblk&lt;br /&gt;
&lt;br /&gt;
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
&lt;br /&gt;
    sda      8:0    0  150G  0 disk&lt;br /&gt;
&lt;br /&gt;
    └─sda1   8:1    0   41G  0 part /&lt;br /&gt;
&lt;br /&gt;
    sr0     11:0    1  506K  0 rom&lt;br /&gt;
&lt;br /&gt;
=== Расширяем ===&lt;br /&gt;
root@test1:~# growpart /dev/sda 1&lt;br /&gt;
&lt;br /&gt;
    CHANGED: partition=1 start=2048 old: size=85981151 end=85983199 new: size=314570719,end=314572767&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# resize2fs /dev/sda1&lt;br /&gt;
&lt;br /&gt;
    resize2fs 1.44.5 (15-Dec-2018)&lt;br /&gt;
&lt;br /&gt;
    Filesystem at /dev/sda1 is mounted on /; on-line resizing required&lt;br /&gt;
&lt;br /&gt;
    old_desc_blocks = 6, new_desc_blocks = 19&lt;br /&gt;
&lt;br /&gt;
    The filesystem on /dev/sda1 is now 39321339 (4k) blocks long.&lt;br /&gt;
&lt;br /&gt;
=== После расширения ===&lt;br /&gt;
root@test1:~# lsblk&lt;br /&gt;
&lt;br /&gt;
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
&lt;br /&gt;
    sda      8:0    0  150G  0 disk&lt;br /&gt;
&lt;br /&gt;
    └─sda1   8:1    0  150G  0 part /&lt;br /&gt;
&lt;br /&gt;
    sr0     11:0    1  506K  0 rom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# df -h&lt;br /&gt;
&lt;br /&gt;
    Файловая система Размер Использовано  Дост Использовано% Cмонтировано в&lt;br /&gt;
&lt;br /&gt;
    udev               3,9G            0  3,9G            0% /dev&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M         9,1M  788M            2% /run&lt;br /&gt;
&lt;br /&gt;
    /dev/sda1          148G          37G  106G           26% /&lt;br /&gt;
&lt;br /&gt;
    tmpfs              3,9G         1,1M  3,9G            1% /dev/shm&lt;br /&gt;
&lt;br /&gt;
    tmpfs              5,0M            0  5,0M            0% /run/lock&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M            0  797M            0% /run/user/1005&lt;br /&gt;
&lt;br /&gt;
= НЕсистемный диск =&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
https://qastack.ru/server/509468/how-to-extend-an-ext4-partition-and-filesystem&lt;br /&gt;
== Описание ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;В данном случае речь идет о расширении &amp;quot;физического&amp;quot; виртуального диска виртуальной машины в системе ESXI&amp;lt;/blockquote&amp;gt;В ВМ Сentos7 имеем диск 1ГБ и отформатированный на нем раздел /dev/sdb1 размером 1ГБ, смонтированный в /mnt/d1&lt;br /&gt;
&lt;br /&gt;
df -h&lt;br /&gt;
 ...&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/sdb1                        1.0G  4.0M  0.8G   1% /mnt/d1&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Расширение раздела ==&lt;br /&gt;
Выключаем ВМ, расширяем виртуальный диск в ВМ до 4ГБ, включаем ВМ&lt;br /&gt;
&lt;br /&gt;
Запускаем &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выбираем диск&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;select /dev/sdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить  раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 4296&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location 4296 is outside of the device /dev/sdb.&lt;br /&gt;
Расширяем объем раздела&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 4295&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если диск отмонтирован, можно проверить ФС&lt;br /&gt;
&lt;br /&gt;
Монтированный диск система не даст проверить&amp;lt;blockquote&amp;gt;(НЕОБЯЗАТЕЛЬНО, в моем случае удалось расширить раздел не отмонтируя и не проверяя его)&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;e2fsck -f /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем ФС на разделе&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 resize2fs 1.42.9 (28-Dec-2013)&lt;br /&gt;
 Filesystem at /dev/sdb1 is mounted on /mnt/d1; on-line resizing required&lt;br /&gt;
 old_desc_blocks = 1, new_desc_blocks = 1&lt;br /&gt;
 The filesystem on /dev/sdb1 is now 1048320 blocks long.&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/sdb1                        4.0G  4.0M  3.8G   1% /mnt/d1&lt;br /&gt;
 ...&lt;br /&gt;
Проверим наличие и содержимое файла, который был на разделе до его расширения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /mnt/d1/test.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 всем привет&lt;br /&gt;
 ля ля ля&lt;br /&gt;
 ...&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=HDD._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B8%D1%82%D1%8C_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BB%D0%B8_%D0%9D%D0%95%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_(%D0%B1%D0%B5%D0%B7_%D0%9E%D0%A1)_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB_ext4_(%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D1%8B%D0%B9,_%D0%BD%D0%B5_LVM)_%D0%B2_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%88%D0%B8%D0%BD%D0%B5_%D1%81%D1%80%D0%B5%D0%B4%D1%8B_ESXi&amp;diff=1939</id>
		<title>HDD. Расширить Системный или НЕсистемный (без ОС) раздел ext4 (обычный, не LVM) в виртуальной машине среды ESXi</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=HDD._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B8%D1%82%D1%8C_%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BB%D0%B8_%D0%9D%D0%95%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BD%D1%8B%D0%B9_(%D0%B1%D0%B5%D0%B7_%D0%9E%D0%A1)_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB_ext4_(%D0%BE%D0%B1%D1%8B%D1%87%D0%BD%D1%8B%D0%B9,_%D0%BD%D0%B5_LVM)_%D0%B2_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%88%D0%B8%D0%BD%D0%B5_%D1%81%D1%80%D0%B5%D0%B4%D1%8B_ESXi&amp;diff=1939"/>
		<updated>2026-04-02T10:03:48Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:HDD]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Системный диск =&lt;br /&gt;
РАСШИРЕНИЕ СИСТЕМНОГО РАЗДЕЛА /(root). НЕ LVM. ИСПОЛЬЗУЕМ growfs&lt;br /&gt;
&lt;br /&gt;
// dev/sda1&lt;br /&gt;
&lt;br /&gt;
=== До расширения ===&lt;br /&gt;
root@test1:~# df -h&lt;br /&gt;
&lt;br /&gt;
    Файловая система Размер Использовано  Дост Использовано% Cмонтировано в&lt;br /&gt;
&lt;br /&gt;
    udev               3,9G            0  3,9G            0% /dev&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M         9,1M  788M            2% /run&lt;br /&gt;
&lt;br /&gt;
    /dev/sda1           41G          37G  2,6G           94% /&lt;br /&gt;
&lt;br /&gt;
    tmpfs              3,9G         1,1M  3,9G            1% /dev/shm&lt;br /&gt;
&lt;br /&gt;
    tmpfs              5,0M            0  5,0M            0% /run/lock&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M            0  797M            0% /run/user/1005&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# lsblk&lt;br /&gt;
&lt;br /&gt;
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
&lt;br /&gt;
    sda      8:0    0  150G  0 disk&lt;br /&gt;
&lt;br /&gt;
    └─sda1   8:1    0   41G  0 part /&lt;br /&gt;
&lt;br /&gt;
    sr0     11:0    1  506K  0 rom&lt;br /&gt;
&lt;br /&gt;
=== Расширяем ===&lt;br /&gt;
root@test1:~# growpart /dev/sda 1&lt;br /&gt;
&lt;br /&gt;
    CHANGED: partition=1 start=2048 old: size=85981151 end=85983199 new: size=314570719,end=314572767&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# resize2fs /dev/sda1&lt;br /&gt;
&lt;br /&gt;
    resize2fs 1.44.5 (15-Dec-2018)&lt;br /&gt;
&lt;br /&gt;
    Filesystem at /dev/sda1 is mounted on /; on-line resizing required&lt;br /&gt;
&lt;br /&gt;
    old_desc_blocks = 6, new_desc_blocks = 19&lt;br /&gt;
&lt;br /&gt;
    The filesystem on /dev/sda1 is now 39321339 (4k) blocks long.&lt;br /&gt;
&lt;br /&gt;
=== После расширения ===&lt;br /&gt;
root@test1:~# lsblk&lt;br /&gt;
&lt;br /&gt;
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT&lt;br /&gt;
&lt;br /&gt;
    sda      8:0    0  150G  0 disk&lt;br /&gt;
&lt;br /&gt;
    └─sda1   8:1    0  150G  0 part /&lt;br /&gt;
&lt;br /&gt;
    sr0     11:0    1  506K  0 rom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
root@test1:~# df -h&lt;br /&gt;
&lt;br /&gt;
    Файловая система Размер Использовано  Дост Использовано% Cмонтировано в&lt;br /&gt;
&lt;br /&gt;
    udev               3,9G            0  3,9G            0% /dev&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M         9,1M  788M            2% /run&lt;br /&gt;
&lt;br /&gt;
    /dev/sda1          148G          37G  106G           26% /&lt;br /&gt;
&lt;br /&gt;
    tmpfs              3,9G         1,1M  3,9G            1% /dev/shm&lt;br /&gt;
&lt;br /&gt;
    tmpfs              5,0M            0  5,0M            0% /run/lock&lt;br /&gt;
&lt;br /&gt;
    tmpfs              797M            0  797M            0% /run/user/1005&lt;br /&gt;
&lt;br /&gt;
= НЕсистемный диск =&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
https://qastack.ru/server/509468/how-to-extend-an-ext4-partition-and-filesystem&lt;br /&gt;
== Описание ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;В данном случае речь идет о расширении &amp;quot;физического&amp;quot; виртуального диска виртуальной машины в системе ESXI&amp;lt;/blockquote&amp;gt;В ВМ Сentos7 имеем диск 1ГБ и отформатированный на нем раздел /dev/sdb1 размером 1ГБ, смонтированный в /mnt/d1&lt;br /&gt;
&lt;br /&gt;
df -h&lt;br /&gt;
 ...&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/sdb1                        1.0G  4.0M  0.8G   1% /mnt/d1&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Расширение раздела ==&lt;br /&gt;
Выключаем ВМ, расширяем виртуальный диск в ВМ до 4ГБ, включаем ВМ&lt;br /&gt;
&lt;br /&gt;
Запускаем &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выбираем диск&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;select /dev/sdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить  раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 4296&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location 4296 is outside of the device /dev/sdb.&lt;br /&gt;
Расширяем объем раздела&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 4295&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если диск отмонтирован, можно проверить ФС&lt;br /&gt;
&lt;br /&gt;
Монтированный диск система не даст проверить&amp;lt;blockquote&amp;gt;(НЕОБЯЗАТЕЛЬНО, в моем случае удалось расширить раздел не отмонтируя и не проверяя его)&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;e2fsck -f /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем ФС на разделе&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 resize2fs 1.42.9 (28-Dec-2013)&lt;br /&gt;
 Filesystem at /dev/sdb1 is mounted on /mnt/d1; on-line resizing required&lt;br /&gt;
 old_desc_blocks = 1, new_desc_blocks = 1&lt;br /&gt;
 The filesystem on /dev/sdb1 is now 1048320 blocks long.&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/sdb1                        4.0G  4.0M  3.8G   1% /mnt/d1&lt;br /&gt;
 ...&lt;br /&gt;
Проверим наличие и содержимое файла, который был на разделе до его расширения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /mnt/d1/test.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 всем привет&lt;br /&gt;
 ля ля ля&lt;br /&gt;
 ...&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mikrotik._NAT_Loopback_(NAT_Hairpin)&amp;diff=1938</id>
		<title>Mikrotik. NAT Loopback (NAT Hairpin)</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mikrotik._NAT_Loopback_(NAT_Hairpin)&amp;diff=1938"/>
		<updated>2026-03-19T17:00:39Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание ==&lt;br /&gt;
Необходимо с ЛОКАЛЬНОЙ машины достучаться через ВНЕШНИЙ интерфейс (с помощью проброса порта через DST-NAT) обратно на какую-нибудь локальную машину.&lt;br /&gt;
&lt;br /&gt;
== Настройка ==&lt;br /&gt;
&lt;br /&gt;
=== Способ 1 ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Пример 1'''&lt;br /&gt;
&lt;br /&gt;
В следующем примере мы пройдем с локальной машины из подсети 9 на локальный сервер 192.168.9.12 через маршрутизатор 192.168.9.8 обратно в локалку по порту 22026/UDP на машину 192.168.9.12&lt;br /&gt;
&lt;br /&gt;
'''109.106.130.82, 77.241.254.254''' - адреса двух внешних интерфейсов&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat add chain=dstnat action=dst-nat src-address=&amp;quot;192.168.9.0/24&amp;quot; dst-address=109.106.130.82 protocol=udp dst-port=22026 \&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;in-interface=&amp;quot;$lan&amp;quot; to-addresses=&amp;quot;192.168.9.12&amp;quot; ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat add chain=dstnat action=dst-nat src-address=&amp;quot;192.168.9.0/24&amp;quot; dst-address=77.241.254.254 protocol=udp dst-port=22026 \&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;in-interface=&amp;quot;$lan&amp;quot; to-addresses=&amp;quot;192.168.9.12&amp;quot; ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat add chain=srcnat action=src-nat out-interface=&amp;quot;$lan&amp;quot; dst-address=&amp;quot;192.168.9.12&amp;quot; src-address=&amp;quot;$net&amp;quot; protocol=udp \&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dst-port=22026 to-addresses=&amp;quot;192.168.9.8&amp;quot; ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat add chain=srcnat action=src-nat out-interface=&amp;quot;$lan&amp;quot; dst-address=&amp;quot;192.168.9.12&amp;quot; src-address=&amp;quot;$net&amp;quot; protocol=udp \&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dst-port=22026 to-addresses=&amp;quot;192.168.9.8&amp;quot; ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Пример 2'''&lt;br /&gt;
&lt;br /&gt;
178.210.50.111 - внешний интерфейс&lt;br /&gt;
&lt;br /&gt;
192.168.8.0/24 - локальная сеть, из которой инициируем подключение&lt;br /&gt;
&lt;br /&gt;
192.168.8.1 - адрес маршрутизатора&lt;br /&gt;
&lt;br /&gt;
10.1.8.203 - адрес назначения (в другой подсети того же контура)&lt;br /&gt;
&lt;br /&gt;
64999 - порт назначения&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ip firewall nat add action=dst-nat chain=dstnat dst-address=178.210.50.111 dst-port=64999 in-interface=bridge-local protocol=tcp src-address=192.168.8.0/24 to-addresses=10.1.8.203&lt;br /&gt;
&lt;br /&gt;
/ip firewall nat add chain=dstnat action=dst-nat src-address=&amp;quot;192.168.8.0/24&amp;quot; dst-address=178.210.50.111 protocol=tcp dst-port=64999 in-interface=&amp;quot;bridge-local&amp;quot; to-addresses=&amp;quot;10.1.8.203&amp;quot; ;&lt;br /&gt;
&lt;br /&gt;
/ip firewall nat add chain=srcnat action=src-nat out-interface=&amp;quot;bridge-local&amp;quot; dst-address=&amp;quot;10.1.8.203&amp;quot; src-address=&amp;quot;192.168.8.0/24&amp;quot; protocol=tcp dst-port=64999 to-addresses=&amp;quot;192.168.8.1&amp;quot; ;&lt;br /&gt;
&lt;br /&gt;
=== Способ 2 (ПРОВЕРИТЬ!) ===&lt;br /&gt;
Первым этапом нужно промаркировать (''new-packet-mark=nat-loopback'') те пакеты, которые пришли на внешний адрес маршрутизатора (''dst-address=203.0.113.5'') из локальной сети (''in-interface=LAN'') и являются новыми соединениями (''connection-state=new'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall mangle&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add chain=prerouting comment=&amp;quot;NAT Loopback detect&amp;quot; dst-address=203.0.113.5 in-interface=LAN connection-state=new action=mark-packet new-packet-mark=nat-loopback passthrough=yes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь нужно написать обработчик пакета, который сработает после того как пакет пройдет маршрутизацию и будет на выходе в локальную сеть, в таблице mangle необходимо заменить адрес источника на адрес маршрутизатора.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add chain=srcnat packet-mark=nat-loopback action=masquerade comment=&amp;quot;NAT Loopback replace address&amp;quot;&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Таким образом, появляется возможность писать правила проброса портов в обычном виде по одному на порт или несколько портов. Они будут работать как и в классическом сценарии (при поступлении извне), так и в случае поступления запросов из локальной сети.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip firewall nat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add chain=dstnat dst-address=203.0.113.5 protocol=tcp dst-port=80,443 action=dst-nat to-addresses=192.168.88.5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add chain=dstnat dst-address=203.0.113.5 protocol=tcp dst-port=8080 action=dst-nat to-addresses=192.168.88.20&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add chain=dstnat dst-address=203.0.113.5 protocol=tcp dst-port=25,143 action=dst-nat to-addresses=192.168.88.100&amp;lt;/code&amp;gt;&lt;br /&gt;
[[Категория:Mikrotik]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1937</id>
		<title>Mikrotik. RouterOS 7. Автоматическое переключение между двумя провайдерами. Балансировка входящего трафика</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1937"/>
		<updated>2026-03-04T16:27:11Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Переключалка провайдеров + мониторинг провайдеров + входящие соединения input в микротик или проброс dst-nat с внешки до локального ip-адреса в локальную сеть через любого из 2-х провайдеров =&lt;br /&gt;
&lt;br /&gt;
== Переключалка+балансировка ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://mikrotik-training.ru/files/MUoM/2021/kuznetsov.pdf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
Имеется 2 провайдера, у обоих есть статический внешний IP-адрес (Также инструкция подойдет для 3-х или более провайдеров с соответствующими дополнительными аналогичными настройками).&lt;br /&gt;
&lt;br /&gt;
* ether3-wan1_ttk_NEW - интерфейс ISP1&lt;br /&gt;
* ether4-wan2_beeline_NEW - интерфейс ISP2&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.1 - шлюз ISP1&lt;br /&gt;
* 194.186.163.88 - шлюз ISP2&lt;br /&gt;
* 77.88.8.8, 208.67.222.222 - внешние публичные 24/7 доступные IP&lt;br /&gt;
&lt;br /&gt;
Необходимо:&lt;br /&gt;
&lt;br /&gt;
* ПРИ ОТКЛЮЧЕНИИ ОСНОВНОГО ПРОВАЙДЕРА ШЛЮЗ ПО-УМОЛЧАНИЮ ПЕРЕКЛЮЧАЕТСЯ НА РЕЗЕРВНОГО&lt;br /&gt;
* чтобы сам микрот отвечал (например на ICMP запрос на внешний провайдерский IP-адрес) во внешку по тому провайдеру, по которому запрос пришел&lt;br /&gt;
* чтобы при подключении с внешки до IP-адреса любого из 2-х провайдеров, мы могли подключиться до внутреннего сервера через проброс dst-nst&lt;br /&gt;
&lt;br /&gt;
Создаем группу WAN интерфейсов&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/interface list&lt;br /&gt;
add name=WAN&lt;br /&gt;
&lt;br /&gt;
/interface list member&lt;br /&gt;
add interface=ether3-wan1_ttk_NEW list=WAN&lt;br /&gt;
add interface=ether4-wan2_beeline_NEW list=WAN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;SRC-NAT на группе WAN интерфейсов&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/ip firewall nat add action=masquerade chain=srcnat comment=NAT_masquerade_wan-all out-interface-list=WAN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 1. 2 ISP ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/routing table&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/ip route&lt;br /&gt;
add comment=gw1 distance=201 gateway=213.129.118.1&lt;br /&gt;
add comment=gw2 distance=202 gateway=194.186.163.88&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=213.129.118.1 routing-table=route-table-gw1&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=194.186.163.88 routing-table=route-table-gw2&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=213.129.118.1 scope=11&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=194.186.163.88 scope=11&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!WAN new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!WAN new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 2. 3 ISP ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/routing table&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
add disabled=no fib name=route-table-gw3&lt;br /&gt;
&lt;br /&gt;
/ip route&lt;br /&gt;
add comment=gw1 distance=201 gateway=188.235.62.254&lt;br /&gt;
add comment=gw2 distance=202 gateway=ether4-wan2_pppoe-client_intercon&lt;br /&gt;
&lt;br /&gt;
add comment=gw3 distance=203 gateway=172.24.199.1&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=188.235.62.254 routing-table=route-table-gw1&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=ether4-wan2_pppoe-client_intercon routing-table=route-table-gw2&lt;br /&gt;
add comment=gw3_via_custom_route_table gateway=172.24.199.1 routing-table=route-table-gw3&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=188.235.62.254 scope=11&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=ether4-wan2_pppoe-client_intercon scope=11&lt;br /&gt;
add comment=gw3_via_pub3_chk dst-address=77.88.8.3/32 gateway=172.24.199.1 scope=11&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub3_gw3_chk distance=103 gateway=77.88.8.3 target-scope=11&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!-WAN- new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!-WAN- new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp3 in-interface-list=!-WAN- new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp3 new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Готово&lt;br /&gt;
&lt;br /&gt;
Пробуем пинговать с внешки IP-адреса провайдеров&lt;br /&gt;
&lt;br /&gt;
Каждый должен пинговаться&lt;br /&gt;
&lt;br /&gt;
Пробуем ходить с внешки на IP-адреса провайдеров по порту 80,&lt;br /&gt;
&lt;br /&gt;
По каждому провайдеру проходим до веб-сервера 192.168.1.50&lt;br /&gt;
&lt;br /&gt;
ОТКЛЮЧАЕМ ОСНОВНОГО ПРОВАЙДЕРА - ТРАФИК ИДЕТ ЧЕРЕЗ ШЛЮЗ РЕЗЕРВНОГО&lt;br /&gt;
&lt;br /&gt;
== Мониторинг провайдеров ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://vasilevkirill.ru/routeros-check-internet-v7/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.208 - публичный адрес провайдера 1 на нашем микроте&lt;br /&gt;
* 194.186.163.89 - публичный адрес провайдера 2 на нашем микроте&lt;br /&gt;
* 213.129.118.1 - основной шлюз isp1&lt;br /&gt;
* 194.186.163.88 - основной шлюз isp2&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp1:&lt;br /&gt;
&lt;br /&gt;
* 176.99.13.13&lt;br /&gt;
* 31.177.85.186&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp2:&lt;br /&gt;
&lt;br /&gt;
* 93.158.134.1&lt;br /&gt;
* 5.101.159.11&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Создадим таблицы и правила для прохождения трафика до спец IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ПЕРВЫЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp1 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=176.99.13.13/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=31.177.85.186/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=213.129.118.1 routing-table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ВТОРОЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp2 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=93.158.134.1/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=5.101.159.11/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=194.186.163.88 routing-table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Создадим правила netwatch для проверки пингами спец внешних IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
/tool netwatch&lt;br /&gt;
add comment=ns1.reg.ru disabled=no down-script=&amp;quot;&amp;quot; host=176.99.13.13 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk1 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns9.nic.ru disabled=no down-script=&amp;quot;&amp;quot; host=31.177.85.186 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk2 port=53 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns1.beget.com disabled=no down-script=&amp;quot;&amp;quot; host=5.101.159.11 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk2 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns2.yandex.ru disabled=no down-script=&amp;quot;&amp;quot; host=93.158.134.1 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk1 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system script add name=monitor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system script edit monitor source&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Monitor ros7 v.2026-02-14_isp2&lt;br /&gt;
# by Cless&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
:local NetWatchIsp1CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp1&amp;quot; disabled=no status=up];&lt;br /&gt;
:local NetWatchIsp2CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp2&amp;quot; disabled=no status=up];&lt;br /&gt;
&lt;br /&gt;
#ISP1 CHK&lt;br /&gt;
:if (($NetWatchIsp1CountUp &amp;gt; 0)) do={&lt;br /&gt;
    :global isp1Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
} else={&lt;br /&gt;
        :global isp1Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
#ISP2 CHK&lt;br /&gt;
:if (($NetWatchIsp2CountUp &amp;gt; 0)) do={&lt;br /&gt;
    :global isp2Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
} else={&lt;br /&gt;
        :global isp2Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
#ACTIVE GW CHK&lt;br /&gt;
:local gw1active [ip route get value-name=active [find where comment~&amp;quot;pub1_gw1_chk&amp;quot;]] ;&lt;br /&gt;
:local gw2active [ip route get value-name=active [find where comment~&amp;quot;pub2_gw2_chk&amp;quot;]] ;&lt;br /&gt;
&lt;br /&gt;
:if (($gw1active=true) &amp;amp;&amp;amp; ($gw2active!=true)) do={&lt;br /&gt;
    :global gwActive &amp;quot;gw1&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
:if (($gw1active!=true) &amp;amp;&amp;amp; ($gw2active=true)) do={&lt;br /&gt;
    :global gwActive &amp;quot;gw2&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
# DEBUG&lt;br /&gt;
:global gwActive;&lt;br /&gt;
:global isp1Status;&lt;br /&gt;
:global isp2Status;&lt;br /&gt;
:put &amp;quot;gwActive $gwActive ; isp1Status $isp1Status ; isp2Status $isp2Status&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system scheduler&lt;br /&gt;
add disabled=yes interval=30s name=chk on-event=chk policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
add interval=1m name=monitor on-event=monitor policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Готово!&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system/script/environment/print&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
    2  gwActive        gw1&lt;br /&gt;
    3  isp1Status      OK&lt;br /&gt;
    4  isp2Status      OK&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== На Zabbix ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install python3-librouteros&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vim ./mikrotikVarGet.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import json&lt;br /&gt;
from librouteros import connect&lt;br /&gt;
&lt;br /&gt;
# ARGs check&lt;br /&gt;
if len(sys.argv) &amp;lt; 5:&lt;br /&gt;
    print(&amp;quot;Usage: script.py &amp;lt;IP&amp;gt; &amp;lt;username&amp;gt; &amp;lt;password&amp;gt; &amp;lt;variable_name&amp;gt;&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# Connection parameters&lt;br /&gt;
IP = sys.argv[1]&lt;br /&gt;
USERNAME = sys.argv[2]&lt;br /&gt;
PASSWORD = sys.argv[3]&lt;br /&gt;
mikrotikApiVarName = sys.argv[4]&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    api = connect(&lt;br /&gt;
        host=IP,&lt;br /&gt;
        username=USERNAME,&lt;br /&gt;
        password=PASSWORD&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    all_vars = list(api('/system/script/environment/print'))&lt;br /&gt;
    for i, var in enumerate(all_vars):&lt;br /&gt;
        if var.get('name') == mikrotikApiVarName:&lt;br /&gt;
            print(var.get('value', ''))&lt;br /&gt;
            sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    print(f&amp;quot;DEBUG: Error: {e}&amp;quot;, file=sys.stderr)&lt;br /&gt;
    print(&amp;quot;&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Далее на Zabbix проверяем значение переменных Item и создаем триггеры.&lt;br /&gt;
&lt;br /&gt;
Например:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    mikrotikVarGet.py[&amp;quot;{HOST.CONN}&amp;quot;,&amp;quot;uplit&amp;quot;,&amp;quot;Pass#&amp;quot;,&amp;quot;isp1Status&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1936</id>
		<title>Mikrotik. RouterOS 7. Автоматическое переключение между двумя провайдерами. Балансировка входящего трафика</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1936"/>
		<updated>2026-03-03T18:21:49Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Переключалка провайдеров + мониторинг провайдеров + входящие соединения input в микротик или проброс dst-nat с внешки до локального ip-адреса в локальную сеть через любого из 2-х провайдеров =&lt;br /&gt;
&lt;br /&gt;
== Переключалка+балансировка ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://mikrotik-training.ru/files/MUoM/2021/kuznetsov.pdf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
Имеется 2 провайдера, у обоих есть статический внешний IP-адрес (Также инструкция подойдет для 3-х или более провайдеров с соответствующими дополнительными аналогичными настройками).&lt;br /&gt;
&lt;br /&gt;
* ether3-wan1_ttk_NEW - интерфейс ISP1&lt;br /&gt;
* ether4-wan2_beeline_NEW - интерфейс ISP2&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.1 - шлюз ISP1&lt;br /&gt;
* 194.186.163.88 - шлюз ISP2&lt;br /&gt;
* 77.88.8.8, 208.67.222.222 - внешние публичные 24/7 доступные IP&lt;br /&gt;
&lt;br /&gt;
Необходимо:&lt;br /&gt;
&lt;br /&gt;
* ПРИ ОТКЛЮЧЕНИИ ОСНОВНОГО ПРОВАЙДЕРА ШЛЮЗ ПО-УМОЛЧАНИЮ ПЕРЕКЛЮЧАЕТСЯ НА РЕЗЕРВНОГО&lt;br /&gt;
* чтобы сам микрот отвечал (например на ICMP запрос на внешний провайдерский IP-адрес) во внешку по тому провайдеру, по которому запрос пришел&lt;br /&gt;
* чтобы при подключении с внешки до IP-адреса любого из 2-х провайдеров, мы могли подключиться до внутреннего сервера через проброс dst-nst&lt;br /&gt;
&lt;br /&gt;
Создаем группу WAN интерфейсов&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/interface list&lt;br /&gt;
add name=WAN&lt;br /&gt;
&lt;br /&gt;
/interface list member&lt;br /&gt;
add interface=ether3-wan1_ttk_NEW list=WAN&lt;br /&gt;
add interface=ether4-wan2_beeline_NEW list=WAN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;SRC-NAT на группе WAN интерфейсов&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/ip firewall nat add action=masquerade chain=srcnat comment=NAT_masquerade_wan-all out-interface-list=WAN&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 1. 2 ISP ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/routing table&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/ip route&lt;br /&gt;
add comment=gw1 distance=201 gateway=213.129.118.1&lt;br /&gt;
add comment=gw2 distance=202 gateway=194.186.163.88&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=213.129.118.1 routing-table=route-table-gw1&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=194.186.163.88 routing-table=route-table-gw2&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=213.129.118.1 scope=11&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=194.186.163.88 scope=11&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!WAN new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!WAN new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 2. 3 ISP ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/routing table&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
add disabled=no fib name=route-table-gw3&lt;br /&gt;
&lt;br /&gt;
/ip route&lt;br /&gt;
add comment=gw1 distance=201 gateway=188.235.62.254&lt;br /&gt;
add comment=gw2 distance=202 gateway=ether4-wan2_pppoe-client_intercon&lt;br /&gt;
&lt;br /&gt;
add comment=gw3 distance=203 gateway=172.24.199.1&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=188.235.62.254 routing-table=route-table-gw1&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=ether4-wan2_pppoe-client_intercon routing-table=route-table-gw2&lt;br /&gt;
add comment=gw3_via_custom_route_table gateway=172.24.199.1 routing-table=route-table-gw3&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=188.235.62.254 scope=11&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=ether4-wan2_pppoe-client_intercon scope=11&lt;br /&gt;
add comment=gw3_via_pub3_chk dst-address=77.88.8.3/32 gateway=172.24.199.1 scope=11&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
add check-gateway=ping comment=pub3_gw3_chk distance=103 gateway=77.88.8.3 target-scope=11&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!-WAN- new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!-WAN- new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp3 in-interface-list=!-WAN- new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp3 new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Готово&lt;br /&gt;
&lt;br /&gt;
Пробуем пинговать с внешки IP-адреса провайдеров&lt;br /&gt;
&lt;br /&gt;
Каждый должен пинговаться&lt;br /&gt;
&lt;br /&gt;
Пробуем ходить с внешки на IP-адреса провайдеров по порту 80,&lt;br /&gt;
&lt;br /&gt;
По каждому провайдеру проходим до веб-сервера 192.168.1.50&lt;br /&gt;
&lt;br /&gt;
ОТКЛЮЧАЕМ ОСНОВНОГО ПРОВАЙДЕРА - ТРАФИК ИДЕТ ЧЕРЕЗ ШЛЮЗ РЕЗЕРВНОГО&lt;br /&gt;
&lt;br /&gt;
== Мониторинг провайдеров ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://vasilevkirill.ru/routeros-check-internet-v7/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.208 - публичный адрес провайдера 1 на нашем микроте&lt;br /&gt;
* 194.186.163.89 - публичный адрес провайдера 2 на нашем микроте&lt;br /&gt;
* 213.129.118.1 - основной шлюз isp1&lt;br /&gt;
* 194.186.163.88 - основной шлюз isp2&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp1:&lt;br /&gt;
&lt;br /&gt;
* 176.99.13.13&lt;br /&gt;
* 31.177.85.186&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp2:&lt;br /&gt;
&lt;br /&gt;
* 93.158.134.1&lt;br /&gt;
* 5.101.159.11&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Создадим таблицы и правила для прохождения трафика до спец IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ПЕРВЫЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp1 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=176.99.13.13/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=31.177.85.186/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=213.129.118.1 routing-table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ВТОРОЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp2 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=93.158.134.1/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/routing/rule add dst-address=5.101.159.11/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=194.186.163.88 routing-table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Создадим правила netwatch для проверки пингами спец внешних IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
/tool netwatch&lt;br /&gt;
add comment=ns1.reg.ru disabled=no down-script=&amp;quot;&amp;quot; host=176.99.13.13 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk1 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns9.nic.ru disabled=no down-script=&amp;quot;&amp;quot; host=31.177.85.186 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk2 port=53 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns1.beget.com disabled=no down-script=&amp;quot;&amp;quot; host=5.101.159.11 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk2 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns2.yandex.ru disabled=no down-script=&amp;quot;&amp;quot; host=93.158.134.1 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk1 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/tool netwatch&lt;br /&gt;
add comment=ns1.reg.ru disabled=no down-script=&amp;quot;&amp;quot; host=176.99.13.13 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk1 src-address=80.82.33.162 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns9.nic.ru disabled=no down-script=&amp;quot;&amp;quot; host=31.177.85.186 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk2 port=53 src-address=80.82.33.162 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns1.beget.com disabled=no down-script=&amp;quot;&amp;quot; host=5.101.159.11 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk2 port=53 src-address=178.210.43.248 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
add comment=ns2.yandex.ru disabled=no down-script=&amp;quot;&amp;quot; host=93.158.134.1 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk1 port=53 src-address=178.210.43.248 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system script add name=monitor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system script edit monitor source&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Monitor ros7 v.2026-02-14_isp2&lt;br /&gt;
# by Cless&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
:local NetWatchIsp1CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp1&amp;quot; disabled=no status=up];&lt;br /&gt;
:local NetWatchIsp2CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp2&amp;quot; disabled=no status=up];&lt;br /&gt;
&lt;br /&gt;
#ISP1 CHK&lt;br /&gt;
:if (($NetWatchIsp1CountUp &amp;gt; 0)) do={&lt;br /&gt;
    :global isp1Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
} else={&lt;br /&gt;
        :global isp1Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
#ISP2 CHK&lt;br /&gt;
:if (($NetWatchIsp2CountUp &amp;gt; 0)) do={&lt;br /&gt;
    :global isp2Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
} else={&lt;br /&gt;
        :global isp2Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
#ACTIVE GW CHK&lt;br /&gt;
:local gw1active [ip route get value-name=active [find where comment~&amp;quot;pub1_gw1_chk&amp;quot;]] ;&lt;br /&gt;
:local gw2active [ip route get value-name=active [find where comment~&amp;quot;pub2_gw2_chk&amp;quot;]] ;&lt;br /&gt;
&lt;br /&gt;
:if (($gw1active=true) &amp;amp;&amp;amp; ($gw2active!=true)) do={&lt;br /&gt;
    :global gwActive &amp;quot;gw1&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
:if (($gw1active!=true) &amp;amp;&amp;amp; ($gw2active=true)) do={&lt;br /&gt;
    :global gwActive &amp;quot;gw2&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
# DEBUG&lt;br /&gt;
:global gwActive;&lt;br /&gt;
:global isp1Status;&lt;br /&gt;
:global isp2Status;&lt;br /&gt;
:put &amp;quot;gwActive $gwActive ; isp1Status $isp1Status ; isp2Status $isp2Status&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system scheduler&lt;br /&gt;
add disabled=yes interval=30s name=chk on-event=chk policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
add interval=1m name=monitor on-event=monitor policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Готово!&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/system/script/environment/print&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
    2  gwActive        gw1&lt;br /&gt;
    3  isp1Status      OK&lt;br /&gt;
    4  isp2Status      OK&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== На Zabbix ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install python3-librouteros&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
vim ./mikrotikVarGet.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import json&lt;br /&gt;
from librouteros import connect&lt;br /&gt;
&lt;br /&gt;
# ARGs check&lt;br /&gt;
if len(sys.argv) &amp;lt; 5:&lt;br /&gt;
    print(&amp;quot;Usage: script.py &amp;lt;IP&amp;gt; &amp;lt;username&amp;gt; &amp;lt;password&amp;gt; &amp;lt;variable_name&amp;gt;&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# Connection parameters&lt;br /&gt;
IP = sys.argv[1]&lt;br /&gt;
USERNAME = sys.argv[2]&lt;br /&gt;
PASSWORD = sys.argv[3]&lt;br /&gt;
mikrotikApiVarName = sys.argv[4]&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    api = connect(&lt;br /&gt;
        host=IP,&lt;br /&gt;
        username=USERNAME,&lt;br /&gt;
        password=PASSWORD&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    all_vars = list(api('/system/script/environment/print'))&lt;br /&gt;
    for i, var in enumerate(all_vars):&lt;br /&gt;
        if var.get('name') == mikrotikApiVarName:&lt;br /&gt;
            print(var.get('value', ''))&lt;br /&gt;
            sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
except Exception as e:&lt;br /&gt;
    print(f&amp;quot;DEBUG: Error: {e}&amp;quot;, file=sys.stderr)&lt;br /&gt;
    print(&amp;quot;&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Далее на Zabbix проверяем значение переменных Item и создаем триггеры.&lt;br /&gt;
&lt;br /&gt;
Например:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
    mikrotikVarGet.py[&amp;quot;{HOST.CONN}&amp;quot;,&amp;quot;uplit&amp;quot;,&amp;quot;Pass#&amp;quot;,&amp;quot;isp1Status&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1935</id>
		<title>Mikrotik. RouterOS 7. Автоматическое переключение между двумя провайдерами. Балансировка входящего трафика</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mikrotik._RouterOS_7._%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B5%D0%B6%D0%B4%D1%83_%D0%B4%D0%B2%D1%83%D0%BC%D1%8F_%D0%BF%D1%80%D0%BE%D0%B2%D0%B0%D0%B9%D0%B4%D0%B5%D1%80%D0%B0%D0%BC%D0%B8._%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE_%D1%82%D1%80%D0%B0%D1%84%D0%B8%D0%BA%D0%B0&amp;diff=1935"/>
		<updated>2026-03-03T18:13:19Z</updated>

		<summary type="html">&lt;p&gt;Cless: Новая страница: «= Переключалка провайдеров + мониторинг провайдеров + входящие соединения input в микротик...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Переключалка провайдеров + мониторинг провайдеров + входящие соединения input в микротик или проброс dst-nat с внешки до локального ip-адреса в локальную сеть через любого из 2-х провайдеров =&lt;br /&gt;
&lt;br /&gt;
== Переключалка+балансировка ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://mikrotik-training.ru/files/MUoM/2021/kuznetsov.pdf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
Имеется 2 провайдера, у обоих есть статический внешний IP-адрес (Также инструкция подойдет для 3-х или более провайдеров с соответствующими дополнительными аналогичными настройками).&lt;br /&gt;
&lt;br /&gt;
* ether3-wan1_ttk_NEW - интерфейс ISP1&lt;br /&gt;
* ether4-wan2_beeline_NEW - интерфейс ISP2&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.1 - шлюз ISP1&lt;br /&gt;
* 194.186.163.88 - шлюз ISP2&lt;br /&gt;
* 77.88.8.8, 208.67.222.222 - внешние публичные 24/7 доступные IP&lt;br /&gt;
&lt;br /&gt;
Необходимо:&lt;br /&gt;
&lt;br /&gt;
* ПРИ ОТКЛЮЧЕНИИ ОСНОВНОГО ПРОВАЙДЕРА ШЛЮЗ ПО-УМОЛЧАНИЮ ПЕРЕКЛЮЧАЕТСЯ НА РЕЗЕРВНОГО&lt;br /&gt;
* чтобы сам микрот отвечал (например на ICMP запрос на внешний провайдерский IP-адрес) во внешку по тому провайдеру, по которому запрос пришел&lt;br /&gt;
* чтобы при подключении с внешки до IP-адреса любого из 2-х провайдеров, мы могли подключиться до внутреннего сервера через проброс dst-nst&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Создаем группу WAN интерфейсов&lt;br /&gt;
&lt;br /&gt;
/interface list&lt;br /&gt;
&lt;br /&gt;
add name=WAN&lt;br /&gt;
&lt;br /&gt;
/interface list member&lt;br /&gt;
&lt;br /&gt;
add interface=ether3-wan1_ttk_NEW list=WAN&lt;br /&gt;
&lt;br /&gt;
add interface=ether4-wan2_beeline_NEW list=WAN&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
SRC-NAT на группе WAN интерфейсов&lt;br /&gt;
&lt;br /&gt;
/ip firewall nat add action=masquerade chain=srcnat comment=NAT_masquerade_wan-all out-interface-list=WAN&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 1. 2 ISP ===&lt;br /&gt;
/routing table&lt;br /&gt;
&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ip route&lt;br /&gt;
&lt;br /&gt;
add comment=gw1 distance=201 gateway=213.129.118.1&lt;br /&gt;
&lt;br /&gt;
add comment=gw2 distance=202 gateway=194.186.163.88&lt;br /&gt;
&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=213.129.118.1 routing-table=route-table-gw1&lt;br /&gt;
&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=194.186.163.88 routing-table=route-table-gw2&lt;br /&gt;
&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=213.129.118.1 scope=11&lt;br /&gt;
&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=194.186.163.88 scope=11&lt;br /&gt;
&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!WAN new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!WAN new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
=== ВАРИАНТ 2. 3 ISP ===&lt;br /&gt;
/routing table&lt;br /&gt;
&lt;br /&gt;
add disabled=no fib name=route-table-gw1&lt;br /&gt;
&lt;br /&gt;
add disabled=no fib name=route-table-gw2&lt;br /&gt;
&lt;br /&gt;
add disabled=no fib name=route-table-gw3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ip route&lt;br /&gt;
&lt;br /&gt;
add comment=gw1 distance=201 gateway=188.235.62.254&lt;br /&gt;
&lt;br /&gt;
add comment=gw2 distance=202 gateway=ether4-wan2_pppoe-client_intercon&lt;br /&gt;
&lt;br /&gt;
add comment=gw3 distance=203 gateway=172.24.199.1&lt;br /&gt;
&lt;br /&gt;
add comment=gw1_via_custom_route_table gateway=188.235.62.254 routing-table=route-table-gw1&lt;br /&gt;
&lt;br /&gt;
add comment=gw2_via_custom_route_table gateway=ether4-wan2_pppoe-client_intercon routing-table=route-table-gw2&lt;br /&gt;
&lt;br /&gt;
add comment=gw3_via_custom_route_table gateway=172.24.199.1 routing-table=route-table-gw3&lt;br /&gt;
&lt;br /&gt;
add comment=gw1_via_pub1_chk dst-address=77.88.8.8/32 gateway=188.235.62.254 scope=11&lt;br /&gt;
&lt;br /&gt;
add comment=gw2_via_pub2_chk dst-address=208.67.222.222/32 gateway=ether4-wan2_pppoe-client_intercon scope=11&lt;br /&gt;
&lt;br /&gt;
add comment=gw3_via_pub3_chk dst-address=77.88.8.3/32 gateway=172.24.199.1 scope=11&lt;br /&gt;
&lt;br /&gt;
add check-gateway=ping comment=pub1_gw1_chk distance=101 gateway=77.88.8.8 target-scope=11&lt;br /&gt;
&lt;br /&gt;
add check-gateway=ping comment=pub2_gw2_chk distance=102 gateway=208.67.222.222 target-scope=11&lt;br /&gt;
&lt;br /&gt;
add check-gateway=ping comment=pub3_gw3_chk distance=103 gateway=77.88.8.3 target-scope=11&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/ip firewall mangle&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether3-wan1_domru new-connection-mark=con-isp1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether4-wan2_pppoe-client_intercon new-connection-mark=con-isp2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-connection chain=prerouting connection-mark=no-mark in-interface=ether6-wan3_modem-4g new-connection-mark=con-isp3 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp1 in-interface-list=!-WAN- new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp2 in-interface-list=!-WAN- new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=prerouting connection-mark=con-isp3 in-interface-list=!-WAN- new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp1 new-routing-mark=route-table-gw1 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp2 new-routing-mark=route-table-gw2 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
add action=mark-routing chain=output connection-mark=con-isp3 new-routing-mark=route-table-gw3 passthrough=yes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Готово&lt;br /&gt;
&lt;br /&gt;
Пробуем пинговать с внешки IP-адреса провайдеров&lt;br /&gt;
&lt;br /&gt;
Каждый должен пинговаться&lt;br /&gt;
&lt;br /&gt;
Пробуем ходить с внешки на IP-адреса провайдеров по порту 80,&lt;br /&gt;
&lt;br /&gt;
По каждому провайдеру проходим до веб-сервера 192.168.1.50&lt;br /&gt;
&lt;br /&gt;
ОТКЛЮЧАЕМ ОСНОВНОГО ПРОВАЙДЕРА - ТРАФИК ИДЕТ ЧЕРЕЗ ШЛЮЗ РЕЗЕРВНОГО&lt;br /&gt;
&lt;br /&gt;
== Мониторинг провайдеров ==&lt;br /&gt;
&lt;br /&gt;
=== Ссылки ===&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://vasilevkirill.ru/routeros-check-internet-v7/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка ===&lt;br /&gt;
&lt;br /&gt;
* 213.129.118.208 - публичный адрес провайдера 1 на нашем микроте&lt;br /&gt;
* 194.186.163.89 - публичный адрес провайдера 2 на нашем микроте&lt;br /&gt;
* 213.129.118.1 - основной шлюз isp1&lt;br /&gt;
* 194.186.163.88 - основной шлюз isp2&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp1:&lt;br /&gt;
&lt;br /&gt;
* 176.99.13.13&lt;br /&gt;
* 31.177.85.186&lt;br /&gt;
&lt;br /&gt;
адреса, которые будем пинговать для проверки через isp2:&lt;br /&gt;
&lt;br /&gt;
* 93.158.134.1&lt;br /&gt;
* 5.101.159.11&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Создадим таблицы и правила для прохождения трафика до спец IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ПЕРВЫЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp1 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/routing/rule add dst-address=176.99.13.13/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/routing/rule add dst-address=31.177.85.186/32 action=lookup-only-in-table table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=213.129.118.1 routing-table=via-isp1 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ВТОРОЙ ПРОВАЙДЕР:&lt;br /&gt;
&lt;br /&gt;
/routing/table add name=via-isp2 fib comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/routing/rule add dst-address=93.158.134.1/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/routing/rule add dst-address=5.101.159.11/32 action=lookup-only-in-table table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/ip route add dst-address=0.0.0.0/0 gateway=194.186.163.88 routing-table=via-isp2 comment=&amp;quot;chk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Создадим правила netwatch для проверки пингами спец внешних IP через определенных провайдеров&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/tool netwatch&lt;br /&gt;
&lt;br /&gt;
add comment=ns1.reg.ru disabled=no down-script=&amp;quot;&amp;quot; host=176.99.13.13 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk1 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns9.nic.ru disabled=no down-script=&amp;quot;&amp;quot; host=31.177.85.186 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk2 port=53 src-address=213.129.118.208 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns1.beget.com disabled=no down-script=&amp;quot;&amp;quot; host=5.101.159.11 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk2 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns2.yandex.ru disabled=no down-script=&amp;quot;&amp;quot; host=93.158.134.1 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk1 port=53 src-address=194.186.163.89 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/tool netwatch&lt;br /&gt;
&lt;br /&gt;
add comment=ns1.reg.ru disabled=no down-script=&amp;quot;&amp;quot; host=176.99.13.13 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk1 src-address=80.82.33.162 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns9.nic.ru disabled=no down-script=&amp;quot;&amp;quot; host=31.177.85.186 http-codes=&amp;quot;&amp;quot; interval=30s name=isp1-chk2 port=53 src-address=80.82.33.162 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns1.beget.com disabled=no down-script=&amp;quot;&amp;quot; host=5.101.159.11 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk2 port=53 src-address=178.210.43.248 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
add comment=ns2.yandex.ru disabled=no down-script=&amp;quot;&amp;quot; host=93.158.134.1 http-codes=&amp;quot;&amp;quot; interval=30s name=isp2-chk1 port=53 src-address=178.210.43.248 test-script=&amp;quot;&amp;quot; thr-tcp-conn-time=1s type=icmp up-script=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/system script add name=monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/system script edit monitor source&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#####&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Monitor ros7 v.2026-02-14_isp2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; by Cless&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#####&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;local NetWatchIsp1CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp1&amp;quot; disabled=no status=up];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;local NetWatchIsp2CountUp [/tool/netwatch/print count-only where name~&amp;quot;isp2&amp;quot; disabled=no status=up];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ISP1 CHK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;if (($NetWatchIsp1CountUp &amp;gt; 0)) do={&lt;br /&gt;
&lt;br /&gt;
    :global isp1Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
} else={&lt;br /&gt;
&lt;br /&gt;
        :global isp1Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ISP2 CHK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;if (($NetWatchIsp2CountUp &amp;gt; 0)) do={&lt;br /&gt;
&lt;br /&gt;
    :global isp2Status &amp;quot;OK&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
} else={&lt;br /&gt;
&lt;br /&gt;
        :global isp2Status &amp;quot;FAIL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ACTIVE GW CHK&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;local gw1active [ip route get value-name=active [find where comment~&amp;quot;pub1_gw1_chk&amp;quot;]] ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;local gw2active [ip route get value-name=active [find where comment~&amp;quot;pub2_gw2_chk&amp;quot;]] ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;if (($gw1active=true) &amp;amp;&amp;amp; ($gw2active!=true)) do={&lt;br /&gt;
&lt;br /&gt;
    :global gwActive &amp;quot;gw1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;if (($gw1active!=true) &amp;amp;&amp;amp; ($gw2active=true)) do={&lt;br /&gt;
&lt;br /&gt;
    :global gwActive &amp;quot;gw2&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; DEBUG&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;global gwActive;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;global isp1Status;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;global isp2Status;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;put &amp;quot;gwActive $gwActive ; isp1Status $isp1Status ; isp2Status $isp2Status&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/system scheduler&lt;br /&gt;
&lt;br /&gt;
add disabled=yes interval=30s name=chk on-event=chk policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
&lt;br /&gt;
add interval=1m name=monitor on-event=monitor policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-time=startup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/system/script/environment/print&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    2  gwActive        gw1&lt;br /&gt;
&lt;br /&gt;
    3  isp1Status      OK&lt;br /&gt;
&lt;br /&gt;
    4  isp2Status      OK&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
== На Zabbix ==&lt;br /&gt;
apt install python3-librouteros&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
vim ./mikrotikVarGet.py&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;!/usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
import json&lt;br /&gt;
&lt;br /&gt;
from librouteros import connect&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; ARGs check&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv) &amp;lt; 5:&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Usage: script.py &amp;lt;IP&amp;gt; &amp;lt;username&amp;gt; &amp;lt;password&amp;gt; &amp;lt;variable_name&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Connection parameters&lt;br /&gt;
&lt;br /&gt;
IP = sys.argv[1]&lt;br /&gt;
&lt;br /&gt;
USERNAME = sys.argv[2]&lt;br /&gt;
&lt;br /&gt;
PASSWORD = sys.argv[3]&lt;br /&gt;
&lt;br /&gt;
mikrotikApiVarName = sys.argv[4]&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
&lt;br /&gt;
    api = connect(&lt;br /&gt;
&lt;br /&gt;
        host=IP,&lt;br /&gt;
&lt;br /&gt;
        username=USERNAME,&lt;br /&gt;
&lt;br /&gt;
        password=PASSWORD&lt;br /&gt;
&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    all_vars = list(api('/system/script/environment/print'))&lt;br /&gt;
&lt;br /&gt;
    for i, var in enumerate(all_vars):&lt;br /&gt;
&lt;br /&gt;
        if var.get('name') == mikrotikApiVarName:&lt;br /&gt;
&lt;br /&gt;
            print(var.get(&amp;lt;nowiki&amp;gt;'value', ''&amp;lt;/nowiki&amp;gt;))&lt;br /&gt;
&lt;br /&gt;
            sys.exit(0)&lt;br /&gt;
&lt;br /&gt;
except Exception as e:&lt;br /&gt;
&lt;br /&gt;
    print(f&amp;quot;DEBUG: Error: {e}&amp;quot;, file=sys.stderr)&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Далее на Zabbix проверяем значение переменных Item и создаем триггеры.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
    mikrotikVarGet.py[&amp;quot;{HOST.CONN}&amp;quot;,&amp;quot;uplit&amp;quot;,&amp;quot;Pass#&amp;quot;,&amp;quot;isp1Status&amp;quot;]&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=ZFS._Nas4free._Creating_and_mounting_ZFS-Volume._Mount_ZFS-Volume_via_ISCSI-target&amp;diff=1934</id>
		<title>ZFS. Nas4free. Creating and mounting ZFS-Volume. Mount ZFS-Volume via ISCSI-target</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=ZFS._Nas4free._Creating_and_mounting_ZFS-Volume._Mount_ZFS-Volume_via_ISCSI-target&amp;diff=1934"/>
		<updated>2026-01-31T20:03:40Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:ZFS]]&lt;br /&gt;
[[Категория:ISCSI]]&lt;br /&gt;
[[Категория:XigmaNAS (NAS4free)]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Creating and mounting ZFS-Volume. Mount ZFS-Volume via ISCSI-target&lt;br /&gt;
&lt;br /&gt;
= Configuring =&lt;br /&gt;
&lt;br /&gt;
== Server Nas4free. ZFS, ISCSI-target ==&lt;br /&gt;
&lt;br /&gt;
=== Nas4free CLI ===&lt;br /&gt;
Creating zfs-volume&lt;br /&gt;
&lt;br /&gt;
==== Thick volume ====&lt;br /&gt;
&amp;lt;code&amp;gt;zfs create -V 10G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Thin (Sparse) Volume ====&lt;br /&gt;
&amp;lt;code&amp;gt;zfs create -s -V 10G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /dev/zvol/raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     crw-r-----  1 root  operator   0xc2 Jan 29 10:24 /dev/zvol/raid1/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Show&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -o volsize,used,logicalused,available,quota,name,sharenfs,mountpoint&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     1T  89.5K    26K  3.24T      -  raid2/volumes/nextcloud01-data     -         -&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Nas4free WEB ===&lt;br /&gt;
Create ISCSI-auth&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail&lt;br /&gt;
&lt;br /&gt;
'''User''': vmail&lt;br /&gt;
&lt;br /&gt;
'''Password''': PassWord&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-initiators&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-portals&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-extent&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail&lt;br /&gt;
&lt;br /&gt;
'''Type''': ZFS-volume&lt;br /&gt;
&lt;br /&gt;
'''ZFS-volume''': /dev/zvol/raid1/vmail&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-target&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail    &lt;br /&gt;
&lt;br /&gt;
'''Type''': Disk&lt;br /&gt;
&lt;br /&gt;
'''Flags''': RW&lt;br /&gt;
&lt;br /&gt;
'''Storage''': vmail (/dev/zvol/raid1/vmail)&amp;lt;blockquote&amp;gt;Restart iscsi-target service!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Client Linux (AlmaLinux 8). ISCSI-initiator ==&lt;br /&gt;
Install&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y install iscsi-initiator-utils&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Target path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/iscsi/initiatorname.iscsi&amp;lt;/code&amp;gt;&lt;br /&gt;
     InitiatorName=iqn.2023-01.alef:vmail&lt;br /&gt;
If you use Auth for ISCSI-target, you have to add options below&lt;br /&gt;
&lt;br /&gt;
Login and password for target (CHAP only)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/iscsi/iscsid.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 node.session.auth.username = vmail&lt;br /&gt;
 node.session.auth.password = PassWord&lt;br /&gt;
 ...&lt;br /&gt;
Discovery target (if target discovery auth disabled)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     192.168.199.250:3260,1 iqn.2023-01.alef:vmail&lt;br /&gt;
     ...&lt;br /&gt;
Target info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node -o show&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login to specific targets    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail.zfs -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Logging in to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
     Login to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
     ...&lt;br /&gt;
Show connected session info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m session -o show&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     tcp: [6] 192.168.199.250:3260,1 iqn.2023-01.alef:vmail (non-flash)&lt;br /&gt;
     ...&lt;br /&gt;
Show connected block device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsblk&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     sdb                       8:16   0  10G  0 disk&lt;br /&gt;
     ...&lt;br /&gt;
Create partition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fdisk /dev/sdb&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   n - Next - Next...&amp;lt;/blockquote&amp;gt;Create FS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkfs.ext4 /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Getting partition UUID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1: UUID=&amp;quot;d13097d0-1b54-47b0-b504-ffc56d9bceff&amp;quot; BLOCK_SIZE=&amp;quot;4096&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;797c5bc8-01&amp;quot;&lt;br /&gt;
     ...&lt;br /&gt;
Auto mount after OS boot    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /var/vmail&amp;lt;/code&amp;gt;    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # iscsi vmail&lt;br /&gt;
 UUID=&amp;quot;d13097d0-1b54-47b0-b504-ffc56d9bceff&amp;quot; /var/vmail ext4 _netdev 0 0&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1                         10G  4.1G   89G   5% /var/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Success!&lt;br /&gt;
&lt;br /&gt;
= Increase size of the Volume (extent as ZFS-Volume) =&lt;br /&gt;
&lt;br /&gt;
== Client Linux ISCSI-initiator ==&lt;br /&gt;
Stop all the services, which can write to the ISCSI-device&lt;br /&gt;
&lt;br /&gt;
Unmount device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /var/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout target&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -u&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    Logging out of session [sid: 1, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
    Logout of [sid: 1, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
    ...&lt;br /&gt;
Delete connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -o delete&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server ISCSI-target ==&lt;br /&gt;
Stop iscsi-target service!&lt;br /&gt;
&lt;br /&gt;
Remove all snapshots at zfs-volume, that will be increased (if they exist)!&lt;br /&gt;
&lt;br /&gt;
Rename all replicas of zfs-volume, that will be increased (if they exist):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs rename raid2/mail02-mail_replica raid2/OLD_mail02-mail_replica&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Increase size of the ZFS-Volume&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs set volsize=50G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart commit zvol/raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Import zfs&amp;lt;blockquote&amp;gt;Or you can do synchronization in the web-interface&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool import -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs mount -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show volumes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -o volsize,used,logicalused,available,quota,name,sharenfs,mountpoint&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     raid1/vmail     51.6G  5.78T  1.24G  -&lt;br /&gt;
     ...&lt;br /&gt;
Check that full size of '''zfs-volume''' in increased&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;diskinfo -v /dev/zvol/raid1/mail02-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/zvol/raid1/mail02-mail&lt;br /&gt;
             512             # sectorsize&lt;br /&gt;
             64424509440     # mediasize in bytes ('''50G''')&lt;br /&gt;
             125829120       # mediasize in sectors&lt;br /&gt;
             8192            # stripesize&lt;br /&gt;
             0               # stripeoffset&lt;br /&gt;
     ...&lt;br /&gt;
Check that full size of '''the PARTITION of the zfs-volume''' didn't change (we will increase it later at the iscsi-client)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;diskinfo -v /dev/zvol/raid1/mail02-mails1&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/zvol/raid1/mail02-mails1&lt;br /&gt;
             512             # sectorsize&lt;br /&gt;
             32211206144     # mediasize in bytes ('''30G''')&lt;br /&gt;
             62912512        # mediasize in sectors&lt;br /&gt;
             8192            # stripesize&lt;br /&gt;
             0               # stripeoffset&lt;br /&gt;
             3916            # Cylinders according to firmware.&lt;br /&gt;
             255             # Heads according to firmware.&lt;br /&gt;
             63              # Sectors according to firmware.&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Once I caught an error &amp;quot;'''***ERROR*** lu_disk_init() failed'''&amp;quot; after increasing zfs-volume.&lt;br /&gt;
&lt;br /&gt;
It means that zfs-volume, which we increased, is busy&lt;br /&gt;
&lt;br /&gt;
In that case you can create iscsi-target at the TARGET tab only in RO mode&lt;br /&gt;
&lt;br /&gt;
If you try to run iscsi target in RW mode - service iscsi will be failed&lt;br /&gt;
&lt;br /&gt;
I didn't understand exactly how could I solved it!&lt;br /&gt;
&lt;br /&gt;
If I'm not mistaken, after increasing zfs-volume, I renamed zfs-volume as *_1 and then rename it back&lt;br /&gt;
&lt;br /&gt;
And everything became OK&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;In that case: &lt;br /&gt;
&lt;br /&gt;
Rename to a temporary volume name &lt;br /&gt;
&lt;br /&gt;
'''zfs rename raid1/mail02-mail raid1/mail02-mail_1''' &lt;br /&gt;
&lt;br /&gt;
Rename to its original name &lt;br /&gt;
&lt;br /&gt;
'''zfs rename raid1/mail02-mail_1 raid1/mail02-mail''' &amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''! After that It's NECESSARILY to check log tab in Nas4free after service start!'''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''And Check whether iscsi target successful started!'''&amp;lt;/blockquote&amp;gt;Start iscsi-target service!&lt;br /&gt;
&lt;br /&gt;
== Client ISCSI-initiator ==&lt;br /&gt;
Discovery target (if target discovery auth disabled)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     192.168.199.250:3260,1 iqn.2023-01.alef:vmail&lt;br /&gt;
     ...&lt;br /&gt;
Login to specific targets    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail.zfs -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Logging in to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
     Login to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;!!! DON'T mount device!&lt;br /&gt;
&lt;br /&gt;
!!! Run '''df -h''' and UNMOUNT '''/dev/sdb1''' if it is mounted !&amp;lt;/blockquote&amp;gt;Run parted util&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Select device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; select /dev/sdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get device full size (it will be bigger than actual size)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; print&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Disk /dev/sdb: 53GB&lt;br /&gt;
     ...&lt;br /&gt;
Increaze size to full disk size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; resizepart 1 53GB&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Exit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; quit&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;!!! Run df -h and UNMOUNT /dev/sdb1 if it is mounted !&amp;lt;/blockquote&amp;gt;Check FS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;e2fsck -fy /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Increase FS size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check new size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1                        50G   20M   47G   4% /var/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Success!&lt;br /&gt;
&lt;br /&gt;
= Snapshots =&lt;br /&gt;
&lt;br /&gt;
== Snapshot create ==&lt;br /&gt;
&lt;br /&gt;
=== At Server nas4free ISCSI-target ===&lt;br /&gt;
Create snapshot and for test you can create file before creating each snapshot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -H -t snapshot -o name,creation -S creation -r raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     raid1/vmail@3   Sun Jan 29 11:29 2023&lt;br /&gt;
     raid1/vmail@2   Sun Jan 29 11:27 2023&lt;br /&gt;
     raid1/vmail@1   Sun Jan 29 11:25 2023&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== Snapshot restore     ==&lt;br /&gt;
&lt;br /&gt;
=== At Client Linux ISCSI-initiator ===&lt;br /&gt;
Stop ALL services, which can write to ISCSI-device!&lt;br /&gt;
&lt;br /&gt;
Unmount iscsi-dev, kill iscsi-session&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /var/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -u&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -o delete&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== At Server nas4free ISCSI-target ===&lt;br /&gt;
Stop iscsi-target service (WEB)&lt;br /&gt;
&lt;br /&gt;
Rollback snapshot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs rollback -r raid2/vmail@1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start iscsi-target service (via WEB-interface)&lt;br /&gt;
&lt;br /&gt;
=== At Client Linux ISCSI-initiator ===&lt;br /&gt;
Connect and mount iscsi-dev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see, that FS at /var/vmail have a state, that it had before snapshot creating.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=ZFS._Nas4free._Creating_and_mounting_ZFS-Volume._Mount_ZFS-Volume_via_ISCSI-target&amp;diff=1933</id>
		<title>ZFS. Nas4free. Creating and mounting ZFS-Volume. Mount ZFS-Volume via ISCSI-target</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=ZFS._Nas4free._Creating_and_mounting_ZFS-Volume._Mount_ZFS-Volume_via_ISCSI-target&amp;diff=1933"/>
		<updated>2026-01-31T19:52:48Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:ZFS]]&lt;br /&gt;
[[Категория:ISCSI]]&lt;br /&gt;
[[Категория:XigmaNAS (NAS4free)]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Creating and mounting ZFS-Volume. Mount ZFS-Volume via ISCSI-target&lt;br /&gt;
&lt;br /&gt;
= Configuring =&lt;br /&gt;
&lt;br /&gt;
== Server Nas4free. ZFS, ISCSI-target ==&lt;br /&gt;
&lt;br /&gt;
=== Nas4free CLI ===&lt;br /&gt;
Creating zfs-volume&lt;br /&gt;
&lt;br /&gt;
==== Thick volume ====&lt;br /&gt;
&amp;lt;code&amp;gt;zfs create -V 10G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Thin (Sparse) Volume ====&lt;br /&gt;
&amp;lt;code&amp;gt;zfs create -s -V 10G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /dev/zvol/raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     crw-r-----  1 root  operator   0xc2 Jan 29 10:24 /dev/zvol/raid1/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Show&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -o volsize,used,logicalused,available,quota,name,sharenfs,mountpoint&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     1T  89.5K    26K  3.24T      -  raid2/volumes/nextcloud01-data     -         -&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Nas4free WEB ===&lt;br /&gt;
Create ISCSI-auth&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail&lt;br /&gt;
&lt;br /&gt;
'''User''': vmail&lt;br /&gt;
&lt;br /&gt;
'''Password''': PassWord&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-initiators&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-portals&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-extent&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail&lt;br /&gt;
&lt;br /&gt;
'''Type''': ZFS-volume&lt;br /&gt;
&lt;br /&gt;
'''ZFS-volume''': /dev/zvol/raid1/vmail&lt;br /&gt;
&lt;br /&gt;
Create ISCSI-target&lt;br /&gt;
&lt;br /&gt;
'''Name''': vmail    &lt;br /&gt;
&lt;br /&gt;
'''Type''': Disk&lt;br /&gt;
&lt;br /&gt;
'''Flags''': RW&lt;br /&gt;
&lt;br /&gt;
'''Storage''': vmail (/dev/zvol/raid1/vmail)&amp;lt;blockquote&amp;gt;Restart iscsi-target service!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Client Linux (AlmaLinux 8). ISCSI-initiator ==&lt;br /&gt;
Install&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y install iscsi-initiator-utils&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Target path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/iscsi/initiatorname.iscsi&amp;lt;/code&amp;gt;&lt;br /&gt;
     InitiatorName=iqn.2023-01.alef:vmail&lt;br /&gt;
If you use Auth for ISCSI-target, you have to add options below&lt;br /&gt;
&lt;br /&gt;
Login and password for target (CHAP only)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/iscsi/iscsid.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 node.session.auth.username = vmail&lt;br /&gt;
 node.session.auth.password = PassWord&lt;br /&gt;
 ...&lt;br /&gt;
Discovery target (if target discovery auth disabled)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     192.168.199.250:3260,1 iqn.2023-01.alef:vmail&lt;br /&gt;
     ...&lt;br /&gt;
Target info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node -o show&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login to specific targets    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail.zfs -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Logging in to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
     Login to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
     ...&lt;br /&gt;
Show connected session info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m session -o show&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     tcp: [6] 192.168.199.250:3260,1 iqn.2023-01.alef:vmail (non-flash)&lt;br /&gt;
     ...&lt;br /&gt;
Show connected block device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsblk&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     sdb                       8:16   0  10G  0 disk&lt;br /&gt;
     ...&lt;br /&gt;
Create partition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fdisk /dev/sdb&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   n - Next - Next...&amp;lt;/blockquote&amp;gt;Create FS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkfs.ext4 /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Getting partition UUID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1: UUID=&amp;quot;d13097d0-1b54-47b0-b504-ffc56d9bceff&amp;quot; BLOCK_SIZE=&amp;quot;4096&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;797c5bc8-01&amp;quot;&lt;br /&gt;
     ...&lt;br /&gt;
Auto mount after OS boot    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /var/vmail&amp;lt;/code&amp;gt;    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # iscsi vmail&lt;br /&gt;
 UUID=&amp;quot;d13097d0-1b54-47b0-b504-ffc56d9bceff&amp;quot; /var/vmail ext4 _netdev 0 0&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1                         10G  4.1G   89G   5% /var/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Success!&lt;br /&gt;
&lt;br /&gt;
= Increase size of the Volume (extent as ZFS-Volume) =&lt;br /&gt;
&lt;br /&gt;
== Client Linux ISCSI-initiator ==&lt;br /&gt;
Stop all the services, which can write to the ISCSI-device&lt;br /&gt;
&lt;br /&gt;
Unmount device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /var/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout target&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -u&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    Logging out of session [sid: 1, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
    Logout of [sid: 1, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
    ...&lt;br /&gt;
Delete connection&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -o delete&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server ISCSI-target ==&lt;br /&gt;
Stop iscsi-target service!&lt;br /&gt;
&lt;br /&gt;
Remove all snapshots at zfs-volume, that will be increased (if they exist)!&lt;br /&gt;
&lt;br /&gt;
Rename all replicas of zfs-volume, that will be increased (if they exist):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs rename raid2/mail02-mail_replica raid2/OLD_mail02-mail_replica&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Increase size of the ZFS-Volume&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs set volsize=50G raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart commit zvol/raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Import zfs&amp;lt;blockquote&amp;gt;Or you can do synchronization in the web-interface&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool import -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs mount -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show volumes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -o volsize,used,logicalused,available,quota,name,sharenfs,mountpoint&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     raid1/vmail     51.6G  5.78T  1.24G  -&lt;br /&gt;
     ...&lt;br /&gt;
Check that full size of '''zfs-volume''' in increased&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;diskinfo -v /dev/zvol/raid1/mail02-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/zvol/raid1/mail02-mail&lt;br /&gt;
             512             # sectorsize&lt;br /&gt;
             64424509440     # mediasize in bytes ('''50G''')&lt;br /&gt;
             125829120       # mediasize in sectors&lt;br /&gt;
             8192            # stripesize&lt;br /&gt;
             0               # stripeoffset&lt;br /&gt;
     ...&lt;br /&gt;
Check that full size of '''the PARTITION of the zfs-volume''' didn't change (we will increase it later at the iscsi-client)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;diskinfo -v /dev/zvol/raid1/mail02-mails1&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/zvol/raid1/mail02-mails1&lt;br /&gt;
             512             # sectorsize&lt;br /&gt;
             32211206144     # mediasize in bytes ('''30G''')&lt;br /&gt;
             62912512        # mediasize in sectors&lt;br /&gt;
             8192            # stripesize&lt;br /&gt;
             0               # stripeoffset&lt;br /&gt;
             3916            # Cylinders according to firmware.&lt;br /&gt;
             255             # Heads according to firmware.&lt;br /&gt;
             63              # Sectors according to firmware.&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Once I caught an error &amp;quot;'''***ERROR*** lu_disk_init() failed'''&amp;quot; after increasing zfs-volume.&lt;br /&gt;
&lt;br /&gt;
It means that zfs-volume, which we increased, is busy&lt;br /&gt;
&lt;br /&gt;
In that case you can create iscsi-target at the TARGET tab only in RO mode&lt;br /&gt;
&lt;br /&gt;
If you try to run iscsi target in RW mode - service iscsi will be failed&lt;br /&gt;
&lt;br /&gt;
I didn't understand exactly how could I solved it!&lt;br /&gt;
&lt;br /&gt;
If I'm not mistaken, after increasing zfs-volume, I renamed zfs-volume as *_1 and then rename it back&lt;br /&gt;
&lt;br /&gt;
And everything became OK&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;In that case: &lt;br /&gt;
&lt;br /&gt;
Rename to a temporary volume name &lt;br /&gt;
&lt;br /&gt;
'''zfs rename raid1/mail02-mail raid1/mail02-mail_1''' &lt;br /&gt;
&lt;br /&gt;
Rename to its original name &lt;br /&gt;
&lt;br /&gt;
'''zfs rename raid1/mail02-mail_1 raid1/mail02-mail''' &amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''! After that It's NECESSARILY to check log tab in Nas4free after service start!'''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''And Check whether iscsi target successful started!'''&amp;lt;/blockquote&amp;gt;Start iscsi-target service!&lt;br /&gt;
&lt;br /&gt;
== Client ISCSI-initiator ==&lt;br /&gt;
Discovery target (if target discovery auth disabled)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     192.168.199.250:3260,1 iqn.2023-01.alef:vmail&lt;br /&gt;
     ...&lt;br /&gt;
Login to specific targets    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail.zfs -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Logging in to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260]&lt;br /&gt;
     Login to [iface: default, target: iqn.2023-01.alef:vmail, portal: 192.168.199.250,3260] successful.&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;!!! DON'T mount device!&lt;br /&gt;
&lt;br /&gt;
!!! Run '''df -h''' and UNMOUNT '''/dev/sdb1''' if it is mounted !&amp;lt;/blockquote&amp;gt;Run parted util&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Select device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; select /dev/sdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get device full size (it will be bigger than actual size)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; print&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Disk /dev/sdb: 53GB&lt;br /&gt;
     ...&lt;br /&gt;
Increaze size to full disk size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; resizepart 1 53GB&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Exit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; quit&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;!!! Run df -h and UNMOUNT /dev/sdb1 if it is mounted !&amp;lt;/blockquote&amp;gt;Check FS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;e2fsck -f /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Increase FS size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mount device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/sdb1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check new size&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     /dev/sdb1                        50G   20M   47G   4% /var/vmail&lt;br /&gt;
     ...&lt;br /&gt;
Success!&lt;br /&gt;
&lt;br /&gt;
= Snapshots =&lt;br /&gt;
&lt;br /&gt;
== Snapshot create ==&lt;br /&gt;
&lt;br /&gt;
=== At Server nas4free ISCSI-target ===&lt;br /&gt;
Create snapshot and for test you can create file before creating each snapshot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs snapshot raid1/vmail@3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs list -H -t snapshot -o name,creation -S creation -r raid1/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     raid1/vmail@3   Sun Jan 29 11:29 2023&lt;br /&gt;
     raid1/vmail@2   Sun Jan 29 11:27 2023&lt;br /&gt;
     raid1/vmail@1   Sun Jan 29 11:25 2023&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== Snapshot restore     ==&lt;br /&gt;
&lt;br /&gt;
=== At Client Linux ISCSI-initiator ===&lt;br /&gt;
Stop ALL services, which can write to ISCSI-device!&lt;br /&gt;
&lt;br /&gt;
Unmount iscsi-dev, kill iscsi-session&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /var/vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -u&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm --mode node --targetname iqn.2023-01.alef:vmail --portal 192.168.199.250 -o delete&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== At Server nas4free ISCSI-target ===&lt;br /&gt;
Stop iscsi-target service (WEB)&lt;br /&gt;
&lt;br /&gt;
Rollback snapshot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zfs rollback -r raid2/vmail@1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start iscsi-target service (via WEB-interface)&lt;br /&gt;
&lt;br /&gt;
=== At Client Linux ISCSI-initiator ===&lt;br /&gt;
Connect and mount iscsi-dev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m discovery -t sendtargets -p 192.168.199.250&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;iscsiadm -m node --login --targetname iqn.2023-01.alef:vmail -p 192.168.199.250,3260&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see, that FS at /var/vmail have a state, that it had before snapshot creating.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1932</id>
		<title>Mail Server. AlmaLinux 8. Postfix + Dovecot + Postfixadmin + Roundcube Webmail</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1932"/>
		<updated>2025-08-21T19:18:32Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Mail]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Opensource Mail Server. Postfix + Dovecot + Postfixadmin + Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
https://www.dmosk.ru/instruktions.php?object=mailserver-centos8&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== DNS Server Global ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Add resource records to the dns server, which is serving your domains (at mikrotik, for example, but it can be any dns-record manager of the registrar, which provides you your new domain)&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - public external IP of the mail server&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''192.168.199.40''''' - local IP of this mail server in you local network&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Root domain MX-record, which point to the mail domain ===&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=yourdomain.ru mx-exchange=mail.yourdomain.ru. mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Domain for administration - mail02.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This should be the hostname of your physical mail server&lt;br /&gt;
&lt;br /&gt;
It's not your domain for mail, just for management&lt;br /&gt;
&lt;br /&gt;
If there will be other mail domains on that server, all emails still will be sended with source-host &amp;quot;mail02.yourdomain.ru&amp;quot; as mail sender&lt;br /&gt;
&lt;br /&gt;
This domain needs to be added to ISP's PTR-record as well&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail02.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mail domain - mail.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This is your first mail domain&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS Server Local ==&lt;br /&gt;
At the local '''DNS server''' (whose IP is registred in the file '''/etc/resolv.conf''' of this mail server) you have to register accordance of '''your domains''' and '''local IP''' in you local network of this server:&lt;br /&gt;
 ...&lt;br /&gt;
 192.168.199.42 mail.yourdomain.ru&lt;br /&gt;
 192.168.199.42 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Mail server ==&lt;br /&gt;
&lt;br /&gt;
=== General configuration ===&lt;br /&gt;
System update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hostname&amp;lt;blockquote&amp;gt;'''''mail02.yourdomain.ru''''' - mail server hostname&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - mail server public external IP&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/hosts&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 185.225.35.200 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
Check&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig A mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utils, firewall, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y chrony wget&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;timedatectl set-timezone Europe/Moscow&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable chronyd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp --add-port=22/tcp --add-port=10050/tcp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL Certs ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to choose whether you will use self-signed certs or letsencrypt certs or purchased certs. We will use it later for Webmail Interface (nginx), and for Mail Desktop Clients (postfix, dovecot)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certificates ====&lt;br /&gt;
''If you're going to purchase SSL certificates from CA:''&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''a few wildcard certs''' with main domain and wildcard subdomains (e.g., '''example.com''' and '''*.example.com''') for '''each mail domain'''.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''the only ONE''' multidomain certificate with '''ALL main domain certs and wildcard certificates of your main domain ('''e.g., '''example.com''' and '''*.example.com''' for each domain''')'''.&lt;br /&gt;
&lt;br /&gt;
==== Self-signed ====&lt;br /&gt;
Generate certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/ssl/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj &amp;quot;/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=mail02.yourdomain.ru&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Letsencrypt ====&lt;br /&gt;
Nginx will create /usr/share/nginx/html directory for letsencrypt challenges&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y certbot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to create cert for each domain. You can put all certs into one file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y &amp;lt;nowiki&amp;gt;http://rpms.remirepo.net/enterprise/remi-release-8.rpm&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf module install -y php:remi-7.4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # For more information on configuration, see:&lt;br /&gt;
 #   * Official English Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 #   * Official Russian Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/ru/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 user nginx;&lt;br /&gt;
 worker_processes auto;&lt;br /&gt;
 error_log /var/log/nginx/error.log;&lt;br /&gt;
 pid /run/nginx.pid;&lt;br /&gt;
 # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.&lt;br /&gt;
 include /usr/share/nginx/modules/*.conf;&lt;br /&gt;
 events {&lt;br /&gt;
    worker_connections 1024;&lt;br /&gt;
 }&lt;br /&gt;
 http {&lt;br /&gt;
    log_format  main  '$remote_addr - $remote_user [$time_local] &amp;quot;$request&amp;quot; '&lt;br /&gt;
                      '$status $body_bytes_sent &amp;quot;$http_referer&amp;quot; '&lt;br /&gt;
                      '&amp;quot;$http_user_agent&amp;quot; &amp;quot;$http_x_forwarded_for&amp;quot;';&lt;br /&gt;
    access_log  /var/log/nginx/access.log  main;&lt;br /&gt;
    sendfile            on;&lt;br /&gt;
    tcp_nopush          on;&lt;br /&gt;
    tcp_nodelay         on;&lt;br /&gt;
    keepalive_timeout   65;&lt;br /&gt;
    types_hash_max_size 2048;&lt;br /&gt;
    include             /etc/nginx/mime.types;&lt;br /&gt;
    default_type        application/octet-stream;&lt;br /&gt;
    # Load modular configuration files from the /etc/nginx/conf.d directory.&lt;br /&gt;
    # See &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/ngx_core_module.html#include&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    # for more information.&lt;br /&gt;
    include /etc/nginx/conf.d/*.conf;&lt;br /&gt;
 }&lt;br /&gt;
Redirect all HTTP-requests to HTTPS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 # Note: This file must be loaded before other virtual host config files,&lt;br /&gt;
 #&lt;br /&gt;
 # HTTP&lt;br /&gt;
 server {&lt;br /&gt;
    # Listen on ipv4&lt;br /&gt;
    listen 80;&lt;br /&gt;
    listen [::]:80;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    # Redirect all insecure http:// requests to https://&lt;br /&gt;
    return 301 &amp;lt;nowiki&amp;gt;https://$host$request_uri&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====HTTPS configuring====&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use self-signed or letsencrypt multidomain certificate (all domains and subdomains in one cert)=====&lt;br /&gt;
&lt;br /&gt;
Create a general config for HTTPS traffic (in order to use it with Roundcube Webmail and Postfixadmin)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2 default_server;&lt;br /&gt;
        listen       [::]:443 ssl http2 default_server;&lt;br /&gt;
        server_name  _;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
         &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate certificates, purchased from official CA or letsencrypt certs (separate cert for every mail domain)=====&lt;br /&gt;
&lt;br /&gt;
Backup /etc/nginx/conf.d/00-default_ssl.conf (or don't create it at all)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/conf.d/00-default_ssl.conf /etc/nginx/conf.d/00-default_ssl.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create separate config for each mail domain (in order to use it with Roundcube Webmail), and put in it the corresponding certificate path.&lt;br /&gt;
&lt;br /&gt;
Also you can create separate config for you management domain (in order to use it with Postfixadmin web-interface) in the same way (in our case mail02.yourdomain.ru). Or you can use any of our mail domains in order to get access to Postfixadmin web-interface. You also can use for that purpose letsencrypt cert or purchased cert.&lt;br /&gt;
&lt;br /&gt;
For example, this first config is for domain mail.don661.ru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/10-mail.don661.ru_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2;&lt;br /&gt;
        listen       [::]:443 ssl http2;&lt;br /&gt;
        server_name  mail.don661.ru;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
 &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
 &lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
        client_max_body_size 35M;&lt;br /&gt;
        client_body_timeout 300s;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable php-fpm --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MariaDB ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y mariadb-server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable mariadb --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysqladmin -u root password&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin/templates_c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DB creating&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -u root -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 # configuring is finished maker&lt;br /&gt;
 $CONF['configured'] = true;&lt;br /&gt;
 &lt;br /&gt;
 # default_language&lt;br /&gt;
 $CONF['default_language'] = 'en';&lt;br /&gt;
 &lt;br /&gt;
 # database_password&lt;br /&gt;
 $CONF['database_password'] = 'PassWord#1';&lt;br /&gt;
 &lt;br /&gt;
 # app checks domain during domains and mailboxes&lt;br /&gt;
 $CONF['emailcheck_resolve_domain']='NO';&lt;br /&gt;
 &lt;br /&gt;
 # amount of records (mailboxes, aliases) per page&lt;br /&gt;
 $CONF['page_size'] = '9999';&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter Setup password, copy generated HASH of the Setup password to config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['setup_password'] = '$2y$10$ZafzUSBaHy47kta5KfPAjF0aQBjH5i';&lt;br /&gt;
 ...&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with Setup password&lt;br /&gt;
&lt;br /&gt;
Create new admin at the footer of the page&lt;br /&gt;
     Администратор admin@yourdomain.ru успешно добавлен!&lt;br /&gt;
You are done with your basic setup. You can now login to PostfixAdmin using the account you just created.&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y postfix postfix-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
User to work with mail services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;groupadd -g 1024 vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;useradd -d /home/mail -g 1024 -u 1024 vmail -m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown vmail:vmail /home/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Main config ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Edit parameters&lt;br /&gt;
 ...&lt;br /&gt;
 # domain, that will be put in email during mail send if it doesn't point in mail's FROM&lt;br /&gt;
 &lt;br /&gt;
 myhostname = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 mydomain = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 myorigin = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 # domains for input emails&lt;br /&gt;
 mydestination = $myhostname, localhost.$mydomain, localhost, localhost.localdomain&lt;br /&gt;
 ...&lt;br /&gt;
 # where we can get local users&lt;br /&gt;
 local_recipient_maps = unix:passwd.byname $alias_maps&lt;br /&gt;
 ...&lt;br /&gt;
 # clients, that will send mail without auth at server. allow local server send emails&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 ...&lt;br /&gt;
 inet_interfaces = all&lt;br /&gt;
 ...&lt;br /&gt;
 inet_protocols = all&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # COMMENT OLD PARAMETERS&lt;br /&gt;
 #smtpd_tls_cert_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtpd_tls_key_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CApath = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CAfile = &amp;lt;...&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed certs&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_cert_file = /etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_key_file = /etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;###&amp;lt;/nowiki&amp;gt; OR&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt certs&lt;br /&gt;
 smtpd_tls_cert_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 smtp_tls_CApath = /etc/letsencrypt/live/ALL-MAIL-DOMAINS&lt;br /&gt;
 smtp_tls_CAfile = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/chain.pem&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the primary certificate for the server, to be used for outgoing connections&lt;br /&gt;
 smtpd_tls_chain_files =&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/privkey.pem,&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the map to be used when SNI support is enabled&lt;br /&gt;
 tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
nano /etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; One host per line&lt;br /&gt;
 &lt;br /&gt;
 mail.yourprimarymailserverdomain.com /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 mail.yoursecondarymailserverdomain.com /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; add more domains with keys and certs as needed&lt;br /&gt;
&lt;br /&gt;
postmap -F hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
systemctl restart postfix&lt;br /&gt;
==== Main config again ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   virtual_mailbox_base — storage path for mailboxes&lt;br /&gt;
&lt;br /&gt;
   virtual_alias_maps — format and path of the aliases for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_domains — format and path of the virtual domains&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_maps — format and path of the mailboxes for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_minimum_uid — start UID number for users&lt;br /&gt;
&lt;br /&gt;
   virtual_uid_maps — user id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_gid_maps — group id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_transport — message deliver&lt;br /&gt;
&lt;br /&gt;
   dovecot_destination_recipient_limit — message transfer from Postfix to Dovecot in steps 1 (one) at a time&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_exceptions_networks — networks excepted from encryption&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl settings&lt;br /&gt;
&lt;br /&gt;
   broken_sasl_auth_clients — option for MS Outlook clients&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — auth type&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — Dovecot tmp files. Full or related (default /var/spool/postfix). Full path — /var/spool/postfix/private/auth&lt;br /&gt;
&lt;br /&gt;
   smtp_use_tls — smtp transfer mandatory&lt;br /&gt;
&lt;br /&gt;
   smtpd_use_tls — indicates to clients that TLS support is available&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_auth_only — use TLS only&lt;br /&gt;
&lt;br /&gt;
   smtpd_helo_required — request to start the session with a greeting&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /home/mail&lt;br /&gt;
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf&lt;br /&gt;
 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf&lt;br /&gt;
 '''### If you want to reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files), add the following option):'''&lt;br /&gt;
 '''# ''smtpd_reject_unlisted_sender = yes''&lt;br /&gt;
 '''### (You can try to send an email with non-existing user in field FROM, you will see a rejection in output:&lt;br /&gt;
 '''### ''echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)'''''&lt;br /&gt;
 virtual_minimum_uid = 1024&lt;br /&gt;
 virtual_uid_maps = static:1024&lt;br /&gt;
 virtual_gid_maps = static:1024&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_exceptions_networks = $mynetworks&lt;br /&gt;
 smtpd_sasl_security_options = noanonymous&lt;br /&gt;
 broken_sasl_auth_clients = yes&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/auth&lt;br /&gt;
 smtp_use_tls = yes&lt;br /&gt;
 smtpd_use_tls = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
Aliases config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_alias_maps.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * '''user, password''' — MySQL DB login and password; '''hosts''' — MySQL hostname; '''dbname''' — Mysql DB name; '''query''' — DB request template&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT goto FROM alias WHERE address='%s' AND active = '1'&lt;br /&gt;
Virtual domains config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_domains_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT domain FROM domain WHERE domain='%u'&lt;br /&gt;
Mailboxes config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_mailbox_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* you need to be sure that there's no any uncomment options for '''submission''', '''smtps''' и '''dovecot''' (by default there's no such uncomment options). In this config we configuring Postfix at ports 25, 465 и 587. In master.cf we configuring auxiliary services for Postfix: &lt;br /&gt;
&lt;br /&gt;
   submission   inet  n  -  n  -  -  smtpd:&lt;br /&gt;
&lt;br /&gt;
   submission — service name. In this example '''submission''' is used for MUA at port 587 during message sending.&lt;br /&gt;
&lt;br /&gt;
   inet — type of the service. Possible cases: inet (TCP/IP socket), unix (stream socket), unix-dgram (datagram socket), fifo (named queue channel), pass (stream socket UNIX).&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;n&amp;quot; — whether service private or limited. Possible cases: y or n. For inet service type it should be only n.&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;-&amp;quot; — whether service works with root rights. Possible cases: y, n or -. &amp;quot;-&amp;quot; means that this options doesn't applied to this service.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;n&amp;quot; — whether the service should work in chroot. Possible cases: y или n.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;-&amp;quot; — in what time the service should be awaked if one is inactive.&lt;br /&gt;
&lt;br /&gt;
   третий &amp;quot;-&amp;quot; — the maximum number of child processes of this service.&lt;br /&gt;
&lt;br /&gt;
   smtpd — running command.&lt;br /&gt;
&lt;br /&gt;
   * the following are the arguments for running the command:&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_security_level — TLS security level.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — sasl auth type.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — temp files path.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl options.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_local_domain — smtp-auth users' domain.&lt;br /&gt;
&lt;br /&gt;
   syslog_name — log prefix of the service in the syslog.&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_wrappermode — whether running service in custom mode (for TLS support).&lt;br /&gt;
&lt;br /&gt;
   smtpd_client_restrictions — limit clients' connections. allow only authorized clients.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the file&lt;br /&gt;
 submission   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=may&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_sasl_type=dovecot&lt;br /&gt;
   -o smtpd_sasl_path=/var/spool/postfix/private/auth&lt;br /&gt;
   -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
   -o smtpd_sasl_local_domain=$myhostname&lt;br /&gt;
 smtps   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o syslog_name=postfix/smtps&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
 dovecot   unix  -  n  n  -  -  pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient}&lt;br /&gt;
&lt;br /&gt;
Log configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postconf maillog_file=/var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable postfix --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot dovecot-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mailboxes path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
 mail_home = /home/mail/%d/%u&lt;br /&gt;
 ...&lt;br /&gt;
Listener for the auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* auth service and 2 listeners:&lt;br /&gt;
&lt;br /&gt;
'''/var/spool/postfix/private/auth''' for Dovecot auth ('''/var/spool/postfix/private/auth''' is a '''private/auth''' in Postfix),&lt;br /&gt;
&lt;br /&gt;
'''auth-userdb''' - '''dovecot-lda''' auth socket, '''666''' means any user can use it, '''user and group''' - socket owner&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 service auth {&lt;br /&gt;
   unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0666&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
   }&lt;br /&gt;
   unix_listener auth-userdb {&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * otherwise we will see an error: '''net_connect_unix(/var/run/dovecot/stats-writer) failed permission denied''', because vmail user doesn't has specific rights.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the conf&lt;br /&gt;
 &lt;br /&gt;
 service stats {&lt;br /&gt;
    unix_listener stats-reader {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
    unix_listener stats-writer {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Dovecot auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-auth.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * comment common auth and add sql-auth.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;!include auth-system.conf.ext&lt;br /&gt;
 !include auth-sql.conf.ext&lt;br /&gt;
 ...&lt;br /&gt;
Encryption configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_cert = &amp;lt;/etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_key = &amp;lt;/etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; TLS SNI (Server Name Indication) support (https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Individual cert for each domain&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; It is important to note that having multiple SSL certificates per IP will not be compatible with all clients, especially mobile ones. It is a TLS SNI limitation.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Default cert&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 &lt;br /&gt;
 local_name mail.ladavoronezh.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 local_name mail.don661.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dirs autocreation during the first login a mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 lda_mailbox_autocreate = yes&lt;br /&gt;
 ...&lt;br /&gt;
Connect to DB configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/auth-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * config for getting users' name and password. It's a default config.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 passdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 userdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Connect to mysql configure&amp;lt;blockquote&amp;gt;   * getting data from mysql (mariadb).&lt;br /&gt;
&lt;br /&gt;
'''password_query''' — request for getting password from the '''mailbox''' table;&lt;br /&gt;
&lt;br /&gt;
'''user_query''' — request for getting user's data (home dir, id 1024 (it's a '''vmail''' user id).&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&lt;br /&gt;
 driver = mysql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=PassWord#1&lt;br /&gt;
 default_pass_scheme = MD5-CRYPT&lt;br /&gt;
 password_query = SELECT password FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
Interface for dovecot listening&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 listen = *&lt;br /&gt;
 ...&lt;br /&gt;
 log_path = /var/log/dovecot.log&lt;br /&gt;
 info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
 debug_log_path = /var/log/dovecot-debug.log&lt;br /&gt;
 &lt;br /&gt;
 # debug log (DON'T ENABLE IT BY DEFAULT, ONLY IN DEBUG CASES)&lt;br /&gt;
 ###mail_debug = yes&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable dovecot --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/dovecot*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin. First domain and mailbox creating ===&lt;br /&gt;
Go to the Postfixadmin Web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/postfixadmin/public&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create domain yourdomain.ru&lt;br /&gt;
* Create Mailbox cless@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
=== Roundcube ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube Webmail config defaults.inc.php default parameters:&lt;br /&gt;
&lt;br /&gt;
https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://github.com/roundcube/roundcubemail/releases/download/1.6.1/roundcubemail-1.6.1-complete.tar.gz&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $config['db_dsnw'] = 'mysql://roundcube:PassWord#1@localhost/roundcubemail';&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 $config['enable_installer'] = true;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 // Comment&lt;br /&gt;
 &lt;br /&gt;
 //$config['smtp_host'] = 'localhost:587';&lt;br /&gt;
 //$config['smtp_user'] = '%u';&lt;br /&gt;
 //$config['smtp_pass'] = &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // Add&lt;br /&gt;
 &lt;br /&gt;
 $config['smtp_host'] = 'tls://localhost';&lt;br /&gt;
 $config['smtp_conn_options'] = array(&lt;br /&gt;
   'ssl' =&amp;gt; array(&lt;br /&gt;
   'verify_peer' =&amp;gt; false,&lt;br /&gt;
   'verify_peer_name' =&amp;gt; false,&lt;br /&gt;
 ),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
 # web session timeout (in minutes)&lt;br /&gt;
 $config['session_lifetime'] = 1440;&lt;br /&gt;
 ...&lt;br /&gt;
 // If true all folders will be checked during AUTO-REFRESH for recent messages (Otherwise only standard folders will be checked, like Inbox or SPAM)&lt;br /&gt;
 $config['check_all_folders'] = true;&lt;br /&gt;
 &lt;br /&gt;
 // default roundcube webmail interface language&lt;br /&gt;
 $config['language'] = 'ru_RU';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''$config['create_default_folders'] = true''' (creating dirs by default (if there's lack of ones)):&lt;br /&gt;
&lt;br /&gt;
'''Drafts''' — Messages drafts.&lt;br /&gt;
&lt;br /&gt;
'''Junk''' — SPAM.&lt;br /&gt;
&lt;br /&gt;
'''Sent''' — Sent messages.&lt;br /&gt;
&lt;br /&gt;
'''Trash''' — Trash bin for messages.&lt;br /&gt;
&lt;br /&gt;
* It's necessary to avoid errors, for example during receiving or deleting messages.&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# Add at the end of the file&lt;br /&gt;
&lt;br /&gt;
$config['drafts_mbox'] = 'Drafts';&lt;br /&gt;
$config['junk_mbox'] = 'Junk';&lt;br /&gt;
$config['sent_mbox'] = 'Sent';&lt;br /&gt;
$config['trash_mbox'] = 'Trash';&lt;br /&gt;
$config['create_default_folders'] = true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create roundcubemail DB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply template&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p roundcubemail &amp;lt; /usr/share/nginx/html/webmail/SQL/mysql.initial.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install php php-common php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-zip php-imagick php-gd php-fpm php php-pdo php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP configure&amp;lt;blockquote&amp;gt;* necessary to create message size limit&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 date.timezone = &amp;quot;Europe/Moscow&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 30M&lt;br /&gt;
 ...&lt;br /&gt;
 upload_max_filesize = 30M&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 http {&lt;br /&gt;
    ...&lt;br /&gt;
    client_max_body_size 30M;&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/webmail/installer/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After web installation - disable installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['enable_installer'] = false;&lt;br /&gt;
 ...&lt;br /&gt;
Remove installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\rm -R /usr/share/nginx/html/webmail/installer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quota Dovecot + PostfixAdmin ===&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=quota-dovecot-postfixadmin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * plugin to create quotas.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 mail_plugins = $mail_plugins quota&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-imap.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''mail_plugins'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {&lt;br /&gt;
   mail_plugins = $mail_plugins imap_quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 service dict {&lt;br /&gt;
    unix_listener dict {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-quota.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''quota = dict:User quota::proxy::quota'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 plugin {&lt;br /&gt;
   quota = dict:User quota::proxy::quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 dict {&lt;br /&gt;
   quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Create config file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-dict-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Mysql connection&lt;br /&gt;
&lt;br /&gt;
'''host''' — mysql server host;&lt;br /&gt;
&lt;br /&gt;
'''dbname''' — db containing postfix users;&lt;br /&gt;
&lt;br /&gt;
'''user''' — db user;&lt;br /&gt;
&lt;br /&gt;
'''password''' — db password.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 connect = '''host'''=localhost '''dbname'''=postfix '''user'''=postfix '''password'''=PassWord#1&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/storage&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/messages&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *if you have several '''user_query''' in your config, create query for the last one.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find &amp;quot;user_query&amp;quot; and put into this line: '''CONCAT('*:bytes=', quota) AS quota_rule'''&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid, '''''CONCAT('*:bytes=', quota) AS quota_rule''''' FROM mailbox WHERE username = '%u'&lt;br /&gt;
 ...&lt;br /&gt;
Check dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveconf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout-Login into Roundcube webmail.&lt;br /&gt;
&lt;br /&gt;
At the foot of the page there'll be a quota appear.&lt;br /&gt;
&lt;br /&gt;
=== Clamav + Amavisd ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavisd-new clamd perl-Digest-SHA1 perl-IO-stringy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rsyslog is necessary to write SPAM and VIRUS log to /var/log/maillog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y rsyslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now rsyslog.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $mydomain = 'yourdomain.ru';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 $log_level = 0;              # verbosity 0..5, -d&lt;br /&gt;
 $log_recip_templ = undef;    # disable by-recipient level-0 log entries&lt;br /&gt;
 $do_syslog = 1;              # log via syslogd (preferred)&lt;br /&gt;
 $syslog_facility = 'mail';   # Syslog facility as a string&lt;br /&gt;
            # e.g.: mail, daemon, user, local0, ... local7&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $myhostname = 'mail02.yourdomain.ru';&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add before line &amp;quot;'''''1;  # insure a defined return value'''''&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $allowed_header_tests{'multiple'} = 0;&lt;br /&gt;
 $allowed_header_tests{'missing'} = 0;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/clamd.d/scan.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Uncomment&lt;br /&gt;
 TCPSocket 3310&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable clamd@scan --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable amavisd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postfix settings&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''content_filter''' - point to application, which ьуфте to scan messages;&lt;br /&gt;
&lt;br /&gt;
'''receive_override_options''' - allow you to see original email addresses with viruses.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10024&lt;br /&gt;
 receive_override_options = no_address_mappings&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10025 (сервис без имени, он просто будет слушать на порту 10025 — это порт по умолчанию, на который отправляет сообщение amavis после выполнения проверки). Также, мы используем следующие опции:&lt;br /&gt;
&lt;br /&gt;
   smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.&lt;br /&gt;
&lt;br /&gt;
   smtp_enforce_tls — требовать ли TLS.&lt;br /&gt;
&lt;br /&gt;
   content_filter — приложение для сканирования. В данном примере сканирование отключено.&lt;br /&gt;
&lt;br /&gt;
   receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.&lt;br /&gt;
&lt;br /&gt;
   пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.&lt;br /&gt;
&lt;br /&gt;
   smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.&lt;br /&gt;
&lt;br /&gt;
   mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.&lt;br /&gt;
&lt;br /&gt;
   smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 scan   unix  -  -  n  -  16  smtp&lt;br /&gt;
   -o smtp_send_xforward_command=yes&lt;br /&gt;
   -o smtp_enforce_tls=no&lt;br /&gt;
 127.0.0.1:10025   inet  n  -  n  -  16  smtpd&lt;br /&gt;
   -o content_filter=&lt;br /&gt;
   -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
   -o smtpd_helo_restrictions=&lt;br /&gt;
   -o smtpd_client_restrictions=&lt;br /&gt;
   -o smtpd_sender_restrictions=&lt;br /&gt;
   -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
   # '''OR, if you want to restrict sending emails by users with inexistened local domains, etc.:'''&lt;br /&gt;
   # '''(You can see logs of PASSED o DROPPED emails in ''/var/log/maillog'' after sending them''')&lt;br /&gt;
   # '''-o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject'''&lt;br /&gt;
   -o mynetworks_style=host&lt;br /&gt;
   -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clamd update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y clamav-update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/freshclam.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Choose one of the update mirrors&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://clamav.jinr.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://packages.microsoft.com/clamav/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 DatabaseMirror pivotal-clamav-mirror.s3.amazonaws.com&lt;br /&gt;
 ...&lt;br /&gt;
Then remove the freshclam.dat file and restart the service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rm -f /var/lib/clamav/freshclam.dat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart clamav-freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Antispam DB update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sa-update --nogpg --verbose&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cron&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 15 3 * * * /bin/freshclam&lt;br /&gt;
 30 3 * * * /bin/sa-update&lt;br /&gt;
Antivirus checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&lt;br /&gt;
The email will never come, and you will see the following in the logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17688]: (17688-04) Blocked INFECTED (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... relay=127.0.0.1[127.0.0.1]:10024, delay=0.25, delays=0.19/0/0/0.06, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17688-04 - INFECTED: Eicar-Signature)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Redirect SPAM to user's SPAM-directory using Amavis service ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis dovecot-pigeonhole dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * закомментированная строка указывала, что файл с настройками находится в домашней директории каждого пользователя. Мы же будем делать централизованный конфиг в файле /etc/dovecot/sieve/default.sieve.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;sieve = file:~/sieve;active=~/.dovecot.sieve&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 sieve = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавили плагин sieve. Также необходимо со строки снять комментарий, если он был.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lda {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-lmtp.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * также мы добавили плагин sieve + необходимо со строки снять комментарий, если он есть.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lmtp {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/sieve/default.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы ищем в заголовках X-Spam-Flag и отправляем такие письма в папку Junk.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R vmail:vmail /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по умолчанию стоит значение D_DISCARD, что означает, что сообщения будут отклонятся. Нам же нужно D_PASS — пропускать.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $final_spam_destiny = D_PASS;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SPAM filter checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
The email will be appear inthe SPAM-directory, any you will see in the logs:&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17689]: (17689-04) Blocked SPAM {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... status=sent (250 2.7.0 Ok, discarded, id=17689-04 - spam)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Logrotate of mail logs ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/logrotate.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# see &amp;quot;man logrotate&amp;quot; for details&lt;br /&gt;
# rotate log files weekly&lt;br /&gt;
weekly&lt;br /&gt;
&lt;br /&gt;
# keep 4 weeks worth of backlogs&lt;br /&gt;
rotate 4&lt;br /&gt;
&lt;br /&gt;
# create new (empty) log files after rotating old ones&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
# use date as a suffix of the rotated file&lt;br /&gt;
dateext&lt;br /&gt;
&lt;br /&gt;
# uncomment this if you want your log files compressed&lt;br /&gt;
compress&lt;br /&gt;
&lt;br /&gt;
# RPM packages drop log rotation information into this directory&lt;br /&gt;
include /etc/logrotate.d&lt;br /&gt;
&lt;br /&gt;
# system-specific logs may be also be configured here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;nano /etc/logrotate.d/mail&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/var/log/dovecot-debug.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot-info.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/postfix.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/maillog {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Check a cron daily task. It should already exist&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/cron.daily/logrotate&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/logrotate /etc/logrotate.conf&lt;br /&gt;
EXITVALUE=$?&lt;br /&gt;
if [ $EXITVALUE != 0 ]; then&lt;br /&gt;
    /usr/bin/logger -t logrotate &amp;quot;ALERT exited abnormally with [$EXITVALUE]&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
exit $EXITVALUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Wait for a daily task to complete&lt;br /&gt;
&lt;br /&gt;
Or you can run the logrotate manually:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;logrotate -f /etc/logrotate.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Improving email deliverability (VERY IMPORTANT!) =&lt;br /&gt;
https://www.linuxbabe.com/mail-server/centos-7-iredmail-email-server&lt;br /&gt;
&lt;br /&gt;
To prevent your emails from being flagged as spam, you should set PTR, SPF, DKIM and DMARC records.&lt;br /&gt;
&lt;br /&gt;
=== PTR записи на DNS сервере ===&lt;br /&gt;
&lt;br /&gt;
==== Описание ====&lt;br /&gt;
Запись PTR прописывается _НЕ_ в ресурсных записях днс-сервера, к которому привязан ваш почтовый домен, это делает именно регистратор ip-адреса (провайдер или хостер, предоставляющий внешний ip-адрес)! Если провайдер ростелеком, пишем на электронку support@tmb.ru с просьбой зарегистрировать ptr-запись, штатная техподдержка отказывается предоставлять такую услугу&lt;br /&gt;
&lt;br /&gt;
Если у вас есть свой почтовый сервер, то необходимо, чтобы ваш провайдер (а точнее тот, кто выдал вам статические ip-адреса. если ваш внешний IP предоставил вам хостер, на котором у вас крутится VPS/VDS, то обращаемся в техподдержку хостера) зарегистрировал на своем DNS-сервере PTR записи для вашего почтового сервера (MX-записи). Иначе, подавляющая часть почтовых серверов интернета откажется принимать почту от вашего почтового сервера.&lt;br /&gt;
&lt;br /&gt;
Так же, многие почтовые сервера отвергают письма, если при проверке адреса отправителя в строке им выдается &amp;quot;dynamicip&amp;quot; или &amp;quot;dsl&amp;quot; или подобные слова означающие, что ваш адрес не статический или не совпадает с именем вашего домена.&lt;br /&gt;
&lt;br /&gt;
Если в ответе сервера на ваше отправленное письмо вы видите что-то типа:&lt;br /&gt;
&lt;br /&gt;
  mxs.mail.ru: 550 Sorry, we do not accept mail from hosts with dynamic IP or generic DNS PTR-records. Please get a custom reverse DNS name from your ISP for your host 215.54.54.54 or contact abuse@corp.mail.ru in case of error&lt;br /&gt;
&lt;br /&gt;
это значит, что вам необходимо корректно зарегистрировать PTR запись на DNS-сервере для вашего доменного имени.&lt;br /&gt;
&lt;br /&gt;
Для этого необходимо послать запрос тому, кто выдал вам статические ip-адреса (обычно, это ваш провайдер) с просьбой зарегистрировать PTR запись для вашего домена.&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть одна для одного IP (не нужно создавать две записи для основного домена (mydomain.ru) и почтового домена (mail.mydomain.ru) если оба они привязаны А-записью к одному IP)&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть создана именно для MX записи. То есть, если адреса домена и почтового обменника не совпадают, то PTR создаем именно для MX записи.&lt;br /&gt;
&lt;br /&gt;
Например, если домен mydomain.ru находится по адресу 22.11.33.44, а почтовый обменник (MX запись) создана для хоста mail.mydomain.ru, расположенного по адресу 11.22.33.44, то и PTR запись нужно создавать для mail.mydomain.ru:&lt;br /&gt;
       44.33.22.11.in-addr.arpa  mail.mydomain.ru&lt;br /&gt;
  Естественно, можно &amp;quot;до кучи&amp;quot; создать обратную запись и для самого домена mydomain.ru. Она так же не помешает:&lt;br /&gt;
       44.33.11.22.in-addr.arpa  mydomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Резюмируя, необходимо сделать следующее: ====&lt;br /&gt;
1. Необходимо прописать ресурсную запись MX (MX 10 mail.yourdomain.ru.) для основного домена &amp;quot;yourdomain.ru&amp;quot;, указав что почтовым доменом MX-сервера является &amp;quot;mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делаем мы.&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего yourdomain.ru - 1.2.3.4   &lt;br /&gt;
   A yourdomain.ru 1.2.3.4&lt;br /&gt;
   MX 10 mail.yourdomain.ru.&lt;br /&gt;
2. Создать PTR-запись на DNS сервере регистратора&lt;br /&gt;
&lt;br /&gt;
IP домена &amp;quot;mail.yourdomain.ru&amp;quot; необязательно должен совпадать с IP &amp;quot;yourdomain.ru&amp;quot;, но PTR-запись должна быть создана регистратором IP-адреса (5.6.7.8) домена &amp;quot;mail.yourdomain.ru&amp;quot;. Если у нас несколько почтовых доменов на одном почтовом сервере и все они выходят через единственный внешний IP, то PTR соответствие необходимо прописать для домена, которым именуется (hostname) сам физический почтовый сервер.&lt;br /&gt;
&lt;br /&gt;
Например, сама физическая машина именуется mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
(&lt;br /&gt;
&lt;br /&gt;
Также для этого необходимо прописать &amp;quot;mail.yourdomain.ru&amp;quot; в следующих местах:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname mail.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cоответствие внешнего IP, для которого создаем PTR-запись, и домена mail.yourdomain.ru прописываем в /etc/hosts)&lt;br /&gt;
 ...&lt;br /&gt;
 45.67.59.224 mail.yourdomain.ru&lt;br /&gt;
Изменить настройки postfix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 myhostname = mail.yourdomain.ru&lt;br /&gt;
 myorigin = mail.yourdomain.ru&lt;br /&gt;
 mydomain = mail.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
mail.yourdomain.ru не обязан вообще быть почтовым доменом, но он будет в поле &amp;quot;helo: mail.yourdomain.ru&amp;quot; при отправке письма с любого другого почтового домена, работающего на нашем почтовом сервере. поэтому создаем ptr-запись именно для mail.yourdomain.ru - &amp;quot;8.7.6.5.in-addr.arpa mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делает регистратор внешнего IP&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего mail.yourdomain.ru 5.6.7.8&lt;br /&gt;
   8.7.6.5.in-addr.arpa mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Проверки ====&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host 5.6.7.8&amp;lt;/code&amp;gt;&lt;br /&gt;
       ...&lt;br /&gt;
       8.7.6.5.in-addr.arpa domain name pointer mail.yourdomain.ru.&lt;br /&gt;
       ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
Например, для домена mydomain.ru с адресом 215.54.54.54, необходимо зарегистрировать следующую запись:&lt;br /&gt;
       54.54.54.215.in-addr.arpa name=mydomain.ru&lt;br /&gt;
А если почтовый сервер сидит на отдельном адресе, например, mail.mydomain.ru имеет адрес 215.54.54.55, то необходимо зарегистрировать еще одну PTR запись:&lt;br /&gt;
       55.54.54.215.in-addr.arpa name=mail.mydomain.ru&lt;br /&gt;
Проверить наличие PTR записи на сервере DNS можно с помощью интерфейса команды NSLOOKUP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nslookup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь подключаемся к DNS-серверу провайдера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;server 215.54.54.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Устанавливаем тип ресурсной записи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set type=PTR&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Делаем запрос на интересующий нас адрес:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;215.54.54.54&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ответ мы должны получить имя своего домена mydomain.ru&lt;br /&gt;
&lt;br /&gt;
=== SPF ===&lt;br /&gt;
SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain. In your DNS management interface, create a new TXT record like below.&lt;br /&gt;
&lt;br /&gt;
Add TXT-record to your main domain (for example &amp;quot;yourdomain.ru&amp;quot;, _NOT_ subdomain &amp;quot;mail.yourdomain.ru&amp;quot;!)&lt;br /&gt;
 A yourdomain.ru 45.67.59.224&lt;br /&gt;
 MX 10 mail.yourdomain.ru.&lt;br /&gt;
 TXT v=spf1 mx ~all&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   yourdomain.ru.              10      IN      TXT     &amp;quot;v=spf1 mx ~all&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DKIM ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Add first mail domain ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to add second and following as well as the first&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/lib/dkim&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate PEM for our domain&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; domain.ru - the first domain, for wich we generated dkim&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;amavisd genrsa /var/lib/dkim/dmosk.ru.pem 1024&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown amavis:amavis /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 0400 /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;$inet_socket_port = 10024;&lt;br /&gt;
 &lt;br /&gt;
 # Add&lt;br /&gt;
 &lt;br /&gt;
 $inet_socket_port = [10024,10026];&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find this string (its value must be &amp;quot;1&amp;quot;)&lt;br /&gt;
 $enable_dkim_verification = 1;  # enable DKIM signatures verification&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; After the string above add following&lt;br /&gt;
 &lt;br /&gt;
 dkim_key('yourdomain.ru', &amp;quot;dkim&amp;quot;, &amp;quot;/var/lib/dkim/yourdomain.ru.pem&amp;quot;);&lt;br /&gt;
 @dkim_signature_options_bysender_maps = ( {&lt;br /&gt;
   &amp;quot;yourdomain.ru&amp;quot; =&amp;gt; { d =&amp;gt; &amp;quot;yourdomain.ru&amp;quot;, a =&amp;gt; 'rsa-sha256', ttl =&amp;gt; 10*24*3600 },&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; FIND THIS STRING. ITS VALUE MUST BE &amp;quot;1&amp;quot;&lt;br /&gt;
 $enable_dkim_signing = 1;    # load DKIM signing code, keys defined by dkim_key&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generate record for DNS server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf showkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   dkim._domainkey.yourdomain.ru.      3600 TXT (&lt;br /&gt;
   &amp;quot;v=DKIM1; p=&amp;quot;&lt;br /&gt;
   &amp;quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz&amp;quot;&lt;br /&gt;
   &amp;quot;3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUg&amp;quot;&lt;br /&gt;
   &amp;quot;jOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0J&amp;quot;&lt;br /&gt;
   &amp;quot;xfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9O&amp;quot;&lt;br /&gt;
   &amp;quot;YO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61N&amp;quot;&lt;br /&gt;
   &amp;quot;rJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVh&amp;quot;&lt;br /&gt;
   &amp;quot;kwIDAQAB&amp;quot;)&lt;br /&gt;
   ...&lt;br /&gt;
Copy it from &amp;quot;&amp;quot;v=DKIM1...&amp;quot; to &amp;quot;...kwIDAQAB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove all &amp;quot;&amp;quot; and line breaks&lt;br /&gt;
&lt;br /&gt;
You'll get something like this (in one line):&lt;br /&gt;
 v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Create subdomain &amp;quot;dkim._domainkey&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;dkim._domainkey&amp;quot; subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 TXT v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test at mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf testkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   TESTING#1 yourdomain.ru: dkim._domainkey.yourdomain.ru =&amp;gt; pass&lt;br /&gt;
   ...&lt;br /&gt;
Test on arbitrary server in internet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig dkim._domainkey.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   dkim._domainkey.yourdomain.ru. 10   IN      TXT     &amp;quot;v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjz&amp;quot; &amp;quot;zr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DMARC ===&lt;br /&gt;
DMARC stands for Domain-based Message Authentication, Reporting and Conformance. DMARC can help receiving email servers to identify legitimate emails and prevent your domain name from being used by email spoofing.&lt;br /&gt;
&lt;br /&gt;
To create a DMARC record, go to your DNS manager and add a TXT record. In the name field, enter _dmarc. In the value field, enter the following. (You should create the dmarc@your-domain.com email address.)&lt;br /&gt;
&lt;br /&gt;
Create subdomain &amp;quot;_dmarc&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;_dmarc&amp;quot; (_dmarc.yourdomain.ru) subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 A 45.67.59.224&lt;br /&gt;
 TXT v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig _dmarc.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
  �;; ANSWER SECTION:&lt;br /&gt;
   _dmarc.yourdomain.ru.       10      IN      TXT     &amp;quot;v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
General deliverability test&lt;br /&gt;
&lt;br /&gt;
Go to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://www.mail-tester.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send email from your mail account of your new mail server to randomly generated service's mail address (test-avlwah6p3@srv1.mail-tester.com, for example)&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Затем проверьте оценку&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wait for tests passed&lt;br /&gt;
&lt;br /&gt;
If your score higher than 8, congratulations! &lt;br /&gt;
&lt;br /&gt;
= Add additional mail domain =&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
Root domain and MX-record, which point to the for mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=cless.pro mx-exchange=mail.cless.pro mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.cless.pro address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL certs ===&lt;br /&gt;
&lt;br /&gt;
==== Lentencrypt ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail.cless.pro,mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certs ====&lt;br /&gt;
Add additional cert configs for a new domain for '''Nginx''', '''Postfix''' and '''Dovecot'''.&lt;br /&gt;
&lt;br /&gt;
=== Improving email deliverability ===&lt;br /&gt;
Check the '''Improving email deliverability''' section of this manual and do corresponding actions.&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin web panel ===&lt;br /&gt;
&lt;br /&gt;
* Create domain cless.pro&lt;br /&gt;
* Create mailbox cless@cless.pro&lt;br /&gt;
&lt;br /&gt;
=== Roundcube webmail ===&lt;br /&gt;
Login to Roundcube webmail&lt;br /&gt;
&lt;br /&gt;
Send/Receive email&lt;br /&gt;
&lt;br /&gt;
= Autodiscover Mail Server settings for Mail Clients =&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=autodiscover-mail&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
It provides mail clients Mail Server connection info during configuring Mail Client mailbox&lt;br /&gt;
&lt;br /&gt;
=== Thinderbird ===&lt;br /&gt;
Механизм автонастройки от Mozilla похож на Microsoft. Необходимые настройки должны отдаваться веб-сервером в виде XML-документа. Однако запрос не https, а http; и не POST, а GET. Также обращение идет сначала в формате '''server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain''', и если ответ не будет получен — '''autoconfig.server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain'''.&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;Create А-record (or CNAME) for root domain (example.com):&amp;lt;blockquote&amp;gt;''* где  '''111.111.111.111''' — IP-address of web server, with XML.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 autoconfig    IN      A       111.111.111.111&lt;br /&gt;
&lt;br /&gt;
==== Nginx config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/910-autodiscover_example.ru.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
# HTTP&lt;br /&gt;
server {&lt;br /&gt;
    listen 80;&lt;br /&gt;
    server_name autoconfig.example.com;&lt;br /&gt;
    root /usr/share/nginx/html/autodiscover/example.com;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autodiscover config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /usr/share/nginx/html/autodiscover/example.ru/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/autodiscover/example.ru/mail/config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;emailProvider id=&amp;quot;example.com&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;domain&amp;gt;example.com&amp;lt;/domain&amp;gt;&lt;br /&gt;
                &amp;lt;displayName&amp;gt;Mail example.com&amp;lt;/displayName&amp;gt;&lt;br /&gt;
                &amp;lt;displayShortName&amp;gt;example.com&amp;lt;/displayShortName&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;143&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;pop&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;pop.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;995&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;SSL&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;587&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/outgoingServer&amp;gt;&lt;br /&gt;
        &amp;lt;/emailProvider&amp;gt;&lt;br /&gt;
&amp;lt;/clientConfig&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simpliest method according to the RFC standard (I'm not sure that it works) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;It works in unstable way. The mail client usually managed to get mail server info, but not everything. Mail client gets '''hosts''' (for example, imap.yourdomain.ru), but not the '''ports'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
You need to add ''subdomains'' for your ''main domain'' '''yourdomain.ru''' and create '''SRV''' records&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
 _&amp;lt;service name&amp;gt;._&amp;lt;protocol&amp;gt; &amp;lt;priority&amp;gt; &amp;lt;weight&amp;gt; &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;&lt;br /&gt;
Examples&lt;br /&gt;
 _smtp._tcp              IN SRV  10 0 25  smtp.yourdomain.ru.&lt;br /&gt;
 _pop3._tcp              IN SRV  20 0 110 pop.yourdomain.ru.&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _smtps._tcp             IN SRV   0 0 465 smtp.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
 _imaps._tcp             IN SRV   0 0 993 imap.yourdomain.ru.&lt;br /&gt;
 _pop3s._tcp             IN SRV  10 0 995 pop.yourdomain.ru.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
To give your mail clients info about '''imap''' and '''smtp''' settings of your mail server:&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
&lt;br /&gt;
= Full-text search =&lt;br /&gt;
&lt;br /&gt;
== Fts-xapian ('''It works good!''') ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://github.com/grosjo/fts-xapian]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/#community-developed-plugins]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/settings/plugin/fts-plugin/]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin]&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
Dovecot has some problems with email searching if there's a huge amount of emails in the mailbox. It can perodically throw an error &amp;quot;Server error&amp;quot; during the search.&lt;br /&gt;
&lt;br /&gt;
To avoid such problems we can use Full-text search.&lt;br /&gt;
&lt;br /&gt;
=== Build plugin ===&lt;br /&gt;
&lt;br /&gt;
==== Variant 1. Build plugin at the same machine ====&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
==== Variant 2. Build plugin at the another machine with the same arch and apps versions, and copy compiled plugin to the mail server ====&lt;br /&gt;
&lt;br /&gt;
===== Another machine for building =====&lt;br /&gt;
Build plugin at the another machine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy plugin to the mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rsync -avPh /usr/lib64/dovecot/lib21_fts_xapian_plugin.* root@&amp;lt;mail-server-IP&amp;gt;:/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== Configure plugin at the mail server ===&lt;br /&gt;
Check the installed plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /usr/lib64/dovecot/lib21_fts_xapian_plugin.*&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     -rw-r--r-- 1 root root 2.9M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.a&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.1K Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.la&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.2M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.so&lt;br /&gt;
     ...&lt;br /&gt;
Add plugin to the common conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
mail_plugins = $mail_plugins &amp;lt;...&amp;gt; fts fts_xapian&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Add plugin config&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/95-fts.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;partial=2 - the minimum length of the search string&lt;br /&gt;
&lt;br /&gt;
fts_autoindex = yes/no - whether to run reindex in background or not. TAKES A LOT OF RESOURCES CONSTANTLY AND MIGHT FAIL USER SEARCH. BETTER RUN MANUAL REINDEX: '''doveadm index -u user@domain.ru \*'''&lt;br /&gt;
&lt;br /&gt;
fts_enforced = yes/no - The system must use Xapian for full-text search. Alternative search backends are disabled or not permitted. All text indexing will be handled by Xapian&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
plugin {&lt;br /&gt;
    fts = xapian&lt;br /&gt;
    fts_xapian = partial=2 full=20 attachments=0 verbose=0&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex = yes&lt;br /&gt;
    fts_enforced = yes&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex_exclude = \Trash&lt;br /&gt;
&lt;br /&gt;
    # Index attachements&lt;br /&gt;
    fts_decoder = decode2text&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service indexer-worker {&lt;br /&gt;
    # Increase vsz_limit to 2GB or above.&lt;br /&gt;
    # Or 0 if you have rather large memory usable on your server, which is preferred for performance)&lt;br /&gt;
    vsz_limit = 2G&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service decode2text {&lt;br /&gt;
    executable = script /usr/libexec/dovecot/decode2text.sh&lt;br /&gt;
    user = dovecot&lt;br /&gt;
    unix_listener decode2text {&lt;br /&gt;
        mode = 0666&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot and check the service status. There shouldn't be errors or warnings in the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's necessary to index all the mailboxes if you have already had productive and filled mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm index -u $i \*; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm index -u user@domain.ru \*&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
       '''fts optimize'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts optimize [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
&lt;br /&gt;
       '''fts rescan'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts rescan [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Scan what mails exist in the full text search index and compare those to what actually exist in mailboxes.  This removes mails from the index that have already been expunged and makes sure&lt;br /&gt;
&lt;br /&gt;
           that  the  next  doveadm index will index all the missing mails (if any). Note that currently most FTS backends do not implement this properly, but instead they delete all the FTS indexes.&lt;br /&gt;
&lt;br /&gt;
           This may change in the future versions.&amp;lt;/blockquote&amp;gt;Place the task to optimize your xapian indexes into the crontab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
 0 4 * * * for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts optimize -u $i; done&lt;br /&gt;
 ...&lt;br /&gt;
Optionally&amp;lt;blockquote&amp;gt;I'm not sure this is really necessary&lt;br /&gt;
&lt;br /&gt;
It takes a lot of time and during this process the search doesn't work&lt;br /&gt;
&lt;br /&gt;
Also, after the rescan, the directories &amp;quot;/home/mail/&amp;lt;domain&amp;gt;/&amp;lt;user&amp;gt;/xapian-indexes/db_*&amp;quot; will be deleted, and they will be created only after a user will click on the directories in the web-interface. It takes also a lot of time&lt;br /&gt;
&lt;br /&gt;
You can rescan indexes of your mailboxes&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts rescan -u $i; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm fts rescan -u user@domain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the console&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y telnet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;telnet localhost imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a login user@don661.ru PassWord#1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a select Inbox&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a SEARCH text &amp;quot;test&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the '''Roundcube Webmail'''&amp;lt;blockquote&amp;gt;In '''Roundcube Webmail''' for the searching of text in the message body it's necessary to click on the arrow right to the search field and to check &amp;quot;'''Message body'''&amp;quot; as a search source!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SOLR ('''I didn't test it!''') ==&lt;br /&gt;
https://doc.dovecot.org/configuration_manual/fts/solr/&lt;br /&gt;
&lt;br /&gt;
== Fts-elastic ('''I didn't test it!''') ==&lt;br /&gt;
https://github.com/filiphanes/fts-elastic&lt;br /&gt;
&lt;br /&gt;
= Postfix limits (I didn't test it!) =&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=postfix-limits#mailbox-size&lt;br /&gt;
&lt;br /&gt;
= Desktop mail clients =&lt;br /&gt;
&lt;br /&gt;
=== Thunderbird ===&lt;br /&gt;
'''IMAP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 143&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
'''SMTP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 587&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
= Hints =&lt;br /&gt;
&lt;br /&gt;
== Mail queue check ==&lt;br /&gt;
&amp;lt;code&amp;gt;mailq&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show connected users ==&lt;br /&gt;
Users IMAP (via mail clients)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm who&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users WEB Roundcube&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;netstat -an | grep :443 | grep -v TIME_WAIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restrict sending emails by local users with non-existing local domains in the field ''FROM'' ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 -o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject&lt;br /&gt;
 ...&lt;br /&gt;
You can see logs of PASSED o DROPPED emails in '''/var/log/maillog''' after sending them.&lt;br /&gt;
&lt;br /&gt;
== Reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files) ==&lt;br /&gt;
https://serverfault.com/questions/694511/postfix-how-to-reject-sender-addresses-that-dont-exist-only-for-local-domains&lt;br /&gt;
&lt;br /&gt;
Add the following option to '''/etc/postfix/main.cf''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 smtpd_reject_unlisted_sender = yes&lt;br /&gt;
 ...&lt;br /&gt;
You can try to send an email with non-existing user in field FROM, and you will see a rejection in output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)&amp;lt;/code&amp;gt;&lt;br /&gt;
== Message size limit (message size itself + attached file size) ==&lt;br /&gt;
You have to set limits in the each following entity.&lt;br /&gt;
&lt;br /&gt;
In this example we make limit at about ~30MB for attachment&lt;br /&gt;
&lt;br /&gt;
==== Postfix limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 message_size_limit = 46080000 # ~30MB (10240000 - ~10MB)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Roundcube limit ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube preserves some percentage of the max message size (search 1.33 on this page, so if you set the max to 100M, it tells you only 75MB is allowed (100 / 1.33). This is better because email messsage will be encoded before sending to MTA and the encoded attachment is larger than the original file.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['max_message_size'] = '40M'; # max summ message size (not file)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
==== Nginx limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 server {&lt;br /&gt;
     ...&lt;br /&gt;
     client_max_body_size 35M; # max size of a message&lt;br /&gt;
     client_body_timeout 300s; # timeout while upload attachment, otherwise upload may be canceled by timeout in case of a low upload speed, for example&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PHP limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 35M;&lt;br /&gt;
 upload_max_filesize = 35M;&lt;br /&gt;
 ...&lt;br /&gt;
reboot &lt;br /&gt;
&lt;br /&gt;
== Amount of attached files in an email ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; Maximum number of files that can be uploaded via a single request&lt;br /&gt;
 max_file_uploads = 50&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx.service php-fpm.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating users via CLI ==&lt;br /&gt;
&lt;br /&gt;
=== A single mailbox creation ===&lt;br /&gt;
Postfixadmin-cli installation&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;if you have already had installed postfixadmin, you don't have to do the following&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Help&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comment password validation limits (e.g. &amp;quot;# must contain at least 2 digits&amp;quot; or something you needed) in the array 'password_validation' of the postfix config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['password_validation'] = array(&lt;br /&gt;
 ...&lt;br /&gt;
 #    '/([0-9].*){2}/'        =&amp;gt; 'password_no_digits 2',      # must contain at least 2 digits&lt;br /&gt;
 ...&lt;br /&gt;
Create user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-cli mailbox add prod@domain123.ru --password &amp;quot;AlefStudioS*100&amp;quot; --password2 &amp;quot;AlefStudioS*100&amp;quot; --name &amp;quot;Компания AlefStudio&amp;quot; --quota &amp;quot;4096&amp;quot; --active --welcome-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mass mailboxes creation ===&lt;br /&gt;
Mailboxes list file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./mailboxes.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 john@domain.ru|pass1|John Smith&lt;br /&gt;
 ann@domain.ru|pass2|Анна Паста Бродерик-Иванова&lt;br /&gt;
Milbox creation script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Mass postfixadmin mailboxes creation by @ClessAlvein&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# VARS&lt;br /&gt;
&lt;br /&gt;
mailboxesListFile=&amp;quot;./USERS_lada-tambovavtocity.ru.txt&amp;quot;&lt;br /&gt;
mailboxQuota=&amp;quot;2048&amp;quot;&lt;br /&gt;
pfCli=&amp;quot;/usr/share/nginx/html/postfixadmin/scripts/postfixadmin-cli&amp;quot;&lt;br /&gt;
dateTimeCurrent=`date +%Y-%m-%d_%H-%M-%S`&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# SCRIPT START&lt;br /&gt;
&lt;br /&gt;
# declare array with mailbox data in the each line&lt;br /&gt;
declare -A arrayMailboxes;&lt;br /&gt;
&lt;br /&gt;
# getting each line from the file with each user's data&lt;br /&gt;
while IFS= read -r line || [[ &amp;quot;$line&amp;quot; ]];&lt;br /&gt;
do&lt;br /&gt;
  # getting user, pass, name from the line and put it to the assoc array key=value&lt;br /&gt;
  while IFS=&amp;quot;|&amp;quot; read &amp;quot;mailboxUserFromFile&amp;quot; &amp;quot;mailboxPassFromFile&amp;quot; &amp;quot;mailboxNameFromFile&amp;quot;;&lt;br /&gt;
  do&lt;br /&gt;
    # makeup&lt;br /&gt;
    echo &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # debug&lt;br /&gt;
    #echo &amp;quot;${mailboxUser}, ${mailboxPass}, ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # declare assoc array with each key as a bit mailbox's data&lt;br /&gt;
    declare -A arrayMailbox;&lt;br /&gt;
&lt;br /&gt;
    # each key is a bit of the mailbox's data&lt;br /&gt;
    arrayMailbox[arrayMailboxUser]=${mailboxUserFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxPass]=${mailboxPassFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxName]=${mailboxNameFromFile};&lt;br /&gt;
&lt;br /&gt;
    # for each bit of mailbox's data create var (user,pass,name)&lt;br /&gt;
    for key in &amp;quot;${!arrayMailbox[@]}&amp;quot;;&lt;br /&gt;
    do&lt;br /&gt;
      case $key in&lt;br /&gt;
      arrayMailboxUser)&lt;br /&gt;
        mailboxUser=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxPass)&lt;br /&gt;
        mailboxPass=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxName)&lt;br /&gt;
        mailboxName=${arrayMailbox[${key}]};;&lt;br /&gt;
      esac&lt;br /&gt;
    done&lt;br /&gt;
  done &amp;lt; &amp;lt;( echo ${line} )&lt;br /&gt;
&lt;br /&gt;
  # if ${mailboxName} is empty&lt;br /&gt;
  if [ -z &amp;quot;${mailboxName}&amp;quot; ]; then&lt;br /&gt;
    mailboxName=${mailboxUser}&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  # debug&lt;br /&gt;
  echo &amp;quot;mailboxUser: ${mailboxUser}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxPass: ${mailboxPass}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxName: ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  # create each mailbox&lt;br /&gt;
  ${pfCli} mailbox add ${mailboxUser} \&lt;br /&gt;
    --password &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --password2 &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --name &amp;quot;${mailboxName}&amp;quot; \&lt;br /&gt;
    --quota &amp;quot;${mailboxQuota}&amp;quot; \&lt;br /&gt;
    --active --welcome-mail \&lt;br /&gt;
    | tee -a ./log_${dateTimeCurrent}&lt;br /&gt;
&lt;br /&gt;
done &amp;lt; ${mailboxesListFile}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Create mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Roundcube Filter plugin (for email forwarding, sending copy of emails to another email, and other actions) ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=roundcube-managesieve&lt;br /&gt;
&lt;br /&gt;
We will use '''Roundcube managesieve plugin''' for that purpose&amp;lt;blockquote&amp;gt;* First off, check that there's no directory &amp;quot;sieve&amp;quot; in the &amp;quot;/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   * if you have already had '''mail_home = /home/vmail/%d/%u''' in this config, you have to edit it as deliberately '''mail_home = /home/vmail/%d/%u/sieve'''&lt;br /&gt;
&lt;br /&gt;
   * мы задаем опцию mail_home с путем до каталогов с почтой. Обратите внимание, что на вашем сервере настройка может быть другая и необходимо указать правильное значение. Переменные %d и %u указывают, соответственно, на имя домена и учетной записи.&lt;br /&gt;
 ...&lt;br /&gt;
 mail_home = /home/vmail/%d/%u/sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавляем плагин sieve, который должен теперь использоваться локальным агентом доставки lda.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocol lda {&lt;br /&gt;
   # Space separated list of plugins to load (default is global mail_plugins).&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-managesieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по аналогии с protocol lda, мы указываем на необходимость использования sieve&lt;br /&gt;
&lt;br /&gt;
   * мы указываем, что наш сервис будет работать на порту 4190&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocols = $protocols sieve&lt;br /&gt;
 ...&lt;br /&gt;
 service managesieve-login {&lt;br /&gt;
   inet_listener sieve {&lt;br /&gt;
     port = 4190&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *sieve — путь до файла с правилами. Указывается для каждого ящика с помощью переменных.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_path — путь до общего файла с правилами. Используется, если отсутствует файл по пути sieve.&lt;br /&gt;
&lt;br /&gt;
   *sieve_dir — путь до каталога с подключаемыми скриптами-правилами. Указывается для каждого почтового ящика.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_dir — путь до общего каталога с подключаемыми правилами. Используется, если отсутствует sieve_dir.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 plugin {&lt;br /&gt;
   sieve = /home/mail/%d/%u/sieve/dovecot.sieve&lt;br /&gt;
   sieve_global_path = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
   sieve_dir = /home/mail/%d/%u/sieve&lt;br /&gt;
   sieve_global_dir = /etc/dovecot/sieve/global/&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''!!! I'm not sure that the following is necessary'''&lt;br /&gt;
&lt;br /&gt;
'''!!! At first try not to make this actions'''&lt;br /&gt;
&lt;br /&gt;
'''!!! If everything works without it - nevermind'''&lt;br /&gt;
&lt;br /&gt;
   Create dir for global rules sieve_global_dir:&lt;br /&gt;
&lt;br /&gt;
       mkdir -p /etc/dovecot/sieve/global&lt;br /&gt;
&lt;br /&gt;
   Chown dir:&lt;br /&gt;
&lt;br /&gt;
       chown dovecot:dovecot -R /etc/dovecot/sieve&amp;lt;/blockquote&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Roundcube config edit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * At first, check that there's the &amp;quot;managesieve&amp;quot; plugin in the plugin directoty: &amp;quot;/usr/share/nginx/html/webmail/plugins/&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['managesieve_host'] = 'localhost';&lt;br /&gt;
 ...&lt;br /&gt;
 $config['plugins'] = [&lt;br /&gt;
     ...&lt;br /&gt;
     'managesieve',&lt;br /&gt;
 ];&lt;br /&gt;
 ...&lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
Go to Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
Create test filter (for example), copy message to another email after it will be received&lt;br /&gt;
 '''Settings''' - '''Filter''' - Filter &amp;quot;'''Roundcube'''&amp;quot; - &amp;quot;'''+'''&amp;quot;&lt;br /&gt;
     '''Filter name''': mail_forward&lt;br /&gt;
     '''Area''': ALL messages&lt;br /&gt;
     '''Action''': send copy to - xxx@mail.ru&lt;br /&gt;
         '''Save'''&lt;br /&gt;
Now you can see the brand new files in the directory &amp;quot;'''/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/sieve/'''&amp;quot; (config '''roundcube.sieve''' and symlink '''dovecot.sieve''' (config '''/etc/dovecot/conf.d/90-sieve.conf''' point to '''dovecot.sieve'''))&lt;br /&gt;
     ...&lt;br /&gt;
     dovecot.sieve -&amp;gt; roundcube.sieve&lt;br /&gt;
     roundcube.sieve&lt;br /&gt;
     ...&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
Send email to yourself&lt;br /&gt;
&lt;br /&gt;
The message will be received and will be sent to xxx@mail.ru as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, in that case, if you have a private per-user sieve script ('''/home/mail/%d/%u/sieve/dovecot.sieve''', we have already configured it), the global sieve script '''WON'T WORK'''!&lt;br /&gt;
&lt;br /&gt;
To make the private per-user script and the global script work at the same time, we need to do following.&lt;br /&gt;
&lt;br /&gt;
In this example we will filter all mail for all users, and put SPAM to the Junk directory.&lt;br /&gt;
&lt;br /&gt;
https://talk.plesk.com/threads/global-dovecot-sieve-rule.341552/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;*This rule filter SPAM (we have already configured spamassasin above, right?) and put it to Junk dir&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
     fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
Create the new global sieve configuration directive for Dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/37-custom-global-sieve.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 plugin {&lt;br /&gt;
 # Make sure to run &amp;quot;sievec&amp;quot; on this file after creating it:&lt;br /&gt;
 sieve_after = /etc/dovecot/conf.d/custom-sieve/global_after.sieve&lt;br /&gt;
 }&lt;br /&gt;
Run this to compile the new sieve, it will create a binary rule in the same directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sievec /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart the Dovecot services&amp;lt;blockquote&amp;gt;You don't have to start spamassasin service to make spam filter work. Amavisd does it!&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
If you have already configured Spamassassin in this manual above - send email to yourself with following in the message body: '''XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'''&lt;br /&gt;
&lt;br /&gt;
The message wil be put in the Junk directory and the copy of this message will be sent to xxx@mail.ru&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Apr 23 20:39:54 mail amavis[1696]: (01696-01) Passed SPAM {RelayedTaggedInternal,Quarantined}, MYNETS LOCAL [::1]:50042 &amp;lt;admin@alef-studio.ru&amp;gt; -&amp;gt; &amp;lt;admin@alef-studio.ru&amp;gt;, Queue-ID: BE39DE013B, Message-ID: &amp;lt;223db76d330a882501d9b6584e72e16b@alef-studio.ru&amp;gt;, mail_id: qx51q6idSWsl, Hits: 998.992, size: 1158, queued_as: 8850CE0A8A, 709 ms&lt;br /&gt;
     ...&lt;br /&gt;
Now we can configure the private filter rules for each user, and our global SPAM filter will work as well!&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Create new messages with HTML-EDITOR by default ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['htmleditor'] = 1;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Roundcube Pugin. Viewer Office Docs (DOC, XLS, ODT, ODS, etc.) ==&lt;br /&gt;
https://github.com/jfcherng-roundcube/plugin-cloudview&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Address-book from Windows AD DC on-line ==&lt;br /&gt;
&lt;br /&gt;
=== At Windows AD DC Server ===&lt;br /&gt;
Go to &amp;quot;'''Domain Users and Computers'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First off, you need to have a user &amp;quot;'''admin'''&amp;quot; with Administrator's permissions to connect to the AD DC from Roundcube&lt;br /&gt;
&lt;br /&gt;
Create a user in group &amp;quot;'''Users'''&amp;quot; with an email in (! '''You won't see any user at all in Roundcube web-interface if you don't add an email address to the specific users's field !''')&lt;br /&gt;
&lt;br /&gt;
Get a LDAP/AD Administartor's &amp;quot;'''admin'''&amp;quot; Distinguished Name for connect to AD from the Mail Server (we will use it later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;C:\Users\Администратор.WIN-RMJC4R0JMJR&amp;gt; '''dsquery user -name admin'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 '''&amp;quot;CN=admin,CN=Users,DC=alf,DC=local&amp;quot;'''&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== At Mail Server ===&lt;br /&gt;
Add to the Roundcube config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
//Разрешить поиск и автодополнение из массива AD&lt;br /&gt;
$rcmail_config['autocomplete_addressbooks'] = array('sql','AD');&lt;br /&gt;
&lt;br /&gt;
$config['ldap_public'] = array(&lt;br /&gt;
//Имя массива, в котором выполняется поиск&lt;br /&gt;
    'AD' =&amp;gt;array (&lt;br /&gt;
        'name' =&amp;gt; 'ALF', //Отображаемое имя в интерфейсе WEBMail Roundcube&lt;br /&gt;
        'hosts' =&amp;gt; array('10.100.199.21'), //IP адрес или ДНС имя AD DC&lt;br /&gt;
        'sizelimit' =&amp;gt; 600,&lt;br /&gt;
        'port' =&amp;gt; 389,&lt;br /&gt;
        'use_tls' =&amp;gt; false,&lt;br /&gt;
        'user_specific' =&amp;gt; false,&lt;br /&gt;
        'base_dn' =&amp;gt; 'DC=alf,DC=local', //Где выполнять поиск&lt;br /&gt;
        'bind_dn' =&amp;gt; 'admin@alf.local', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'bind_pass' =&amp;gt; 'PassWord#1', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'writable' =&amp;gt; false,&lt;br /&gt;
        'ldap_version' =&amp;gt; 3,&lt;br /&gt;
        'search_fields' =&amp;gt; array(&lt;br /&gt;
           'mail',&lt;br /&gt;
           'cn',&lt;br /&gt;
        ),&lt;br /&gt;
        'name_field' =&amp;gt; 'cn',&lt;br /&gt;
        'email_field' =&amp;gt; 'mail',&lt;br /&gt;
        'surname_field' =&amp;gt; 'sn',&lt;br /&gt;
        'firstname_field' =&amp;gt; 'givenName',&lt;br /&gt;
        //Можно добавить немного дополнительной информации в адресной книге&lt;br /&gt;
        'organization_field'     =&amp;gt; 'company',&lt;br /&gt;
        'jobtitle_field'    =&amp;gt; 'title',&lt;br /&gt;
        'department_field'   =&amp;gt; 'department',&lt;br /&gt;
        //Порядок сортировки&lt;br /&gt;
        'sort' =&amp;gt; 'sn',&lt;br /&gt;
        'scope' =&amp;gt; 'sub', //Выполнять поиск по всему каталогу LDAP // search mode: sub|base|list&lt;br /&gt;
        'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectClass=user)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        //'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectcategory=person)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        'global_search' =&amp;gt; true,&lt;br /&gt;
        'fuzzy_search' =&amp;gt; true&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// LDAP&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache'.&lt;br /&gt;
$config['ldap_cache'] = 'db';&lt;br /&gt;
// Lifetime of LDAP cache. Possible units: s, m, h, d, w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Go to Roundcube web-interface - Contacts&lt;br /&gt;
&lt;br /&gt;
You will see new section &amp;quot;ALF&amp;quot; and contact in there&lt;br /&gt;
&lt;br /&gt;
You can debug if something goes wrong:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /usr/share/nginx/html/webmail/logs/errors.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Amavis blocks some inbound emails addresses with error &amp;quot;'''Blocked BAD-HEADER-0'''&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
https://sourceforge.net/p/amavis/mailman/message/16755074/&lt;br /&gt;
&lt;br /&gt;
https://www.habibza.in/amavisd-whitelist-or-allowed-mail-from-blocked-bad-header/&lt;br /&gt;
&lt;br /&gt;
https://forum.iredmail.org/topic4681-solved-how-to-bypass-amavisd-for-some-senders.html&lt;br /&gt;
&lt;br /&gt;
=== Solution 1 ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $final_bad_header_destiny = D_PASS;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ??? Solution 2. DOESN'T WORK ??? ===&lt;br /&gt;
Create whitelist of emails or even domains, which you want to allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/whitelist-badheader&amp;lt;/code&amp;gt;&lt;br /&gt;
 user@somedomain.com&lt;br /&gt;
 somedomain.com&lt;br /&gt;
Edit amavis config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # white list, which will allow inbound emails with BAD-HEADER-0&lt;br /&gt;
 @bypass_header_checks_maps = (&lt;br /&gt;
    read_hash(&amp;quot;/etc/amavisd/whitelist-badheader&amp;quot;),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
Restart services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logging users' action (e.g. copying, erasing users' emails), which users perform via any IMAP/POP3 mail clients, via Dovecot MDA logging ==&lt;br /&gt;
Enable mail plugins in Dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_plugins = $mail_plugins mail_log notify&lt;br /&gt;
 ...&lt;br /&gt;
Enable plugins '''mail_log_events, mail_log_fields'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/conf.d/90-plugin.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
plugin {&lt;br /&gt;
  #setting_name = value&lt;br /&gt;
&lt;br /&gt;
  # Events to log. Defined in src/plugins/mail-log/mail-log-plugin.c - also available: flag_change save mailbox_create&lt;br /&gt;
  # autoexpunge is included in expunge&lt;br /&gt;
  mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename&lt;br /&gt;
&lt;br /&gt;
  # Also available: Defined in src/plugins/mail-log/mail-log-plugin.c - flags vsize from subject&lt;br /&gt;
  mail_log_fields = uid box msgid from subject&lt;br /&gt;
&lt;br /&gt;
  # Don't log fields that require opening the email (v2.2.28+).&lt;br /&gt;
  #mail_log_cached_only = yes&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make some actions in the user's mailbox (e.g. move email to the Trash and then delete it completely)&lt;br /&gt;
&lt;br /&gt;
Now you can look in the logs ('''expunge = delete''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat '''/var/log/dovecot-info.log''' | grep &amp;quot;'''Info: expunge'''\|'''Info: copy'''&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
 May 11 10:53:56 imap(admin@don661.ru)&amp;lt;259523&amp;gt;&amp;lt;aw5K9CgY6oN/AAAB&amp;gt;: Info: '''copy''' from INBOX: box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 May 11 10:54:13 imap(admin@don661.ru)&amp;lt;259531&amp;gt;&amp;lt;JGZG9SgYLKZ/AAAB&amp;gt;: Info: '''expunge''': box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 May 11 11:08:21 pop3(admin@don661.ru)&amp;lt;259979&amp;gt;&amp;lt;Mz/SJykYIdpOhIjD&amp;gt;: Info: '''expunge''': box=INBOX, uid=10, msgid=&amp;lt;65e7897f-b08d-4f13-8655-73d08485b2f2@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
&lt;br /&gt;
== Block particular senders (emails, domains) - inbox mail (Заблокировать конкретные ящики-отправители или домены - входящую почту) ==&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/header_checks&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 /^From:.*baduser@example.com/ REJECT&lt;br /&gt;
 /^From:.*@spamdomain.com/ REJECT&lt;br /&gt;
 /^From:.*@scientamicron.com/ REJECT&lt;br /&gt;
 /^From:.*@ip-223-6.dataclub.info/ REJECT&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; BLOCK SENDERS LIST&lt;br /&gt;
 header_checks = regexp:/etc/postfix/header_checks&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send an email from the blocked user (user01@gmail.com)&lt;br /&gt;
&lt;br /&gt;
Check logs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Mar 16 22:11:27 mail postfix/cleanup[3119]: 0D83BE1E24: reject: header From: &amp;quot;user01@gmail.com&amp;quot; &amp;lt;user01@gmail.com&amp;gt; from mail-lj1-f176.google.com[209.85.208.176]; from=&amp;lt;user01@gmail.com&amp;gt; to=&amp;lt;call.center2@lada-tambovavtocity.ru&amp;gt; proto=ESMTP helo=&amp;lt;mail-lj1-f176.google.com&amp;gt;: 5.7.1 message content rejected&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
= Errors =&lt;br /&gt;
&lt;br /&gt;
=== Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat ./dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
        ...&lt;br /&gt;
        Feb 16 16:18:17 lda(cless@yourdomain.ru)&amp;lt;2571&amp;gt;&amp;lt;B0HqGhkt7mMLCgAA1XGFgw&amp;gt;: Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database&lt;br /&gt;
        ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
    mail_home = /home/mail/%d/%u&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         Feb 27 00:56:40 imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem&lt;br /&gt;
         ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: '''&amp;quot;Connection error (failed to reach the server) roundcube&amp;quot;''' at Roundcube Webmail web-interface during sending a message, if the size of the message is 10MB+ (a huge sign with pictures, for example) ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
The update from '''PHP-7.3''' to '''PHP-7.4''' has solved the issue.&lt;br /&gt;
&lt;br /&gt;
=== ERROR: PHP-ImageMagick module creates huge files, which use all disk space in / partition ===&lt;br /&gt;
https://github.com/ImageMagick/ImageMagick/issues/395&lt;br /&gt;
&lt;br /&gt;
PHP-ImageMagick module creates huge files, which use all disk space in / partition&lt;br /&gt;
 /tmp/systemd-private-78b2a42fd129405aa1e735b61bf8fb72-php-fpm.service-Icx1Wg/tmp/magick-*&lt;br /&gt;
??? SOLUTION ???&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 1:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/ImageMagick-7/policy.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;policymap&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;memory&amp;quot; value=&amp;quot;2GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;disk&amp;quot; value=&amp;quot;1GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;cache&amp;quot; name=&amp;quot;synchronize&amp;quot; value=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/policymap&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 2:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the following cron jobs for automatic cleanup. The first 2 lines will clean up old files based on their age.&lt;br /&gt;
&lt;br /&gt;
In one case this was still insufficient, since a user was uploading a lot of very large images within a short time, causing the /tmp folder to fill up very quickly. Therefore the last line removes images which are at a certain filesize treshold. I picked a treshold just below the usual size of the magick-* files (see list in first post).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Temporary solution to prevent /tmp from being filled with 200+ MB ImageMagick files&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'magick-*' -delete&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'php*' -delete&lt;br /&gt;
 */5 * * * * find /tmp/ -mmin +5 -type f -name 'magick-*' -size +200M -delete&lt;br /&gt;
&lt;br /&gt;
=== Error in '''Roundcube Webmail during the searching for emails''': '''(Server error)''' ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
It's necessary to Install Full-text search.&lt;br /&gt;
&lt;br /&gt;
Proceed to the according section of this manual: '''Fts-xapian'''.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1931</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1931"/>
		<updated>2025-07-10T07:05:25Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; push DNS to clients&lt;br /&gt;
 push &amp;quot;dhcp-option DNS 10.192.16.10&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 &lt;br /&gt;
 user nobody&lt;br /&gt;
 &lt;br /&gt;
 # CENTOS&lt;br /&gt;
 group nobody&lt;br /&gt;
 &lt;br /&gt;
 # UBUNTU&lt;br /&gt;
 ;group nogroup&lt;br /&gt;
 &lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
 &lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 ; РАСКОММЕНТИТЬ ТОЛЬКО ПОСЛЕ ГЕНЕРАЦИИ crl.pem - БАЗА ОТОЗВАННЫХ СЕРТИФИКАТОВ&lt;br /&gt;
 ;crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 dhcp-option DNS 10.54.100.227&lt;br /&gt;
 dhcp-option DNS 10.54.100.228&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 cd ./easy-rsa&lt;br /&gt;
 ./easyrsa gen-req ${clientName} nopass&lt;br /&gt;
 ./easyrsa sign-req client ${clientName}&lt;br /&gt;
 cd ..&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
=== Статус подключенных клиентов ===&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/openvpn/openvpn-status.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=LVM._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_LV_%D0%B7%D0%B0_%D1%81%D1%87%D0%B5%D1%82_%D1%81%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BC%D0%B5%D1%81%D1%82%D0%B0_%D0%BD%D0%B0_%D1%84%D0%B8%D0%B7%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%B4%D0%B8%D1%81%D0%BA%D0%B5&amp;diff=1930</id>
		<title>LVM. Расширение объема раздела LV за счет свободного места на физическом диске</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=LVM._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_LV_%D0%B7%D0%B0_%D1%81%D1%87%D0%B5%D1%82_%D1%81%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BC%D0%B5%D1%81%D1%82%D0%B0_%D0%BD%D0%B0_%D1%84%D0%B8%D0%B7%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%B4%D0%B8%D1%81%D0%BA%D0%B5&amp;diff=1930"/>
		<updated>2025-07-01T06:47:27Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Описание=&lt;br /&gt;
В данной инструкции мы увеличиваем '''системный''' раздел '''root''', но она также подойдет и для увеличения '''НЕсистемного''' раздела.&lt;br /&gt;
&lt;br /&gt;
= Расширение =&lt;br /&gt;
&lt;br /&gt;
== '''Вариант 1'''. Простой. Все действия производим онлайн в рабочей системе. БЕЗ удаления раздела '''root'''. ==&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''EXT4''' ===&lt;br /&gt;
Сначала убедимся что на нашем физическом диске есть свободная от разделов область (дополнительный незанятый разделами объем).&lt;br /&gt;
&lt;br /&gt;
Или, если у нас виртуальная машина - сначала увеличиваем объем диска в ВМ.&lt;br /&gt;
&lt;br /&gt;
Далее смотрим информацию о физическом диске и разделах. Должны увидеть что объем физического диска имеет необходимый объем для расширения (или что общий объем диска увеличился, если мы увеличили его в ВМ гипервизора).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fdisk -l&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что изначальный объем раздела '''LV''' '''root''' - '''21'''G, а свободного места '''- 86'''M&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/mapper/almalinux_alma-root   '''21'''G   20G   '''86'''M  99% /&lt;br /&gt;
Если мы посмотрим на '''PV''', то увидим что свободного места для расширения на нем нет, несмотря на то, что физически диск имеет свободную область (или что мы вручную увеличили объем физического диска в ВМ).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvs&amp;lt;/code&amp;gt;&lt;br /&gt;
 PV         VG             Fmt  Attr PSize   PFree&lt;br /&gt;
 /dev/sda2  almalinux_alma lvm2 a--  &amp;lt;21.00g    0&lt;br /&gt;
Так и должно быть, идем далее.&lt;br /&gt;
&lt;br /&gt;
Для начала необходимо расширить логический раздел /dev/sdb'''X''' для '''root''' на физическом диске (например, если на диске было свободное от разделов место или мы прибавили место к виртуальному диску в виртуальной машине (если машина в гипервизоре)). Иначе '''pvs''' и '''vgs''' будут показывать что размер раздела не увеличился и неоткуда брать место для создания '''LV''' большего объема.&lt;br /&gt;
&lt;br /&gt;
==== Если PV создан на партиции /dev/sdaX ====&lt;br /&gt;
&lt;br /&gt;
===== Интерактивное расширение через '''parted''' =====&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sda: '''4295'''MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
  2      1075MB  4295MB  4294MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 2 '''4296'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location '''4296''' is outside of the device /dev/sdb.&lt;br /&gt;
'''! Если &amp;lt;u&amp;gt;logical&amp;lt;/u&amp;gt; раздел находится на &amp;lt;u&amp;gt;extended&amp;lt;/u&amp;gt; разделе, то сначала расширяем &amp;lt;u&amp;gt;extended&amp;lt;/u&amp;gt; раздел, а потом &amp;lt;u&amp;gt;logical&amp;lt;/u&amp;gt;.'''&lt;br /&gt;
&lt;br /&gt;
Расширяем объем раздела до полного объема физического диска - '''4295'''MB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 2 '''4295'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sda: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1075MB  1074MB  primary  ext4         boot&lt;br /&gt;
  2      1075MB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== НЕинтерактивное расширение через '''growpart''' =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''-N -''' Можно предварительно запустить в холостом режиме с данным ключом&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3''' - номер раздела (/dev/sdb'''3''')&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;growpart -v /dev/sda 3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Расширяем PV ====&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sda'''X'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Если PV создан на голом диске /dev/sda =====&lt;br /&gt;
Просто расширяем PV&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sde&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Идем далее.&lt;br /&gt;
&lt;br /&gt;
Смотрим что есть дополнительный незанятый объем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   PV         VG             Fmt  Attr PSize   PFree&lt;br /&gt;
   /dev/sda2  almalinux_alma lvm2 a--  &amp;lt;31.00g '''8.00'''g&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG             #PV #LV #SN Attr   VSize   VFree&lt;br /&gt;
   almalinux_alma   1   2   0 wz--n- &amp;lt;31.00g '''8.00'''g&lt;br /&gt;
Расширяем '''LV''' на весь свободный объем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvresize /dev/almalinux_alma/root /dev/sda2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
Расширяем раздел и одновременно расширяем ФС (только если данный раздел отформатирован в '''XFS'''), используя ключ &amp;quot;'''-r'''&amp;quot; (используется &amp;lt;code&amp;gt;xfs_growfs&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
В данном случае после расширения раздела нет необходимости использовать &amp;lt;code&amp;gt;xfs_growfs&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение на весь объем&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r /dev/almalinux_alma/root /dev/sda2&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение на +определенный объем&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r -L +5G /dev/vg00/root /dev/vda2&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение до итогового объема 20GB&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r -L 20G /dev/vg00/root /dev/vda2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ'''&lt;br /&gt;
&lt;br /&gt;
Расширяем '''LV''' на конкретное значение в '''GB'''&amp;lt;blockquote&amp;gt;'''-A n''' - Turn off auto-backup of metadata (see man page for details and cautions) which should prevent having to write to /etc/lvm You can then run '''vgcfgbackup''' after you have been successful in resizing. Необходимая опция если на расширяемом разделе осталось 0 свободного места.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvextend -A n -L +5G /dev/almalinux_alma/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что объем '''LV''' увеличился&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG             Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   root almalinux_alma -wi-ao---- '''28.59'''g&lt;br /&gt;
   swap almalinux_alma -wi-ao----  2.40g&lt;br /&gt;
Расширяем ФС '''EXT4''' на '''LV''' '''root''' на '''весь доступный объем'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/almalinux_alma/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ'''&lt;br /&gt;
&lt;br /&gt;
Если расширяемый раздел LV имеет ФС '''XFS'''&amp;lt;blockquote&amp;gt;Указываем именно директорию с примонтированным расширенным разделом ('''/''' в данном случае, или, например, '''/mnt/d1''', если расширяли не системный диск)&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;xfs_growfs -d /&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что общий объем раздела '''root''' и объем свободного места увеличился&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/mapper/almalinux_alma-root   '''29'''G   20G  '''7.7G'''  72% /&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
== '''Вариант 2'''. Сложный. Увеличение раздела через удаление текущего раздела и создание нового увеличенного раздела. (Лучше использовать '''Вариант 1''' как более простой, без удаления раздела.) ==&lt;br /&gt;
Грузимся с загрузочного LIVE дистрибутива Linux. Предпочтительно с '''SystemRescueCD.''' Все действия производим в LIVE системе '''SystemRescueCD'''. В ней имеются необходимые утилиты, например, '''fsarchiver'''.&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''XFS''' ===&lt;br /&gt;
Активируем LVM разделы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vgchange -ay&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG                    Attr       '''LSize'''   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root centos_centos7-test01''' -wi-ao----  '''10.00g'''&lt;br /&gt;
Создаем директорию для монтирования системы root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем директорию для бэкапа файлов раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_backup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем раздел root в директорию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/centos_centos7-test01/root /mnt/root_lv/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем сетевую шару, на которую будем бэкапировать файлы раздела root (для этого подойдет и обычный раздел локального диска, например, подключенного через USB)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -t cifs -o username=admin,password=PassWord#1 //192.168.17.12/img/tmp/root /mnt/root_backup/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Бэкапим файлы раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;xfsdump -l 0 -L &amp;quot;root_backup&amp;quot; -M &amp;quot;root_backup&amp;quot; -f /mnt/root_backup/root_backup.img /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Демонтируем раздел root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удаляем раздел root, чтобы на его месте создать новый root увеличенного размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvremove /dev/centos_centos7-test01/root&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''СКОРЕЕ ВСЕГО ПЕРЕД СОЗДАНИЕМ НОВОГО РАЗДЕЛА LV НЕОБХОДИМО РАСШИРИТЬ ЛОГИЧЕСКИЙ РАЗДЕЛ НА ДИСКЕ'''&lt;br /&gt;
&lt;br /&gt;
'''ВОЗМОЖНО Я НЕ УЧЕЛ ЭТО ПРИ НАПИСАНИИ МАНУАЛА'''&lt;br /&gt;
&lt;br /&gt;
'''ЭТО МОЖНО СДЕЛАТЬ С ИСПОЛЬЗОВАНИЕМ ''parted'''''&lt;br /&gt;
&lt;br /&gt;
'''СМОТРИ НИЖЕ - РАСШИРЕНИЕ РАЗДЕЛА EXT4 ЭТОГО МАНУАЛА'''&lt;br /&gt;
&lt;br /&gt;
'''ДОПОЛНИТЬ ЭТОТ МАНУАЛ КОГДА БУДУ РАСШИРЯТЬ LVM С XFS'''&amp;lt;/blockquote&amp;gt;Создаем новый root увеличенного размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvcreate -Zy -L '''15G''' -n root centos_centos7-test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG                    Attr       '''LSize'''   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root centos_centos7-test01''' -wi-a-----  '''15.00g'''&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG                    #PV #LV #SN Attr   VSize    '''VFree'''&lt;br /&gt;
   '''centos_centos7-test01'''   1   2   0 wz--n-  &amp;lt;30.00g '''&amp;lt;15.00g'''&lt;br /&gt;
Форматируем новый раздел root&amp;lt;blockquote&amp;gt;В mkfs.xfs (начиная с версии 3.2.4 xfsprogs) недавно стал использоваться по умолчанию суперблок версии 5 с множеством новых улучшений, таких как контрольные суммы метаданных CRC.&lt;br /&gt;
&lt;br /&gt;
Чтобы избежать ошибки, требуется '''&amp;quot;-m reflink=0&amp;quot;''', что отключает несовместимую поддержку копирования при записи reflink.&lt;br /&gt;
&lt;br /&gt;
Иначе при загрузке основной системы '''root''' раздел загрузится в '''RO''' режиме&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkfs.xfs -m reflink=0 /dev/centos_centos7-test01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем новый раздел в директорию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/centos_centos7-test01/root /mnt/root_lv/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Восстанавливаем файлы root из сохраненного образа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;xfsrestore -f /mnt/root_backup/root_backup.img /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Демонтируем раздел root и директорию для бэкапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /mnt/root_*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отключаем подключенный '''SystemRescueCD'''&lt;br /&gt;
&lt;br /&gt;
Грузимся в основную систему&lt;br /&gt;
&lt;br /&gt;
Система должна загрузиться&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''EXT4.''' ===&lt;br /&gt;
Активируем LVM разделы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vgchange -ay&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG   Attr       '''LSize'''  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root''' vg01 -wi-ao---- '''10.00g'''&lt;br /&gt;
Создаем директорию для бэкапа раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_backup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем сетевую шару, на которую будем бэкапировать раздел root (для этого подойдет и обычный раздел локального диска, например, подключенного через USB)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -t cifs -o username=admin,password=PassWord#1 //192.168.17.12/img/tmp/root /mnt/root_backup/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем образ раздела '''root'''&amp;lt;blockquote&amp;gt;Будет создан образ '''/mnt/root_backup/root_lv.fsa'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;fsarchiver savefs /mnt/root_backup/root_lv /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
     Statistics for filesystem 0&lt;br /&gt;
     * files successfully processed:....regfiles=27662, directories=5301, symlinks=1186, hardlinks=4250, specials=23&lt;br /&gt;
     * files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0&lt;br /&gt;
Удаляем раздел '''root'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvremove /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь необходимо расширить логический раздел /dev/sdb'''X''' для '''root''' на физическом диске (например, если на диске было свободное от разделов место или мы прибавили место к виртуальному диску в виртуальной машине (если машина в гипервизоре)). Иначе '''pvs''' и '''vgs''' будут показывать что размер раздела не увеличился и неоткуда брать место для создания '''LV''' большего объема.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: '''4295'''MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить  раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 '''4296'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location '''4296''' is outside of the device /dev/sdb.&lt;br /&gt;
Расширяем объем раздела&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 '''4295'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем PV&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sdb'''X'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем раздел '''root''' с увеличенным объемом&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvcreate -Zy -L '''15G''' -n root vg01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Форматируем '''root'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkfs.ext4 /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Восстанавливаем раздел '''root''' из сохраненного ранее образа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fsarchiver restfs /mnt/root_backup/root_lv.fsa id=0,dest=/dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
     Statistics for filesystem 0&lt;br /&gt;
     * files successfully processed:....regfiles=27662, directories=5301, symlinks=1186, hardlinks=4250, specials=23&lt;br /&gt;
     * files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG   #PV #LV #SN Attr   VSize   VFree&lt;br /&gt;
   vg01   1   2   0 wz--n- &amp;lt;30.00g '''15.00g'''&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG   Attr       '''LSize'''  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root''' vg01 -wi-ao---- '''15.00g'''&lt;br /&gt;
Отключаем подключенный '''SystemRescueCD'''&lt;br /&gt;
&lt;br /&gt;
Грузимся в основную систему&lt;br /&gt;
&lt;br /&gt;
Система должна загрузиться&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
[[Категория:LVM]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1929</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1929"/>
		<updated>2025-05-13T06:47:31Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 &lt;br /&gt;
 user nobody&lt;br /&gt;
 &lt;br /&gt;
 # CENTOS&lt;br /&gt;
 group nobody&lt;br /&gt;
 &lt;br /&gt;
 # UBUNTU&lt;br /&gt;
 ;group nogroup&lt;br /&gt;
 &lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
 &lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 ; РАСКОММЕНТИТЬ ТОЛЬКО ПОСЛЕ ГЕНЕРАЦИИ crl.pem - БАЗА ОТОЗВАННЫХ СЕРТИФИКАТОВ&lt;br /&gt;
 ;crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 dhcp-option DNS 10.54.100.227&lt;br /&gt;
 dhcp-option DNS 10.54.100.228&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 cd ./easy-rsa&lt;br /&gt;
 ./easyrsa gen-req ${clientName} nopass&lt;br /&gt;
 ./easyrsa sign-req client ${clientName}&lt;br /&gt;
 cd ..&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
=== Статус подключенных клиентов ===&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/openvpn/openvpn-status.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1928</id>
		<title>Mail Server. AlmaLinux 8. Postfix + Dovecot + Postfixadmin + Roundcube Webmail</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1928"/>
		<updated>2025-05-01T07:23:21Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Mail]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Opensource Mail Server. Postfix + Dovecot + Postfixadmin + Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
https://www.dmosk.ru/instruktions.php?object=mailserver-centos8&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== DNS Server Global ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Add resource records to the dns server, which is serving your domains (at mikrotik, for example, but it can be any dns-record manager of the registrar, which provides you your new domain)&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - public external IP of the mail server&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''192.168.199.40''''' - local IP of this mail server in you local network&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Root domain MX-record, which point to the mail domain ===&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=yourdomain.ru mx-exchange=mail.yourdomain.ru. mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Domain for administration - mail02.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This should be the hostname of your physical mail server&lt;br /&gt;
&lt;br /&gt;
It's not your domain for mail, just for management&lt;br /&gt;
&lt;br /&gt;
If there will be other mail domains on that server, all emails still will be sended with source-host &amp;quot;mail02.yourdomain.ru&amp;quot; as mail sender&lt;br /&gt;
&lt;br /&gt;
This domain needs to be added to ISP's PTR-record as well&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail02.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mail domain - mail.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This is your first mail domain&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS Server Local ==&lt;br /&gt;
At the local '''DNS server''' (whose IP is registred in the file '''/etc/resolv.conf''' of this mail server) you have to register accordance of '''your domains''' and '''local IP''' in you local network of this server:&lt;br /&gt;
 ...&lt;br /&gt;
 192.168.199.42 mail.yourdomain.ru&lt;br /&gt;
 192.168.199.42 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Mail server ==&lt;br /&gt;
&lt;br /&gt;
=== General configuration ===&lt;br /&gt;
System update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hostname&amp;lt;blockquote&amp;gt;'''''mail02.yourdomain.ru''''' - mail server hostname&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - mail server public external IP&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/hosts&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 185.225.35.200 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
Check&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig A mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utils, firewall, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y chrony wget&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;timedatectl set-timezone Europe/Moscow&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable chronyd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp --add-port=22/tcp --add-port=10050/tcp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL Certs ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to choose whether you will use self-signed certs or letsencrypt certs or purchased certs. We will use it later for Webmail Interface (nginx), and for Mail Desktop Clients (postfix, dovecot)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certificates ====&lt;br /&gt;
''If you're going to purchase SSL certificates from CA:''&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''a few wildcard certs''' with main domain and wildcard subdomains (e.g., '''example.com''' and '''*.example.com''') for '''each mail domain'''.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''the only ONE''' multidomain certificate with '''ALL main domain certs and wildcard certificates of your main domain ('''e.g., '''example.com''' and '''*.example.com''' for each domain''')'''.&lt;br /&gt;
&lt;br /&gt;
==== Self-signed ====&lt;br /&gt;
Generate certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/ssl/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj &amp;quot;/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=mail02.yourdomain.ru&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Letsencrypt ====&lt;br /&gt;
Nginx will create /usr/share/nginx/html directory for letsencrypt challenges&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y certbot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to create cert for each domain. You can put all certs into one file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y &amp;lt;nowiki&amp;gt;http://rpms.remirepo.net/enterprise/remi-release-8.rpm&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf module install -y php:remi-7.4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # For more information on configuration, see:&lt;br /&gt;
 #   * Official English Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 #   * Official Russian Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/ru/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 user nginx;&lt;br /&gt;
 worker_processes auto;&lt;br /&gt;
 error_log /var/log/nginx/error.log;&lt;br /&gt;
 pid /run/nginx.pid;&lt;br /&gt;
 # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.&lt;br /&gt;
 include /usr/share/nginx/modules/*.conf;&lt;br /&gt;
 events {&lt;br /&gt;
    worker_connections 1024;&lt;br /&gt;
 }&lt;br /&gt;
 http {&lt;br /&gt;
    log_format  main  '$remote_addr - $remote_user [$time_local] &amp;quot;$request&amp;quot; '&lt;br /&gt;
                      '$status $body_bytes_sent &amp;quot;$http_referer&amp;quot; '&lt;br /&gt;
                      '&amp;quot;$http_user_agent&amp;quot; &amp;quot;$http_x_forwarded_for&amp;quot;';&lt;br /&gt;
    access_log  /var/log/nginx/access.log  main;&lt;br /&gt;
    sendfile            on;&lt;br /&gt;
    tcp_nopush          on;&lt;br /&gt;
    tcp_nodelay         on;&lt;br /&gt;
    keepalive_timeout   65;&lt;br /&gt;
    types_hash_max_size 2048;&lt;br /&gt;
    include             /etc/nginx/mime.types;&lt;br /&gt;
    default_type        application/octet-stream;&lt;br /&gt;
    # Load modular configuration files from the /etc/nginx/conf.d directory.&lt;br /&gt;
    # See &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/ngx_core_module.html#include&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    # for more information.&lt;br /&gt;
    include /etc/nginx/conf.d/*.conf;&lt;br /&gt;
 }&lt;br /&gt;
Redirect all HTTP-requests to HTTPS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 # Note: This file must be loaded before other virtual host config files,&lt;br /&gt;
 #&lt;br /&gt;
 # HTTP&lt;br /&gt;
 server {&lt;br /&gt;
    # Listen on ipv4&lt;br /&gt;
    listen 80;&lt;br /&gt;
    listen [::]:80;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    # Redirect all insecure http:// requests to https://&lt;br /&gt;
    return 301 &amp;lt;nowiki&amp;gt;https://$host$request_uri&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====HTTPS configuring====&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use self-signed or letsencrypt multidomain certificate (all domains and subdomains in one cert)=====&lt;br /&gt;
&lt;br /&gt;
Create a general config for HTTPS traffic (in order to use it with Roundcube Webmail and Postfixadmin)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2 default_server;&lt;br /&gt;
        listen       [::]:443 ssl http2 default_server;&lt;br /&gt;
        server_name  _;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
         &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate certificates, purchased from official CA or letsencrypt certs (separate cert for every mail domain)=====&lt;br /&gt;
&lt;br /&gt;
Backup /etc/nginx/conf.d/00-default_ssl.conf (or don't create it at all)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/conf.d/00-default_ssl.conf /etc/nginx/conf.d/00-default_ssl.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create separate config for each mail domain (in order to use it with Roundcube Webmail), and put in it the corresponding certificate path.&lt;br /&gt;
&lt;br /&gt;
Also you can create separate config for you management domain (in order to use it with Postfixadmin web-interface) in the same way (in our case mail02.yourdomain.ru). Or you can use any of our mail domains in order to get access to Postfixadmin web-interface. You also can use for that purpose letsencrypt cert or purchased cert.&lt;br /&gt;
&lt;br /&gt;
For example, this first config is for domain mail.don661.ru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/10-mail.don661.ru_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2;&lt;br /&gt;
        listen       [::]:443 ssl http2;&lt;br /&gt;
        server_name  mail.don661.ru;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
 &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
 &lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
        client_max_body_size 35M;&lt;br /&gt;
        client_body_timeout 300s;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable php-fpm --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MariaDB ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y mariadb-server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable mariadb --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysqladmin -u root password&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin/templates_c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DB creating&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -u root -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 # configuring is finished maker&lt;br /&gt;
 $CONF['configured'] = true;&lt;br /&gt;
 &lt;br /&gt;
 # default_language&lt;br /&gt;
 $CONF['default_language'] = 'en';&lt;br /&gt;
 &lt;br /&gt;
 # database_password&lt;br /&gt;
 $CONF['database_password'] = 'PassWord#1';&lt;br /&gt;
 &lt;br /&gt;
 # app checks domain during domains and mailboxes&lt;br /&gt;
 $CONF['emailcheck_resolve_domain']='NO';&lt;br /&gt;
 &lt;br /&gt;
 # amount of records (mailboxes, aliases) per page&lt;br /&gt;
 $CONF['page_size'] = '9999';&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter Setup password, copy generated HASH of the Setup password to config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['setup_password'] = '$2y$10$ZafzUSBaHy47kta5KfPAjF0aQBjH5i';&lt;br /&gt;
 ...&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with Setup password&lt;br /&gt;
&lt;br /&gt;
Create new admin at the footer of the page&lt;br /&gt;
     Администратор admin@yourdomain.ru успешно добавлен!&lt;br /&gt;
You are done with your basic setup. You can now login to PostfixAdmin using the account you just created.&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y postfix postfix-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
User to work with mail services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;groupadd -g 1024 vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;useradd -d /home/mail -g 1024 -u 1024 vmail -m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown vmail:vmail /home/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Main config ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Edit parameters&lt;br /&gt;
 ...&lt;br /&gt;
 # domain, that will be put in email during mail send if it doesn't point in mail's FROM&lt;br /&gt;
 &lt;br /&gt;
 myhostname = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 mydomain = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 myorigin = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 # domains for input emails&lt;br /&gt;
 mydestination = $myhostname, localhost.$mydomain, localhost, localhost.localdomain&lt;br /&gt;
 ...&lt;br /&gt;
 # where we can get local users&lt;br /&gt;
 local_recipient_maps = unix:passwd.byname $alias_maps&lt;br /&gt;
 ...&lt;br /&gt;
 # clients, that will send mail without auth at server. allow local server send emails&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 ...&lt;br /&gt;
 inet_interfaces = all&lt;br /&gt;
 ...&lt;br /&gt;
 inet_protocols = all&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # COMMENT OLD PARAMETERS&lt;br /&gt;
 #smtpd_tls_cert_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtpd_tls_key_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CApath = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CAfile = &amp;lt;...&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed certs&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_cert_file = /etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_key_file = /etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;###&amp;lt;/nowiki&amp;gt; OR&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt certs&lt;br /&gt;
 smtpd_tls_cert_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/cert.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 smtp_tls_CApath = /etc/letsencrypt/live/ALL-MAIL-DOMAINS&lt;br /&gt;
 smtp_tls_CAfile = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/chain.pem&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the primary certificate for the server, to be used for outgoing connections&lt;br /&gt;
 smtpd_tls_chain_files =&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/privkey.pem,&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the map to be used when SNI support is enabled&lt;br /&gt;
 tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
nano /etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; One host per line&lt;br /&gt;
 &lt;br /&gt;
 mail.yourprimarymailserverdomain.com /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 mail.yoursecondarymailserverdomain.com /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; add more domains with keys and certs as needed&lt;br /&gt;
&lt;br /&gt;
postmap -F hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
systemctl restart postfix&lt;br /&gt;
==== Main config again ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   virtual_mailbox_base — storage path for mailboxes&lt;br /&gt;
&lt;br /&gt;
   virtual_alias_maps — format and path of the aliases for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_domains — format and path of the virtual domains&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_maps — format and path of the mailboxes for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_minimum_uid — start UID number for users&lt;br /&gt;
&lt;br /&gt;
   virtual_uid_maps — user id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_gid_maps — group id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_transport — message deliver&lt;br /&gt;
&lt;br /&gt;
   dovecot_destination_recipient_limit — message transfer from Postfix to Dovecot in steps 1 (one) at a time&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_exceptions_networks — networks excepted from encryption&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl settings&lt;br /&gt;
&lt;br /&gt;
   broken_sasl_auth_clients — option for MS Outlook clients&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — auth type&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — Dovecot tmp files. Full or related (default /var/spool/postfix). Full path — /var/spool/postfix/private/auth&lt;br /&gt;
&lt;br /&gt;
   smtp_use_tls — smtp transfer mandatory&lt;br /&gt;
&lt;br /&gt;
   smtpd_use_tls — indicates to clients that TLS support is available&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_auth_only — use TLS only&lt;br /&gt;
&lt;br /&gt;
   smtpd_helo_required — request to start the session with a greeting&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /home/mail&lt;br /&gt;
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf&lt;br /&gt;
 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf&lt;br /&gt;
 '''### If you want to reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files), add the following option):'''&lt;br /&gt;
 '''# ''smtpd_reject_unlisted_sender = yes''&lt;br /&gt;
 '''### (You can try to send an email with non-existing user in field FROM, you will see a rejection in output:&lt;br /&gt;
 '''### ''echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)'''''&lt;br /&gt;
 virtual_minimum_uid = 1024&lt;br /&gt;
 virtual_uid_maps = static:1024&lt;br /&gt;
 virtual_gid_maps = static:1024&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_exceptions_networks = $mynetworks&lt;br /&gt;
 smtpd_sasl_security_options = noanonymous&lt;br /&gt;
 broken_sasl_auth_clients = yes&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/auth&lt;br /&gt;
 smtp_use_tls = yes&lt;br /&gt;
 smtpd_use_tls = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
Aliases config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_alias_maps.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * '''user, password''' — MySQL DB login and password; '''hosts''' — MySQL hostname; '''dbname''' — Mysql DB name; '''query''' — DB request template&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT goto FROM alias WHERE address='%s' AND active = '1'&lt;br /&gt;
Virtual domains config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_domains_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT domain FROM domain WHERE domain='%u'&lt;br /&gt;
Mailboxes config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_mailbox_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* you need to be sure that there's no any uncomment options for '''submission''', '''smtps''' и '''dovecot''' (by default there's no such uncomment options). In this config we configuring Postfix at ports 25, 465 и 587. In master.cf we configuring auxiliary services for Postfix: &lt;br /&gt;
&lt;br /&gt;
   submission   inet  n  -  n  -  -  smtpd:&lt;br /&gt;
&lt;br /&gt;
   submission — service name. In this example '''submission''' is used for MUA at port 587 during message sending.&lt;br /&gt;
&lt;br /&gt;
   inet — type of the service. Possible cases: inet (TCP/IP socket), unix (stream socket), unix-dgram (datagram socket), fifo (named queue channel), pass (stream socket UNIX).&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;n&amp;quot; — whether service private or limited. Possible cases: y or n. For inet service type it should be only n.&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;-&amp;quot; — whether service works with root rights. Possible cases: y, n or -. &amp;quot;-&amp;quot; means that this options doesn't applied to this service.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;n&amp;quot; — whether the service should work in chroot. Possible cases: y или n.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;-&amp;quot; — in what time the service should be awaked if one is inactive.&lt;br /&gt;
&lt;br /&gt;
   третий &amp;quot;-&amp;quot; — the maximum number of child processes of this service.&lt;br /&gt;
&lt;br /&gt;
   smtpd — running command.&lt;br /&gt;
&lt;br /&gt;
   * the following are the arguments for running the command:&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_security_level — TLS security level.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — sasl auth type.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — temp files path.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl options.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_local_domain — smtp-auth users' domain.&lt;br /&gt;
&lt;br /&gt;
   syslog_name — log prefix of the service in the syslog.&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_wrappermode — whether running service in custom mode (for TLS support).&lt;br /&gt;
&lt;br /&gt;
   smtpd_client_restrictions — limit clients' connections. allow only authorized clients.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the file&lt;br /&gt;
 submission   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=may&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_sasl_type=dovecot&lt;br /&gt;
   -o smtpd_sasl_path=/var/spool/postfix/private/auth&lt;br /&gt;
   -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
   -o smtpd_sasl_local_domain=$myhostname&lt;br /&gt;
 smtps   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o syslog_name=postfix/smtps&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
 dovecot   unix  -  n  n  -  -  pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient}&lt;br /&gt;
&lt;br /&gt;
Log configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postconf maillog_file=/var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable postfix --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot dovecot-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mailboxes path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
 mail_home = /home/mail/%d/%u&lt;br /&gt;
 ...&lt;br /&gt;
Listener for the auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* auth service and 2 listeners:&lt;br /&gt;
&lt;br /&gt;
'''/var/spool/postfix/private/auth''' for Dovecot auth ('''/var/spool/postfix/private/auth''' is a '''private/auth''' in Postfix),&lt;br /&gt;
&lt;br /&gt;
'''auth-userdb''' - '''dovecot-lda''' auth socket, '''666''' means any user can use it, '''user and group''' - socket owner&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 service auth {&lt;br /&gt;
   unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0666&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
   }&lt;br /&gt;
   unix_listener auth-userdb {&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * otherwise we will see an error: '''net_connect_unix(/var/run/dovecot/stats-writer) failed permission denied''', because vmail user doesn't has specific rights.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the conf&lt;br /&gt;
 &lt;br /&gt;
 service stats {&lt;br /&gt;
    unix_listener stats-reader {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
    unix_listener stats-writer {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Dovecot auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-auth.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * comment common auth and add sql-auth.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;!include auth-system.conf.ext&lt;br /&gt;
 !include auth-sql.conf.ext&lt;br /&gt;
 ...&lt;br /&gt;
Encryption configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_cert = &amp;lt;/etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_key = &amp;lt;/etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; TLS SNI (Server Name Indication) support (https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Individual cert for each domain&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; It is important to note that having multiple SSL certificates per IP will not be compatible with all clients, especially mobile ones. It is a TLS SNI limitation.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Default cert&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 &lt;br /&gt;
 local_name mail.ladavoronezh.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 local_name mail.don661.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dirs autocreation during the first login a mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 lda_mailbox_autocreate = yes&lt;br /&gt;
 ...&lt;br /&gt;
Connect to DB configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/auth-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * config for getting users' name and password. It's a default config.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 passdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 userdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Connect to mysql configure&amp;lt;blockquote&amp;gt;   * getting data from mysql (mariadb).&lt;br /&gt;
&lt;br /&gt;
'''password_query''' — request for getting password from the '''mailbox''' table;&lt;br /&gt;
&lt;br /&gt;
'''user_query''' — request for getting user's data (home dir, id 1024 (it's a '''vmail''' user id).&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&lt;br /&gt;
 driver = mysql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=PassWord#1&lt;br /&gt;
 default_pass_scheme = MD5-CRYPT&lt;br /&gt;
 password_query = SELECT password FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
Interface for dovecot listening&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 listen = *&lt;br /&gt;
 ...&lt;br /&gt;
 log_path = /var/log/dovecot.log&lt;br /&gt;
 info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
 debug_log_path = /var/log/dovecot-debug.log&lt;br /&gt;
 &lt;br /&gt;
 # debug log (DON'T ENABLE IT BY DEFAULT, ONLY IN DEBUG CASES)&lt;br /&gt;
 ###mail_debug = yes&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable dovecot --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/dovecot*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin. First domain and mailbox creating ===&lt;br /&gt;
Go to the Postfixadmin Web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/postfixadmin/public&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create domain yourdomain.ru&lt;br /&gt;
* Create Mailbox cless@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
=== Roundcube ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube Webmail config defaults.inc.php default parameters:&lt;br /&gt;
&lt;br /&gt;
https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://github.com/roundcube/roundcubemail/releases/download/1.6.1/roundcubemail-1.6.1-complete.tar.gz&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $config['db_dsnw'] = 'mysql://roundcube:PassWord#1@localhost/roundcubemail';&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 $config['enable_installer'] = true;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 // Comment&lt;br /&gt;
 &lt;br /&gt;
 //$config['smtp_host'] = 'localhost:587';&lt;br /&gt;
 //$config['smtp_user'] = '%u';&lt;br /&gt;
 //$config['smtp_pass'] = &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // Add&lt;br /&gt;
 &lt;br /&gt;
 $config['smtp_host'] = 'tls://localhost';&lt;br /&gt;
 $config['smtp_conn_options'] = array(&lt;br /&gt;
   'ssl' =&amp;gt; array(&lt;br /&gt;
   'verify_peer' =&amp;gt; false,&lt;br /&gt;
   'verify_peer_name' =&amp;gt; false,&lt;br /&gt;
 ),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
 # web session timeout (in minutes)&lt;br /&gt;
 $config['session_lifetime'] = 1440;&lt;br /&gt;
 ...&lt;br /&gt;
 // If true all folders will be checked during AUTO-REFRESH for recent messages (Otherwise only standard folders will be checked, like Inbox or SPAM)&lt;br /&gt;
 $config['check_all_folders'] = true;&lt;br /&gt;
 &lt;br /&gt;
 // default roundcube webmail interface language&lt;br /&gt;
 $config['language'] = 'ru_RU';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''$config['create_default_folders'] = true''' (creating dirs by default (if there's lack of ones)):&lt;br /&gt;
&lt;br /&gt;
'''Drafts''' — Messages drafts.&lt;br /&gt;
&lt;br /&gt;
'''Junk''' — SPAM.&lt;br /&gt;
&lt;br /&gt;
'''Sent''' — Sent messages.&lt;br /&gt;
&lt;br /&gt;
'''Trash''' — Trash bin for messages.&lt;br /&gt;
&lt;br /&gt;
* It's necessary to avoid errors, for example during receiving or deleting messages.&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# Add at the end of the file&lt;br /&gt;
&lt;br /&gt;
$config['drafts_mbox'] = 'Drafts';&lt;br /&gt;
$config['junk_mbox'] = 'Junk';&lt;br /&gt;
$config['sent_mbox'] = 'Sent';&lt;br /&gt;
$config['trash_mbox'] = 'Trash';&lt;br /&gt;
$config['create_default_folders'] = true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create roundcubemail DB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply template&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p roundcubemail &amp;lt; /usr/share/nginx/html/webmail/SQL/mysql.initial.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install php php-common php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-zip php-imagick php-gd php-fpm php php-pdo php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP configure&amp;lt;blockquote&amp;gt;* necessary to create message size limit&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 date.timezone = &amp;quot;Europe/Moscow&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 30M&lt;br /&gt;
 ...&lt;br /&gt;
 upload_max_filesize = 30M&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 http {&lt;br /&gt;
    ...&lt;br /&gt;
    client_max_body_size 30M;&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/webmail/installer/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After web installation - disable installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['enable_installer'] = false;&lt;br /&gt;
 ...&lt;br /&gt;
Remove installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\rm -R /usr/share/nginx/html/webmail/installer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quota Dovecot + PostfixAdmin ===&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=quota-dovecot-postfixadmin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * plugin to create quotas.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 mail_plugins = $mail_plugins quota&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-imap.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''mail_plugins'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {&lt;br /&gt;
   mail_plugins = $mail_plugins imap_quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 service dict {&lt;br /&gt;
    unix_listener dict {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-quota.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''quota = dict:User quota::proxy::quota'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 plugin {&lt;br /&gt;
   quota = dict:User quota::proxy::quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 dict {&lt;br /&gt;
   quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Create config file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-dict-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Mysql connection&lt;br /&gt;
&lt;br /&gt;
'''host''' — mysql server host;&lt;br /&gt;
&lt;br /&gt;
'''dbname''' — db containing postfix users;&lt;br /&gt;
&lt;br /&gt;
'''user''' — db user;&lt;br /&gt;
&lt;br /&gt;
'''password''' — db password.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 connect = '''host'''=localhost '''dbname'''=postfix '''user'''=postfix '''password'''=PassWord#1&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/storage&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/messages&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *if you have several '''user_query''' in your config, create query for the last one.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find &amp;quot;user_query&amp;quot; and put into this line: '''CONCAT('*:bytes=', quota) AS quota_rule'''&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid, '''''CONCAT('*:bytes=', quota) AS quota_rule''''' FROM mailbox WHERE username = '%u'&lt;br /&gt;
 ...&lt;br /&gt;
Check dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveconf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout-Login into Roundcube webmail.&lt;br /&gt;
&lt;br /&gt;
At the foot of the page there'll be a quota appear.&lt;br /&gt;
&lt;br /&gt;
=== Clamav + Amavisd ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavisd-new clamd perl-Digest-SHA1 perl-IO-stringy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rsyslog is necessary to write SPAM and VIRUS log to /var/log/maillog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y rsyslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now rsyslog.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $mydomain = 'yourdomain.ru';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 $log_level = 0;              # verbosity 0..5, -d&lt;br /&gt;
 $log_recip_templ = undef;    # disable by-recipient level-0 log entries&lt;br /&gt;
 $do_syslog = 1;              # log via syslogd (preferred)&lt;br /&gt;
 $syslog_facility = 'mail';   # Syslog facility as a string&lt;br /&gt;
            # e.g.: mail, daemon, user, local0, ... local7&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $myhostname = 'mail02.yourdomain.ru';&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add before line &amp;quot;'''''1;  # insure a defined return value'''''&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $allowed_header_tests{'multiple'} = 0;&lt;br /&gt;
 $allowed_header_tests{'missing'} = 0;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/clamd.d/scan.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Uncomment&lt;br /&gt;
 TCPSocket 3310&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable clamd@scan --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable amavisd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postfix settings&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''content_filter''' - point to application, which ьуфте to scan messages;&lt;br /&gt;
&lt;br /&gt;
'''receive_override_options''' - allow you to see original email addresses with viruses.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10024&lt;br /&gt;
 receive_override_options = no_address_mappings&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10025 (сервис без имени, он просто будет слушать на порту 10025 — это порт по умолчанию, на который отправляет сообщение amavis после выполнения проверки). Также, мы используем следующие опции:&lt;br /&gt;
&lt;br /&gt;
   smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.&lt;br /&gt;
&lt;br /&gt;
   smtp_enforce_tls — требовать ли TLS.&lt;br /&gt;
&lt;br /&gt;
   content_filter — приложение для сканирования. В данном примере сканирование отключено.&lt;br /&gt;
&lt;br /&gt;
   receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.&lt;br /&gt;
&lt;br /&gt;
   пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.&lt;br /&gt;
&lt;br /&gt;
   smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.&lt;br /&gt;
&lt;br /&gt;
   mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.&lt;br /&gt;
&lt;br /&gt;
   smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 scan   unix  -  -  n  -  16  smtp&lt;br /&gt;
   -o smtp_send_xforward_command=yes&lt;br /&gt;
   -o smtp_enforce_tls=no&lt;br /&gt;
 127.0.0.1:10025   inet  n  -  n  -  16  smtpd&lt;br /&gt;
   -o content_filter=&lt;br /&gt;
   -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
   -o smtpd_helo_restrictions=&lt;br /&gt;
   -o smtpd_client_restrictions=&lt;br /&gt;
   -o smtpd_sender_restrictions=&lt;br /&gt;
   -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
   # '''OR, if you want to restrict sending emails by users with inexistened local domains, etc.:'''&lt;br /&gt;
   # '''(You can see logs of PASSED o DROPPED emails in ''/var/log/maillog'' after sending them''')&lt;br /&gt;
   # '''-o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject'''&lt;br /&gt;
   -o mynetworks_style=host&lt;br /&gt;
   -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clamd update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y clamav-update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/freshclam.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Choose one of the update mirrors&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://clamav.jinr.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://packages.microsoft.com/clamav/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 DatabaseMirror pivotal-clamav-mirror.s3.amazonaws.com&lt;br /&gt;
 ...&lt;br /&gt;
Then remove the freshclam.dat file and restart the service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rm -f /var/lib/clamav/freshclam.dat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart clamav-freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Antispam DB update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sa-update --nogpg --verbose&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cron&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 15 3 * * * /bin/freshclam&lt;br /&gt;
 30 3 * * * /bin/sa-update&lt;br /&gt;
Antivirus checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&lt;br /&gt;
The email will never come, and you will see the following in the logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17688]: (17688-04) Blocked INFECTED (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... relay=127.0.0.1[127.0.0.1]:10024, delay=0.25, delays=0.19/0/0/0.06, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17688-04 - INFECTED: Eicar-Signature)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Redirect SPAM to user's SPAM-directory using Amavis service ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis dovecot-pigeonhole dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * закомментированная строка указывала, что файл с настройками находится в домашней директории каждого пользователя. Мы же будем делать централизованный конфиг в файле /etc/dovecot/sieve/default.sieve.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;sieve = file:~/sieve;active=~/.dovecot.sieve&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 sieve = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавили плагин sieve. Также необходимо со строки снять комментарий, если он был.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lda {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-lmtp.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * также мы добавили плагин sieve + необходимо со строки снять комментарий, если он есть.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lmtp {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/sieve/default.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы ищем в заголовках X-Spam-Flag и отправляем такие письма в папку Junk.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R vmail:vmail /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по умолчанию стоит значение D_DISCARD, что означает, что сообщения будут отклонятся. Нам же нужно D_PASS — пропускать.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $final_spam_destiny = D_PASS;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SPAM filter checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
The email will be appear inthe SPAM-directory, any you will see in the logs:&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17689]: (17689-04) Blocked SPAM {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... status=sent (250 2.7.0 Ok, discarded, id=17689-04 - spam)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Logrotate of mail logs ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/logrotate.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# see &amp;quot;man logrotate&amp;quot; for details&lt;br /&gt;
# rotate log files weekly&lt;br /&gt;
weekly&lt;br /&gt;
&lt;br /&gt;
# keep 4 weeks worth of backlogs&lt;br /&gt;
rotate 4&lt;br /&gt;
&lt;br /&gt;
# create new (empty) log files after rotating old ones&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
# use date as a suffix of the rotated file&lt;br /&gt;
dateext&lt;br /&gt;
&lt;br /&gt;
# uncomment this if you want your log files compressed&lt;br /&gt;
compress&lt;br /&gt;
&lt;br /&gt;
# RPM packages drop log rotation information into this directory&lt;br /&gt;
include /etc/logrotate.d&lt;br /&gt;
&lt;br /&gt;
# system-specific logs may be also be configured here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;nano /etc/logrotate.d/mail&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/var/log/dovecot-debug.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot-info.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/postfix.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/maillog {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Check a cron daily task. It should already exist&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/cron.daily/logrotate&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/logrotate /etc/logrotate.conf&lt;br /&gt;
EXITVALUE=$?&lt;br /&gt;
if [ $EXITVALUE != 0 ]; then&lt;br /&gt;
    /usr/bin/logger -t logrotate &amp;quot;ALERT exited abnormally with [$EXITVALUE]&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
exit $EXITVALUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Wait for a daily task to complete&lt;br /&gt;
&lt;br /&gt;
Or you can run the logrotate manually:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;logrotate -f /etc/logrotate.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Improving email deliverability (VERY IMPORTANT!) =&lt;br /&gt;
https://www.linuxbabe.com/mail-server/centos-7-iredmail-email-server&lt;br /&gt;
&lt;br /&gt;
To prevent your emails from being flagged as spam, you should set PTR, SPF, DKIM and DMARC records.&lt;br /&gt;
&lt;br /&gt;
=== PTR записи на DNS сервере ===&lt;br /&gt;
&lt;br /&gt;
==== Описание ====&lt;br /&gt;
Запись PTR прописывается _НЕ_ в ресурсных записях днс-сервера, к которому привязан ваш почтовый домен, это делает именно регистратор ip-адреса (провайдер или хостер, предоставляющий внешний ip-адрес)! Если провайдер ростелеком, пишем на электронку support@tmb.ru с просьбой зарегистрировать ptr-запись, штатная техподдержка отказывается предоставлять такую услугу&lt;br /&gt;
&lt;br /&gt;
Если у вас есть свой почтовый сервер, то необходимо, чтобы ваш провайдер (а точнее тот, кто выдал вам статические ip-адреса. если ваш внешний IP предоставил вам хостер, на котором у вас крутится VPS/VDS, то обращаемся в техподдержку хостера) зарегистрировал на своем DNS-сервере PTR записи для вашего почтового сервера (MX-записи). Иначе, подавляющая часть почтовых серверов интернета откажется принимать почту от вашего почтового сервера.&lt;br /&gt;
&lt;br /&gt;
Так же, многие почтовые сервера отвергают письма, если при проверке адреса отправителя в строке им выдается &amp;quot;dynamicip&amp;quot; или &amp;quot;dsl&amp;quot; или подобные слова означающие, что ваш адрес не статический или не совпадает с именем вашего домена.&lt;br /&gt;
&lt;br /&gt;
Если в ответе сервера на ваше отправленное письмо вы видите что-то типа:&lt;br /&gt;
&lt;br /&gt;
  mxs.mail.ru: 550 Sorry, we do not accept mail from hosts with dynamic IP or generic DNS PTR-records. Please get a custom reverse DNS name from your ISP for your host 215.54.54.54 or contact abuse@corp.mail.ru in case of error&lt;br /&gt;
&lt;br /&gt;
это значит, что вам необходимо корректно зарегистрировать PTR запись на DNS-сервере для вашего доменного имени.&lt;br /&gt;
&lt;br /&gt;
Для этого необходимо послать запрос тому, кто выдал вам статические ip-адреса (обычно, это ваш провайдер) с просьбой зарегистрировать PTR запись для вашего домена.&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть одна для одного IP (не нужно создавать две записи для основного домена (mydomain.ru) и почтового домена (mail.mydomain.ru) если оба они привязаны А-записью к одному IP)&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть создана именно для MX записи. То есть, если адреса домена и почтового обменника не совпадают, то PTR создаем именно для MX записи.&lt;br /&gt;
&lt;br /&gt;
Например, если домен mydomain.ru находится по адресу 22.11.33.44, а почтовый обменник (MX запись) создана для хоста mail.mydomain.ru, расположенного по адресу 11.22.33.44, то и PTR запись нужно создавать для mail.mydomain.ru:&lt;br /&gt;
       44.33.22.11.in-addr.arpa  mail.mydomain.ru&lt;br /&gt;
  Естественно, можно &amp;quot;до кучи&amp;quot; создать обратную запись и для самого домена mydomain.ru. Она так же не помешает:&lt;br /&gt;
       44.33.11.22.in-addr.arpa  mydomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Резюмируя, необходимо сделать следующее: ====&lt;br /&gt;
1. Необходимо прописать ресурсную запись MX (MX 10 mail.yourdomain.ru.) для основного домена &amp;quot;yourdomain.ru&amp;quot;, указав что почтовым доменом MX-сервера является &amp;quot;mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делаем мы.&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего yourdomain.ru - 1.2.3.4   &lt;br /&gt;
   A yourdomain.ru 1.2.3.4&lt;br /&gt;
   MX 10 mail.yourdomain.ru.&lt;br /&gt;
2. Создать PTR-запись на DNS сервере регистратора&lt;br /&gt;
&lt;br /&gt;
IP домена &amp;quot;mail.yourdomain.ru&amp;quot; необязательно должен совпадать с IP &amp;quot;yourdomain.ru&amp;quot;, но PTR-запись должна быть создана регистратором IP-адреса (5.6.7.8) домена &amp;quot;mail.yourdomain.ru&amp;quot;. Если у нас несколько почтовых доменов на одном почтовом сервере и все они выходят через единственный внешний IP, то PTR соответствие необходимо прописать для домена, которым именуется (hostname) сам физический почтовый сервер.&lt;br /&gt;
&lt;br /&gt;
Например, сама физическая машина именуется mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
(&lt;br /&gt;
&lt;br /&gt;
Также для этого необходимо прописать &amp;quot;mail.yourdomain.ru&amp;quot; в следующих местах:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname mail.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cоответствие внешнего IP, для которого создаем PTR-запись, и домена mail.yourdomain.ru прописываем в /etc/hosts)&lt;br /&gt;
 ...&lt;br /&gt;
 45.67.59.224 mail.yourdomain.ru&lt;br /&gt;
Изменить настройки postfix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 myhostname = mail.yourdomain.ru&lt;br /&gt;
 myorigin = mail.yourdomain.ru&lt;br /&gt;
 mydomain = mail.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
mail.yourdomain.ru не обязан вообще быть почтовым доменом, но он будет в поле &amp;quot;helo: mail.yourdomain.ru&amp;quot; при отправке письма с любого другого почтового домена, работающего на нашем почтовом сервере. поэтому создаем ptr-запись именно для mail.yourdomain.ru - &amp;quot;8.7.6.5.in-addr.arpa mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делает регистратор внешнего IP&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего mail.yourdomain.ru 5.6.7.8&lt;br /&gt;
   8.7.6.5.in-addr.arpa mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Проверки ====&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host 5.6.7.8&amp;lt;/code&amp;gt;&lt;br /&gt;
       ...&lt;br /&gt;
       8.7.6.5.in-addr.arpa domain name pointer mail.yourdomain.ru.&lt;br /&gt;
       ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
Например, для домена mydomain.ru с адресом 215.54.54.54, необходимо зарегистрировать следующую запись:&lt;br /&gt;
       54.54.54.215.in-addr.arpa name=mydomain.ru&lt;br /&gt;
А если почтовый сервер сидит на отдельном адресе, например, mail.mydomain.ru имеет адрес 215.54.54.55, то необходимо зарегистрировать еще одну PTR запись:&lt;br /&gt;
       55.54.54.215.in-addr.arpa name=mail.mydomain.ru&lt;br /&gt;
Проверить наличие PTR записи на сервере DNS можно с помощью интерфейса команды NSLOOKUP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nslookup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь подключаемся к DNS-серверу провайдера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;server 215.54.54.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Устанавливаем тип ресурсной записи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set type=PTR&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Делаем запрос на интересующий нас адрес:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;215.54.54.54&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ответ мы должны получить имя своего домена mydomain.ru&lt;br /&gt;
&lt;br /&gt;
=== SPF ===&lt;br /&gt;
SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain. In your DNS management interface, create a new TXT record like below.&lt;br /&gt;
&lt;br /&gt;
Add TXT-record to your main domain (for example &amp;quot;yourdomain.ru&amp;quot;, _NOT_ subdomain &amp;quot;mail.yourdomain.ru&amp;quot;!)&lt;br /&gt;
 A yourdomain.ru 45.67.59.224&lt;br /&gt;
 MX 10 mail.yourdomain.ru.&lt;br /&gt;
 TXT v=spf1 mx ~all&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   yourdomain.ru.              10      IN      TXT     &amp;quot;v=spf1 mx ~all&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DKIM ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Add first mail domain ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to add second and following as well as the first&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/lib/dkim&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate PEM for our domain&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; domain.ru - the first domain, for wich we generated dkim&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;amavisd genrsa /var/lib/dkim/dmosk.ru.pem 1024&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown amavis:amavis /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 0400 /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;$inet_socket_port = 10024;&lt;br /&gt;
 &lt;br /&gt;
 # Add&lt;br /&gt;
 &lt;br /&gt;
 $inet_socket_port = [10024,10026];&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find this string (its value must be &amp;quot;1&amp;quot;)&lt;br /&gt;
 $enable_dkim_verification = 1;  # enable DKIM signatures verification&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; After the string above add following&lt;br /&gt;
 &lt;br /&gt;
 dkim_key('yourdomain.ru', &amp;quot;dkim&amp;quot;, &amp;quot;/var/lib/dkim/yourdomain.ru.pem&amp;quot;);&lt;br /&gt;
 @dkim_signature_options_bysender_maps = ( {&lt;br /&gt;
   &amp;quot;yourdomain.ru&amp;quot; =&amp;gt; { d =&amp;gt; &amp;quot;yourdomain.ru&amp;quot;, a =&amp;gt; 'rsa-sha256', ttl =&amp;gt; 10*24*3600 },&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; FIND THIS STRING. ITS VALUE MUST BE &amp;quot;1&amp;quot;&lt;br /&gt;
 $enable_dkim_signing = 1;    # load DKIM signing code, keys defined by dkim_key&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generate record for DNS server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf showkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   dkim._domainkey.yourdomain.ru.      3600 TXT (&lt;br /&gt;
   &amp;quot;v=DKIM1; p=&amp;quot;&lt;br /&gt;
   &amp;quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz&amp;quot;&lt;br /&gt;
   &amp;quot;3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUg&amp;quot;&lt;br /&gt;
   &amp;quot;jOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0J&amp;quot;&lt;br /&gt;
   &amp;quot;xfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9O&amp;quot;&lt;br /&gt;
   &amp;quot;YO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61N&amp;quot;&lt;br /&gt;
   &amp;quot;rJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVh&amp;quot;&lt;br /&gt;
   &amp;quot;kwIDAQAB&amp;quot;)&lt;br /&gt;
   ...&lt;br /&gt;
Copy it from &amp;quot;&amp;quot;v=DKIM1...&amp;quot; to &amp;quot;...kwIDAQAB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove all &amp;quot;&amp;quot; and line breaks&lt;br /&gt;
&lt;br /&gt;
You'll get something like this (in one line):&lt;br /&gt;
 v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Create subdomain &amp;quot;dkim._domainkey&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;dkim._domainkey&amp;quot; subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 TXT v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test at mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf testkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   TESTING#1 yourdomain.ru: dkim._domainkey.yourdomain.ru =&amp;gt; pass&lt;br /&gt;
   ...&lt;br /&gt;
Test on arbitrary server in internet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig dkim._domainkey.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   dkim._domainkey.yourdomain.ru. 10   IN      TXT     &amp;quot;v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjz&amp;quot; &amp;quot;zr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DMARC ===&lt;br /&gt;
DMARC stands for Domain-based Message Authentication, Reporting and Conformance. DMARC can help receiving email servers to identify legitimate emails and prevent your domain name from being used by email spoofing.&lt;br /&gt;
&lt;br /&gt;
To create a DMARC record, go to your DNS manager and add a TXT record. In the name field, enter _dmarc. In the value field, enter the following. (You should create the dmarc@your-domain.com email address.)&lt;br /&gt;
&lt;br /&gt;
Create subdomain &amp;quot;_dmarc&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;_dmarc&amp;quot; (_dmarc.yourdomain.ru) subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 A 45.67.59.224&lt;br /&gt;
 TXT v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig _dmarc.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
  �;; ANSWER SECTION:&lt;br /&gt;
   _dmarc.yourdomain.ru.       10      IN      TXT     &amp;quot;v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
General deliverability test&lt;br /&gt;
&lt;br /&gt;
Go to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://www.mail-tester.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send email from your mail account of your new mail server to randomly generated service's mail address (test-avlwah6p3@srv1.mail-tester.com, for example)&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Затем проверьте оценку&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wait for tests passed&lt;br /&gt;
&lt;br /&gt;
If your score higher than 8, congratulations! &lt;br /&gt;
&lt;br /&gt;
= Add additional mail domain =&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
Root domain and MX-record, which point to the for mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=cless.pro mx-exchange=mail.cless.pro mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.cless.pro address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL certs ===&lt;br /&gt;
&lt;br /&gt;
==== Lentencrypt ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail.cless.pro,mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certs ====&lt;br /&gt;
Add additional cert configs for a new domain for '''Nginx''', '''Postfix''' and '''Dovecot'''.&lt;br /&gt;
&lt;br /&gt;
=== Improving email deliverability ===&lt;br /&gt;
Check the '''Improving email deliverability''' section of this manual and do corresponding actions.&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin web panel ===&lt;br /&gt;
&lt;br /&gt;
* Create domain cless.pro&lt;br /&gt;
* Create mailbox cless@cless.pro&lt;br /&gt;
&lt;br /&gt;
=== Roundcube webmail ===&lt;br /&gt;
Login to Roundcube webmail&lt;br /&gt;
&lt;br /&gt;
Send/Receive email&lt;br /&gt;
&lt;br /&gt;
= Autodiscover Mail Server settings for Mail Clients =&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=autodiscover-mail&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
It provides mail clients Mail Server connection info during configuring Mail Client mailbox&lt;br /&gt;
&lt;br /&gt;
=== Thinderbird ===&lt;br /&gt;
Механизм автонастройки от Mozilla похож на Microsoft. Необходимые настройки должны отдаваться веб-сервером в виде XML-документа. Однако запрос не https, а http; и не POST, а GET. Также обращение идет сначала в формате '''server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain''', и если ответ не будет получен — '''autoconfig.server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain'''.&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;Create А-record (or CNAME) for root domain (example.com):&amp;lt;blockquote&amp;gt;''* где  '''111.111.111.111''' — IP-address of web server, with XML.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 autoconfig    IN      A       111.111.111.111&lt;br /&gt;
&lt;br /&gt;
==== Nginx config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/910-autodiscover_example.ru.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
# HTTP&lt;br /&gt;
server {&lt;br /&gt;
    listen 80;&lt;br /&gt;
    server_name autoconfig.example.com;&lt;br /&gt;
    root /usr/share/nginx/html/autodiscover/example.com;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autodiscover config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /usr/share/nginx/html/autodiscover/example.ru/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/autodiscover/example.ru/mail/config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;emailProvider id=&amp;quot;example.com&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;domain&amp;gt;example.com&amp;lt;/domain&amp;gt;&lt;br /&gt;
                &amp;lt;displayName&amp;gt;Mail example.com&amp;lt;/displayName&amp;gt;&lt;br /&gt;
                &amp;lt;displayShortName&amp;gt;example.com&amp;lt;/displayShortName&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;143&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;pop&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;pop.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;995&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;SSL&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;587&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/outgoingServer&amp;gt;&lt;br /&gt;
        &amp;lt;/emailProvider&amp;gt;&lt;br /&gt;
&amp;lt;/clientConfig&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simpliest method according to the RFC standard (I'm not sure that it works) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;It works in unstable way. The mail client usually managed to get mail server info, but not everything. Mail client gets '''hosts''' (for example, imap.yourdomain.ru), but not the '''ports'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
You need to add ''subdomains'' for your ''main domain'' '''yourdomain.ru''' and create '''SRV''' records&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
 _&amp;lt;service name&amp;gt;._&amp;lt;protocol&amp;gt; &amp;lt;priority&amp;gt; &amp;lt;weight&amp;gt; &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;&lt;br /&gt;
Examples&lt;br /&gt;
 _smtp._tcp              IN SRV  10 0 25  smtp.yourdomain.ru.&lt;br /&gt;
 _pop3._tcp              IN SRV  20 0 110 pop.yourdomain.ru.&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _smtps._tcp             IN SRV   0 0 465 smtp.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
 _imaps._tcp             IN SRV   0 0 993 imap.yourdomain.ru.&lt;br /&gt;
 _pop3s._tcp             IN SRV  10 0 995 pop.yourdomain.ru.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
To give your mail clients info about '''imap''' and '''smtp''' settings of your mail server:&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
&lt;br /&gt;
= Full-text search =&lt;br /&gt;
&lt;br /&gt;
== Fts-xapian ('''It works good!''') ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://github.com/grosjo/fts-xapian]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/#community-developed-plugins]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/settings/plugin/fts-plugin/]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin]&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
Dovecot has some problems with email searching if there's a huge amount of emails in the mailbox. It can perodically throw an error &amp;quot;Server error&amp;quot; during the search.&lt;br /&gt;
&lt;br /&gt;
To avoid such problems we can use Full-text search.&lt;br /&gt;
&lt;br /&gt;
=== Build plugin ===&lt;br /&gt;
&lt;br /&gt;
==== Variant 1. Build plugin at the same machine ====&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
==== Variant 2. Build plugin at the another machine with the same arch and apps versions, and copy compiled plugin to the mail server ====&lt;br /&gt;
&lt;br /&gt;
===== Another machine for building =====&lt;br /&gt;
Build plugin at the another machine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy plugin to the mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rsync -avPh /usr/lib64/dovecot/lib21_fts_xapian_plugin.* root@&amp;lt;mail-server-IP&amp;gt;:/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== Configure plugin at the mail server ===&lt;br /&gt;
Check the installed plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /usr/lib64/dovecot/lib21_fts_xapian_plugin.*&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     -rw-r--r-- 1 root root 2.9M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.a&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.1K Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.la&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.2M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.so&lt;br /&gt;
     ...&lt;br /&gt;
Add plugin to the common conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
mail_plugins = $mail_plugins &amp;lt;...&amp;gt; fts fts_xapian&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Add plugin config&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/95-fts.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;partial=2 - the minimum length of the search string&lt;br /&gt;
&lt;br /&gt;
fts_autoindex = yes/no - whether to run reindex in background or not. TAKES A LOT OF RESOURCES CONSTANTLY AND MIGHT FAIL USER SEARCH. BETTER RUN MANUAL REINDEX: '''doveadm index -u user@domain.ru \*'''&lt;br /&gt;
&lt;br /&gt;
fts_enforced = yes/no - The system must use Xapian for full-text search. Alternative search backends are disabled or not permitted. All text indexing will be handled by Xapian&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
plugin {&lt;br /&gt;
    fts = xapian&lt;br /&gt;
    fts_xapian = partial=2 full=20 attachments=0 verbose=0&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex = yes&lt;br /&gt;
    fts_enforced = yes&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex_exclude = \Trash&lt;br /&gt;
&lt;br /&gt;
    # Index attachements&lt;br /&gt;
    fts_decoder = decode2text&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service indexer-worker {&lt;br /&gt;
    # Increase vsz_limit to 2GB or above.&lt;br /&gt;
    # Or 0 if you have rather large memory usable on your server, which is preferred for performance)&lt;br /&gt;
    vsz_limit = 2G&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service decode2text {&lt;br /&gt;
    executable = script /usr/libexec/dovecot/decode2text.sh&lt;br /&gt;
    user = dovecot&lt;br /&gt;
    unix_listener decode2text {&lt;br /&gt;
        mode = 0666&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot and check the service status. There shouldn't be errors or warnings in the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's necessary to index all the mailboxes if you have already had productive and filled mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm index -u $i \*; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm index -u user@domain.ru \*&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
       '''fts optimize'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts optimize [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
&lt;br /&gt;
       '''fts rescan'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts rescan [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Scan what mails exist in the full text search index and compare those to what actually exist in mailboxes.  This removes mails from the index that have already been expunged and makes sure&lt;br /&gt;
&lt;br /&gt;
           that  the  next  doveadm index will index all the missing mails (if any). Note that currently most FTS backends do not implement this properly, but instead they delete all the FTS indexes.&lt;br /&gt;
&lt;br /&gt;
           This may change in the future versions.&amp;lt;/blockquote&amp;gt;Place the task to optimize your xapian indexes into the crontab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
 0 4 * * * for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts optimize -u $i; done&lt;br /&gt;
 ...&lt;br /&gt;
Optionally&amp;lt;blockquote&amp;gt;I'm not sure this is really necessary&lt;br /&gt;
&lt;br /&gt;
It takes a lot of time and during this process the search doesn't work&lt;br /&gt;
&lt;br /&gt;
Also, after the rescan, the directories &amp;quot;/home/mail/&amp;lt;domain&amp;gt;/&amp;lt;user&amp;gt;/xapian-indexes/db_*&amp;quot; will be deleted, and they will be created only after a user will click on the directories in the web-interface. It takes also a lot of time&lt;br /&gt;
&lt;br /&gt;
You can rescan indexes of your mailboxes&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts rescan -u $i; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm fts rescan -u user@domain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the console&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y telnet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;telnet localhost imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a login user@don661.ru PassWord#1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a select Inbox&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a SEARCH text &amp;quot;test&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the '''Roundcube Webmail'''&amp;lt;blockquote&amp;gt;In '''Roundcube Webmail''' for the searching of text in the message body it's necessary to click on the arrow right to the search field and to check &amp;quot;'''Message body'''&amp;quot; as a search source!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SOLR ('''I didn't test it!''') ==&lt;br /&gt;
https://doc.dovecot.org/configuration_manual/fts/solr/&lt;br /&gt;
&lt;br /&gt;
== Fts-elastic ('''I didn't test it!''') ==&lt;br /&gt;
https://github.com/filiphanes/fts-elastic&lt;br /&gt;
&lt;br /&gt;
= Postfix limits (I didn't test it!) =&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=postfix-limits#mailbox-size&lt;br /&gt;
&lt;br /&gt;
= Desktop mail clients =&lt;br /&gt;
&lt;br /&gt;
=== Thunderbird ===&lt;br /&gt;
'''IMAP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 143&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
'''SMTP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 587&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
= Hints =&lt;br /&gt;
&lt;br /&gt;
== Mail queue check ==&lt;br /&gt;
&amp;lt;code&amp;gt;mailq&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show connected users ==&lt;br /&gt;
Users IMAP (via mail clients)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm who&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users WEB Roundcube&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;netstat -an | grep :443 | grep -v TIME_WAIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restrict sending emails by local users with non-existing local domains in the field ''FROM'' ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 -o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject&lt;br /&gt;
 ...&lt;br /&gt;
You can see logs of PASSED o DROPPED emails in '''/var/log/maillog''' after sending them.&lt;br /&gt;
&lt;br /&gt;
== Reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files) ==&lt;br /&gt;
https://serverfault.com/questions/694511/postfix-how-to-reject-sender-addresses-that-dont-exist-only-for-local-domains&lt;br /&gt;
&lt;br /&gt;
Add the following option to '''/etc/postfix/main.cf''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 smtpd_reject_unlisted_sender = yes&lt;br /&gt;
 ...&lt;br /&gt;
You can try to send an email with non-existing user in field FROM, and you will see a rejection in output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)&amp;lt;/code&amp;gt;&lt;br /&gt;
== Message size limit (message size itself + attached file size) ==&lt;br /&gt;
You have to set limits in the each following entity.&lt;br /&gt;
&lt;br /&gt;
In this example we make limit at about ~30MB for attachment&lt;br /&gt;
&lt;br /&gt;
==== Postfix limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 message_size_limit = 46080000 # ~30MB (10240000 - ~10MB)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Roundcube limit ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube preserves some percentage of the max message size (search 1.33 on this page, so if you set the max to 100M, it tells you only 75MB is allowed (100 / 1.33). This is better because email messsage will be encoded before sending to MTA and the encoded attachment is larger than the original file.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['max_message_size'] = '40M'; # max summ message size (not file)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
==== Nginx limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 server {&lt;br /&gt;
     ...&lt;br /&gt;
     client_max_body_size 35M; # max size of a message&lt;br /&gt;
     client_body_timeout 300s; # timeout while upload attachment, otherwise upload may be canceled by timeout in case of a low upload speed, for example&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PHP limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 35M;&lt;br /&gt;
 upload_max_filesize = 35M;&lt;br /&gt;
 ...&lt;br /&gt;
reboot &lt;br /&gt;
&lt;br /&gt;
== Amount of attached files in an email ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; Maximum number of files that can be uploaded via a single request&lt;br /&gt;
 max_file_uploads = 50&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx.service php-fpm.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating users via CLI ==&lt;br /&gt;
&lt;br /&gt;
=== A single mailbox creation ===&lt;br /&gt;
Postfixadmin-cli installation&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;if you have already had installed postfixadmin, you don't have to do the following&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Help&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comment password validation limits (e.g. &amp;quot;# must contain at least 2 digits&amp;quot; or something you needed) in the array 'password_validation' of the postfix config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['password_validation'] = array(&lt;br /&gt;
 ...&lt;br /&gt;
 #    '/([0-9].*){2}/'        =&amp;gt; 'password_no_digits 2',      # must contain at least 2 digits&lt;br /&gt;
 ...&lt;br /&gt;
Create user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-cli mailbox add prod@domain123.ru --password &amp;quot;AlefStudioS*100&amp;quot; --password2 &amp;quot;AlefStudioS*100&amp;quot; --name &amp;quot;Компания AlefStudio&amp;quot; --quota &amp;quot;4096&amp;quot; --active --welcome-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mass mailboxes creation ===&lt;br /&gt;
Mailboxes list file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./mailboxes.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 john@domain.ru|pass1|John Smith&lt;br /&gt;
 ann@domain.ru|pass2|Анна Паста Бродерик-Иванова&lt;br /&gt;
Milbox creation script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Mass postfixadmin mailboxes creation by @ClessAlvein&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# VARS&lt;br /&gt;
&lt;br /&gt;
mailboxesListFile=&amp;quot;./USERS_lada-tambovavtocity.ru.txt&amp;quot;&lt;br /&gt;
mailboxQuota=&amp;quot;2048&amp;quot;&lt;br /&gt;
pfCli=&amp;quot;/usr/share/nginx/html/postfixadmin/scripts/postfixadmin-cli&amp;quot;&lt;br /&gt;
dateTimeCurrent=`date +%Y-%m-%d_%H-%M-%S`&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# SCRIPT START&lt;br /&gt;
&lt;br /&gt;
# declare array with mailbox data in the each line&lt;br /&gt;
declare -A arrayMailboxes;&lt;br /&gt;
&lt;br /&gt;
# getting each line from the file with each user's data&lt;br /&gt;
while IFS= read -r line || [[ &amp;quot;$line&amp;quot; ]];&lt;br /&gt;
do&lt;br /&gt;
  # getting user, pass, name from the line and put it to the assoc array key=value&lt;br /&gt;
  while IFS=&amp;quot;|&amp;quot; read &amp;quot;mailboxUserFromFile&amp;quot; &amp;quot;mailboxPassFromFile&amp;quot; &amp;quot;mailboxNameFromFile&amp;quot;;&lt;br /&gt;
  do&lt;br /&gt;
    # makeup&lt;br /&gt;
    echo &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # debug&lt;br /&gt;
    #echo &amp;quot;${mailboxUser}, ${mailboxPass}, ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # declare assoc array with each key as a bit mailbox's data&lt;br /&gt;
    declare -A arrayMailbox;&lt;br /&gt;
&lt;br /&gt;
    # each key is a bit of the mailbox's data&lt;br /&gt;
    arrayMailbox[arrayMailboxUser]=${mailboxUserFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxPass]=${mailboxPassFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxName]=${mailboxNameFromFile};&lt;br /&gt;
&lt;br /&gt;
    # for each bit of mailbox's data create var (user,pass,name)&lt;br /&gt;
    for key in &amp;quot;${!arrayMailbox[@]}&amp;quot;;&lt;br /&gt;
    do&lt;br /&gt;
      case $key in&lt;br /&gt;
      arrayMailboxUser)&lt;br /&gt;
        mailboxUser=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxPass)&lt;br /&gt;
        mailboxPass=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxName)&lt;br /&gt;
        mailboxName=${arrayMailbox[${key}]};;&lt;br /&gt;
      esac&lt;br /&gt;
    done&lt;br /&gt;
  done &amp;lt; &amp;lt;( echo ${line} )&lt;br /&gt;
&lt;br /&gt;
  # if ${mailboxName} is empty&lt;br /&gt;
  if [ -z &amp;quot;${mailboxName}&amp;quot; ]; then&lt;br /&gt;
    mailboxName=${mailboxUser}&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  # debug&lt;br /&gt;
  echo &amp;quot;mailboxUser: ${mailboxUser}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxPass: ${mailboxPass}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxName: ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  # create each mailbox&lt;br /&gt;
  ${pfCli} mailbox add ${mailboxUser} \&lt;br /&gt;
    --password &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --password2 &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --name &amp;quot;${mailboxName}&amp;quot; \&lt;br /&gt;
    --quota &amp;quot;${mailboxQuota}&amp;quot; \&lt;br /&gt;
    --active --welcome-mail \&lt;br /&gt;
    | tee -a ./log_${dateTimeCurrent}&lt;br /&gt;
&lt;br /&gt;
done &amp;lt; ${mailboxesListFile}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Create mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Roundcube Filter plugin (for email forwarding, sending copy of emails to another email, and other actions) ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=roundcube-managesieve&lt;br /&gt;
&lt;br /&gt;
We will use '''Roundcube managesieve plugin''' for that purpose&amp;lt;blockquote&amp;gt;* First off, check that there's no directory &amp;quot;sieve&amp;quot; in the &amp;quot;/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   * if you have already had '''mail_home = /home/vmail/%d/%u''' in this config, you have to edit it as deliberately '''mail_home = /home/vmail/%d/%u/sieve'''&lt;br /&gt;
&lt;br /&gt;
   * мы задаем опцию mail_home с путем до каталогов с почтой. Обратите внимание, что на вашем сервере настройка может быть другая и необходимо указать правильное значение. Переменные %d и %u указывают, соответственно, на имя домена и учетной записи.&lt;br /&gt;
 ...&lt;br /&gt;
 mail_home = /home/vmail/%d/%u/sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавляем плагин sieve, который должен теперь использоваться локальным агентом доставки lda.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocol lda {&lt;br /&gt;
   # Space separated list of plugins to load (default is global mail_plugins).&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-managesieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по аналогии с protocol lda, мы указываем на необходимость использования sieve&lt;br /&gt;
&lt;br /&gt;
   * мы указываем, что наш сервис будет работать на порту 4190&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocols = $protocols sieve&lt;br /&gt;
 ...&lt;br /&gt;
 service managesieve-login {&lt;br /&gt;
   inet_listener sieve {&lt;br /&gt;
     port = 4190&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *sieve — путь до файла с правилами. Указывается для каждого ящика с помощью переменных.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_path — путь до общего файла с правилами. Используется, если отсутствует файл по пути sieve.&lt;br /&gt;
&lt;br /&gt;
   *sieve_dir — путь до каталога с подключаемыми скриптами-правилами. Указывается для каждого почтового ящика.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_dir — путь до общего каталога с подключаемыми правилами. Используется, если отсутствует sieve_dir.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 plugin {&lt;br /&gt;
   sieve = /home/mail/%d/%u/sieve/dovecot.sieve&lt;br /&gt;
   sieve_global_path = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
   sieve_dir = /home/mail/%d/%u/sieve&lt;br /&gt;
   sieve_global_dir = /etc/dovecot/sieve/global/&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''!!! I'm not sure that the following is necessary'''&lt;br /&gt;
&lt;br /&gt;
'''!!! At first try not to make this actions'''&lt;br /&gt;
&lt;br /&gt;
'''!!! If everything works without it - nevermind'''&lt;br /&gt;
&lt;br /&gt;
   Create dir for global rules sieve_global_dir:&lt;br /&gt;
&lt;br /&gt;
       mkdir -p /etc/dovecot/sieve/global&lt;br /&gt;
&lt;br /&gt;
   Chown dir:&lt;br /&gt;
&lt;br /&gt;
       chown dovecot:dovecot -R /etc/dovecot/sieve&amp;lt;/blockquote&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Roundcube config edit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * At first, check that there's the &amp;quot;managesieve&amp;quot; plugin in the plugin directoty: &amp;quot;/usr/share/nginx/html/webmail/plugins/&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['managesieve_host'] = 'localhost';&lt;br /&gt;
 ...&lt;br /&gt;
 $config['plugins'] = [&lt;br /&gt;
     ...&lt;br /&gt;
     'managesieve',&lt;br /&gt;
 ];&lt;br /&gt;
 ...&lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
Go to Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
Create test filter (for example), copy message to another email after it will be received&lt;br /&gt;
 '''Settings''' - '''Filter''' - Filter &amp;quot;'''Roundcube'''&amp;quot; - &amp;quot;'''+'''&amp;quot;&lt;br /&gt;
     '''Filter name''': mail_forward&lt;br /&gt;
     '''Area''': ALL messages&lt;br /&gt;
     '''Action''': send copy to - xxx@mail.ru&lt;br /&gt;
         '''Save'''&lt;br /&gt;
Now you can see the brand new files in the directory &amp;quot;'''/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/sieve/'''&amp;quot; (config '''roundcube.sieve''' and symlink '''dovecot.sieve''' (config '''/etc/dovecot/conf.d/90-sieve.conf''' point to '''dovecot.sieve'''))&lt;br /&gt;
     ...&lt;br /&gt;
     dovecot.sieve -&amp;gt; roundcube.sieve&lt;br /&gt;
     roundcube.sieve&lt;br /&gt;
     ...&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
Send email to yourself&lt;br /&gt;
&lt;br /&gt;
The message will be received and will be sent to xxx@mail.ru as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, in that case, if you have a private per-user sieve script ('''/home/mail/%d/%u/sieve/dovecot.sieve''', we have already configured it), the global sieve script '''WON'T WORK'''!&lt;br /&gt;
&lt;br /&gt;
To make the private per-user script and the global script work at the same time, we need to do following.&lt;br /&gt;
&lt;br /&gt;
In this example we will filter all mail for all users, and put SPAM to the Junk directory.&lt;br /&gt;
&lt;br /&gt;
https://talk.plesk.com/threads/global-dovecot-sieve-rule.341552/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;*This rule filter SPAM (we have already configured spamassasin above, right?) and put it to Junk dir&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
     fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
Create the new global sieve configuration directive for Dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/37-custom-global-sieve.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 plugin {&lt;br /&gt;
 # Make sure to run &amp;quot;sievec&amp;quot; on this file after creating it:&lt;br /&gt;
 sieve_after = /etc/dovecot/conf.d/custom-sieve/global_after.sieve&lt;br /&gt;
 }&lt;br /&gt;
Run this to compile the new sieve, it will create a binary rule in the same directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sievec /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart the Dovecot services&amp;lt;blockquote&amp;gt;You don't have to start spamassasin service to make spam filter work. Amavisd does it!&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
If you have already configured Spamassassin in this manual above - send email to yourself with following in the message body: '''XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'''&lt;br /&gt;
&lt;br /&gt;
The message wil be put in the Junk directory and the copy of this message will be sent to xxx@mail.ru&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Apr 23 20:39:54 mail amavis[1696]: (01696-01) Passed SPAM {RelayedTaggedInternal,Quarantined}, MYNETS LOCAL [::1]:50042 &amp;lt;admin@alef-studio.ru&amp;gt; -&amp;gt; &amp;lt;admin@alef-studio.ru&amp;gt;, Queue-ID: BE39DE013B, Message-ID: &amp;lt;223db76d330a882501d9b6584e72e16b@alef-studio.ru&amp;gt;, mail_id: qx51q6idSWsl, Hits: 998.992, size: 1158, queued_as: 8850CE0A8A, 709 ms&lt;br /&gt;
     ...&lt;br /&gt;
Now we can configure the private filter rules for each user, and our global SPAM filter will work as well!&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Create new messages with HTML-EDITOR by default ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['htmleditor'] = 1;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Roundcube Pugin. Viewer Office Docs (DOC, XLS, ODT, ODS, etc.) ==&lt;br /&gt;
https://github.com/jfcherng-roundcube/plugin-cloudview&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Address-book from Windows AD DC on-line ==&lt;br /&gt;
&lt;br /&gt;
=== At Windows AD DC Server ===&lt;br /&gt;
Go to &amp;quot;'''Domain Users and Computers'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First off, you need to have a user &amp;quot;'''admin'''&amp;quot; with Administrator's permissions to connect to the AD DC from Roundcube&lt;br /&gt;
&lt;br /&gt;
Create a user in group &amp;quot;'''Users'''&amp;quot; with an email in (! '''You won't see any user at all in Roundcube web-interface if you don't add an email address to the specific users's field !''')&lt;br /&gt;
&lt;br /&gt;
Get a LDAP/AD Administartor's &amp;quot;'''admin'''&amp;quot; Distinguished Name for connect to AD from the Mail Server (we will use it later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;C:\Users\Администратор.WIN-RMJC4R0JMJR&amp;gt; '''dsquery user -name admin'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 '''&amp;quot;CN=admin,CN=Users,DC=alf,DC=local&amp;quot;'''&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== At Mail Server ===&lt;br /&gt;
Add to the Roundcube config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
//Разрешить поиск и автодополнение из массива AD&lt;br /&gt;
$rcmail_config['autocomplete_addressbooks'] = array('sql','AD');&lt;br /&gt;
&lt;br /&gt;
$config['ldap_public'] = array(&lt;br /&gt;
//Имя массива, в котором выполняется поиск&lt;br /&gt;
    'AD' =&amp;gt;array (&lt;br /&gt;
        'name' =&amp;gt; 'ALF', //Отображаемое имя в интерфейсе WEBMail Roundcube&lt;br /&gt;
        'hosts' =&amp;gt; array('10.100.199.21'), //IP адрес или ДНС имя AD DC&lt;br /&gt;
        'sizelimit' =&amp;gt; 600,&lt;br /&gt;
        'port' =&amp;gt; 389,&lt;br /&gt;
        'use_tls' =&amp;gt; false,&lt;br /&gt;
        'user_specific' =&amp;gt; false,&lt;br /&gt;
        'base_dn' =&amp;gt; 'DC=alf,DC=local', //Где выполнять поиск&lt;br /&gt;
        'bind_dn' =&amp;gt; 'admin@alf.local', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'bind_pass' =&amp;gt; 'PassWord#1', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'writable' =&amp;gt; false,&lt;br /&gt;
        'ldap_version' =&amp;gt; 3,&lt;br /&gt;
        'search_fields' =&amp;gt; array(&lt;br /&gt;
           'mail',&lt;br /&gt;
           'cn',&lt;br /&gt;
        ),&lt;br /&gt;
        'name_field' =&amp;gt; 'cn',&lt;br /&gt;
        'email_field' =&amp;gt; 'mail',&lt;br /&gt;
        'surname_field' =&amp;gt; 'sn',&lt;br /&gt;
        'firstname_field' =&amp;gt; 'givenName',&lt;br /&gt;
        //Можно добавить немного дополнительной информации в адресной книге&lt;br /&gt;
        'organization_field'     =&amp;gt; 'company',&lt;br /&gt;
        'jobtitle_field'    =&amp;gt; 'title',&lt;br /&gt;
        'department_field'   =&amp;gt; 'department',&lt;br /&gt;
        //Порядок сортировки&lt;br /&gt;
        'sort' =&amp;gt; 'sn',&lt;br /&gt;
        'scope' =&amp;gt; 'sub', //Выполнять поиск по всему каталогу LDAP // search mode: sub|base|list&lt;br /&gt;
        'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectClass=user)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        //'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectcategory=person)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        'global_search' =&amp;gt; true,&lt;br /&gt;
        'fuzzy_search' =&amp;gt; true&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// LDAP&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache'.&lt;br /&gt;
$config['ldap_cache'] = 'db';&lt;br /&gt;
// Lifetime of LDAP cache. Possible units: s, m, h, d, w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Go to Roundcube web-interface - Contacts&lt;br /&gt;
&lt;br /&gt;
You will see new section &amp;quot;ALF&amp;quot; and contact in there&lt;br /&gt;
&lt;br /&gt;
You can debug if something goes wrong:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /usr/share/nginx/html/webmail/logs/errors.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Amavis blocks some inbound emails addresses with error &amp;quot;'''Blocked BAD-HEADER-0'''&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
https://sourceforge.net/p/amavis/mailman/message/16755074/&lt;br /&gt;
&lt;br /&gt;
https://www.habibza.in/amavisd-whitelist-or-allowed-mail-from-blocked-bad-header/&lt;br /&gt;
&lt;br /&gt;
https://forum.iredmail.org/topic4681-solved-how-to-bypass-amavisd-for-some-senders.html&lt;br /&gt;
&lt;br /&gt;
=== Solution 1 ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $final_bad_header_destiny = D_PASS;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ??? Solution 2. DOESN'T WORK ??? ===&lt;br /&gt;
Create whitelist of emails or even domains, which you want to allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/whitelist-badheader&amp;lt;/code&amp;gt;&lt;br /&gt;
 user@somedomain.com&lt;br /&gt;
 somedomain.com&lt;br /&gt;
Edit amavis config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # white list, which will allow inbound emails with BAD-HEADER-0&lt;br /&gt;
 @bypass_header_checks_maps = (&lt;br /&gt;
    read_hash(&amp;quot;/etc/amavisd/whitelist-badheader&amp;quot;),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
Restart services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logging users' action (e.g. copying, erasing users' emails), which users perform via any IMAP/POP3 mail clients, via Dovecot MDA logging ==&lt;br /&gt;
Enable mail plugins in Dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_plugins = $mail_plugins mail_log notify&lt;br /&gt;
 ...&lt;br /&gt;
Enable plugins '''mail_log_events, mail_log_fields'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/conf.d/90-plugin.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
plugin {&lt;br /&gt;
  #setting_name = value&lt;br /&gt;
&lt;br /&gt;
  # Events to log. Defined in src/plugins/mail-log/mail-log-plugin.c - also available: flag_change save mailbox_create&lt;br /&gt;
  # autoexpunge is included in expunge&lt;br /&gt;
  mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename&lt;br /&gt;
&lt;br /&gt;
  # Also available: Defined in src/plugins/mail-log/mail-log-plugin.c - flags vsize from subject&lt;br /&gt;
  mail_log_fields = uid box msgid from subject&lt;br /&gt;
&lt;br /&gt;
  # Don't log fields that require opening the email (v2.2.28+).&lt;br /&gt;
  #mail_log_cached_only = yes&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make some actions in the user's mailbox (e.g. move email to the Trash and then delete it completely)&lt;br /&gt;
&lt;br /&gt;
Now you can look in the logs ('''expunge = delete''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat '''/var/log/dovecot-info.log''' | grep &amp;quot;'''Info: expunge'''\|'''Info: copy'''&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
 May 11 10:53:56 imap(admin@don661.ru)&amp;lt;259523&amp;gt;&amp;lt;aw5K9CgY6oN/AAAB&amp;gt;: Info: '''copy''' from INBOX: box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 May 11 10:54:13 imap(admin@don661.ru)&amp;lt;259531&amp;gt;&amp;lt;JGZG9SgYLKZ/AAAB&amp;gt;: Info: '''expunge''': box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 May 11 11:08:21 pop3(admin@don661.ru)&amp;lt;259979&amp;gt;&amp;lt;Mz/SJykYIdpOhIjD&amp;gt;: Info: '''expunge''': box=INBOX, uid=10, msgid=&amp;lt;65e7897f-b08d-4f13-8655-73d08485b2f2@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
&lt;br /&gt;
== Block particular senders (emails, domains) - inbox mail (Заблокировать конкретные ящики-отправители или домены - входящую почту) ==&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/header_checks&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 /^From:.*baduser@example.com/ REJECT&lt;br /&gt;
 /^From:.*@spamdomain.com/ REJECT&lt;br /&gt;
 /^From:.*@scientamicron.com/ REJECT&lt;br /&gt;
 /^From:.*@ip-223-6.dataclub.info/ REJECT&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; BLOCK SENDERS LIST&lt;br /&gt;
 header_checks = regexp:/etc/postfix/header_checks&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send an email from the blocked user (user01@gmail.com)&lt;br /&gt;
&lt;br /&gt;
Check logs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Mar 16 22:11:27 mail postfix/cleanup[3119]: 0D83BE1E24: reject: header From: &amp;quot;user01@gmail.com&amp;quot; &amp;lt;user01@gmail.com&amp;gt; from mail-lj1-f176.google.com[209.85.208.176]; from=&amp;lt;user01@gmail.com&amp;gt; to=&amp;lt;call.center2@lada-tambovavtocity.ru&amp;gt; proto=ESMTP helo=&amp;lt;mail-lj1-f176.google.com&amp;gt;: 5.7.1 message content rejected&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
= Errors =&lt;br /&gt;
&lt;br /&gt;
=== Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat ./dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
        ...&lt;br /&gt;
        Feb 16 16:18:17 lda(cless@yourdomain.ru)&amp;lt;2571&amp;gt;&amp;lt;B0HqGhkt7mMLCgAA1XGFgw&amp;gt;: Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database&lt;br /&gt;
        ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
    mail_home = /home/mail/%d/%u&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         Feb 27 00:56:40 imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem&lt;br /&gt;
         ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: '''&amp;quot;Connection error (failed to reach the server) roundcube&amp;quot;''' at Roundcube Webmail web-interface during sending a message, if the size of the message is 10MB+ (a huge sign with pictures, for example) ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
The update from '''PHP-7.3''' to '''PHP-7.4''' has solved the issue.&lt;br /&gt;
&lt;br /&gt;
=== ERROR: PHP-ImageMagick module creates huge files, which use all disk space in / partition ===&lt;br /&gt;
https://github.com/ImageMagick/ImageMagick/issues/395&lt;br /&gt;
&lt;br /&gt;
PHP-ImageMagick module creates huge files, which use all disk space in / partition&lt;br /&gt;
 /tmp/systemd-private-78b2a42fd129405aa1e735b61bf8fb72-php-fpm.service-Icx1Wg/tmp/magick-*&lt;br /&gt;
??? SOLUTION ???&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 1:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/ImageMagick-7/policy.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;policymap&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;memory&amp;quot; value=&amp;quot;2GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;disk&amp;quot; value=&amp;quot;1GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;cache&amp;quot; name=&amp;quot;synchronize&amp;quot; value=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/policymap&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 2:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the following cron jobs for automatic cleanup. The first 2 lines will clean up old files based on their age.&lt;br /&gt;
&lt;br /&gt;
In one case this was still insufficient, since a user was uploading a lot of very large images within a short time, causing the /tmp folder to fill up very quickly. Therefore the last line removes images which are at a certain filesize treshold. I picked a treshold just below the usual size of the magick-* files (see list in first post).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Temporary solution to prevent /tmp from being filled with 200+ MB ImageMagick files&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'magick-*' -delete&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'php*' -delete&lt;br /&gt;
 */5 * * * * find /tmp/ -mmin +5 -type f -name 'magick-*' -size +200M -delete&lt;br /&gt;
&lt;br /&gt;
=== Error in '''Roundcube Webmail during the searching for emails''': '''(Server error)''' ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
It's necessary to Install Full-text search.&lt;br /&gt;
&lt;br /&gt;
Proceed to the according section of this manual: '''Fts-xapian'''.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Kubernetes._PV._%D0%9F%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9_%D1%82%D0%BE%D0%BC._%D0%A5%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B5_%D0%B4%D0%BB%D1%8F_%D0%BC%D0%BE%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D1%8B&amp;diff=1927</id>
		<title>Kubernetes. PV. Постоянный том. Хранилище для монтирования в контейнеры</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Kubernetes._PV._%D0%9F%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9_%D1%82%D0%BE%D0%BC._%D0%A5%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B5_%D0%B4%D0%BB%D1%8F_%D0%BC%D0%BE%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D1%8B&amp;diff=1927"/>
		<updated>2025-03-20T03:51:28Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Описание =&lt;br /&gt;
Создание и подключение постоянного тома (PV) к POD&lt;br /&gt;
&lt;br /&gt;
= Ссылки =&lt;br /&gt;
https://habr.com/ru/company/southbridge/blog/519642/&lt;br /&gt;
&lt;br /&gt;
https://kb.selectel.ru/docs/solutions-and-partner-services/file-storage/sfs-to-kubernetes/sfs-to-kubernetes-cifs/&lt;br /&gt;
&lt;br /&gt;
= Описание =&lt;br /&gt;
Постоянный том (Persistent Volume, PV) — это блочное хранилище заданного размера, которое существует независимо от жизненного цикла пода.&lt;br /&gt;
&lt;br /&gt;
Использование постоянного тома позволит вам управлять или обновлять поды, не беспокоясь о потере кода приложения.&lt;br /&gt;
&lt;br /&gt;
Доступ к постоянному тому можно получить с помощью PersistentVolumeClaim, или PVC, который монтирует постоянный том по требуемому пути.&lt;br /&gt;
&lt;br /&gt;
= Настройка =&lt;br /&gt;
&lt;br /&gt;
== SMB ==&lt;br /&gt;
&lt;br /&gt;
=== Установка CSI-драйвера для Samba ===&lt;br /&gt;
Для установки драйвера нужен пакетный менеджер helm.&lt;br /&gt;
&lt;br /&gt;
Скачайте пакетный менеджер helm chart и CSI-драйвер с GitHub Kubernetes CSI.&lt;br /&gt;
&lt;br /&gt;
Установите последнюю версию драйвера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;helm repo add csi-driver-smb &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;helm install csi-driver-smb csi-driver-smb/csi-driver-smb --namespace kube-system --version v1.4.0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверьте, что поды установлены и запущены:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl --namespace=kube-system get pods --selector=&amp;quot;app=csi-smb-controller&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создание секрета для доступа к SMB ресурсу ===&lt;br /&gt;
Создайте секрет для хранения логина и пароля на сервере SMB (по умолчанию guest/guest)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl create secret generic smbcreds --from-literal username='''user1''' --from-literal password='''PassWord'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Создать манифест для StorageClass ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./sfs_storage_class.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 apiVersion: storage.k8s.io/v1&lt;br /&gt;
 kind: StorageClass&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: smb&lt;br /&gt;
 provisioner: smb.csi.k8s.io&lt;br /&gt;
 parameters:&lt;br /&gt;
   '''source: &amp;quot;//192.168.1.1/share/code&amp;quot;'''&lt;br /&gt;
   csi.storage.k8s.io/provisioner-secret-name: &amp;quot;smbcreds&amp;quot;&lt;br /&gt;
   csi.storage.k8s.io/provisioner-secret-namespace: &amp;quot;default&amp;quot;&lt;br /&gt;
   csi.storage.k8s.io/node-stage-secret-name: &amp;quot;smbcreds&amp;quot;&lt;br /&gt;
   csi.storage.k8s.io/node-stage-secret-namespace: &amp;quot;default&amp;quot;&lt;br /&gt;
 reclaimPolicy: Delete&lt;br /&gt;
 volumeBindingMode: Immediate&lt;br /&gt;
 mountOptions:&lt;br /&gt;
   '''- dir_mode=0777'''&lt;br /&gt;
   '''- file_mode=0777'''&lt;br /&gt;
Примените манифест&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f ./sfs_storage_class.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверьте, что StorageClass создался:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get storageclass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создать манифест для PersistentVolumeClaim&amp;lt;blockquote&amp;gt;storage: 10Gi — размер файлового хранилища&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano ./sfs_persistent_volume_claim.yaml:&amp;lt;/code&amp;gt;&lt;br /&gt;
 apiVersion: v1&lt;br /&gt;
 kind: PersistentVolumeClaim&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: code&lt;br /&gt;
   annotations:&lt;br /&gt;
     volume.beta.kubernetes.io/storage-class: smb&lt;br /&gt;
 spec:&lt;br /&gt;
   accessModes: [&amp;quot;ReadWriteMany&amp;quot;]&lt;br /&gt;
   resources:&lt;br /&gt;
     requests:&lt;br /&gt;
       storage: 10Gi&lt;br /&gt;
Примените манифест в кластер&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f ./sfs_persistent_volume_claim.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверьте, что PersistentVolumeClaim создался:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pvc&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME   STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE&lt;br /&gt;
     '''code'''   Bound    pvc-bf00cd44-2c4e-4be0-a588-277c9ff62307   1Gi        RWX            smb            66m&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pv&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   REASON   AGE&lt;br /&gt;
     pvc-bf00cd44-2c4e-4be0-a588-277c9ff62307   1Gi        RWX            Delete           Bound    default/code   smb                     67m&lt;br /&gt;
     ...&lt;br /&gt;
Смотрим что на шаре создалась директория&lt;br /&gt;
 \\192.168.199.174\share\code\pvc-480016f0-1351-42c9-ba4e-146397c7cd1d\&lt;br /&gt;
Подключить хранилище PV в POD (через Deployment)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano nginx02.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 apiVersion: apps/v1&lt;br /&gt;
 kind: Deployment&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: nginx02&lt;br /&gt;
 spec:&lt;br /&gt;
   replicas: 2&lt;br /&gt;
   selector:&lt;br /&gt;
     matchLabels:&lt;br /&gt;
       app: nginx02&lt;br /&gt;
   strategy:&lt;br /&gt;
     rollingUpdate:&lt;br /&gt;
       maxSurge: 1&lt;br /&gt;
       maxUnavailable: 1&lt;br /&gt;
     type: RollingUpdate&lt;br /&gt;
   template:&lt;br /&gt;
     metadata:&lt;br /&gt;
       labels:&lt;br /&gt;
         app: nginx02&lt;br /&gt;
     spec:&lt;br /&gt;
       volumes:&lt;br /&gt;
       - name: '''code'''&lt;br /&gt;
         persistentVolumeClaim:&lt;br /&gt;
           claimName: '''code'''&lt;br /&gt;
       containers:&lt;br /&gt;
       - image: nginx:1.16&lt;br /&gt;
         name: nginx02&lt;br /&gt;
         volumeMounts:&lt;br /&gt;
         - name: '''code'''&lt;br /&gt;
           mountPath: '''/code'''&lt;br /&gt;
Применяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f nginx02.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pods -o wide&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME                   READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES&lt;br /&gt;
     nginx02-69bc47fc78-k6gpz                       1/1     Running   0          3s     172.16.213.219    kub-node-3   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;&lt;br /&gt;
     nginx02-69bc47fc78-zq6q4                       1/1     Running   0          3s     172.16.213.187    kub-node-1   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
Можно зайти в контейнер и убедиться что директория &amp;quot;'''code'''&amp;quot; примонтировалась&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl exec -i -t pods/nginx02-69bc47fc78-k6gpz -- /bin/bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;   root@php-58bd8849c6-bgxz2:/var/www/html# ls -lh '''/code/'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А также создать файл посмотреть что на шаре он появился&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;code&amp;gt;root@php-58bd8849c6-bgxz2:/var/www/html# echo 123 &amp;gt; /code/test.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим шару&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\\192.168.199.174\share\code\pvc-480016f0-1351-42c9-ba4e-146397c7cd1d\test.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом мы создали постоянное хранилище SMB для контейнеров&lt;br /&gt;
&lt;br /&gt;
== CephFS ==&lt;br /&gt;
&lt;br /&gt;
=== CEPH сервер ===&lt;br /&gt;
Получаем ключ админа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ceph auth get-key client.admin&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     AQAvoRlj44oJDhAApP3iMHMRBCdvh5Xr7346Jg==&lt;br /&gt;
     ...&lt;br /&gt;
Получаем ID кластера и IP хостов&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ceph mon dump&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     fsid 33f476b0-2f4c-11ed-896a-00505682bc3e&lt;br /&gt;
     ...&lt;br /&gt;
     0: [v2:192.168.199.122:3300/0,v1:192.168.199.122:6789/0] mon.ceph02&lt;br /&gt;
     1: [v2:192.168.199.123:3300/0,v1:192.168.199.123:6789/0] mon.ceph03&lt;br /&gt;
     2: [v2:192.168.199.121:3300/0,v1:192.168.199.121:6789/0] mon.ceph01&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== KUBERNETES сервер управления ===&lt;br /&gt;
Устанавливаем csi драйвер для работы с ceph&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;helm repo add ceph-csi &amp;lt;nowiki&amp;gt;https://ceph.github.io/csi-charts&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем файл настройки&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;helm inspect values ceph-csi/ceph-csi-cephfs &amp;gt; '''cephfs.yml'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Меняем значения в файле cephfs.yml&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano cephfs.yml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 csiConfig:&lt;br /&gt;
 - clusterID: &amp;quot;33f476b0-2f4c-11ed-896a-00505682bc3e&amp;quot;&lt;br /&gt;
   monitors:&lt;br /&gt;
   - &amp;quot;192.168.199.121:6789&amp;quot;&lt;br /&gt;
   - &amp;quot;192.168.199.122:6789&amp;quot;&lt;br /&gt;
   - &amp;quot;192.168.199.123:6789&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 nodeplugin:&lt;br /&gt;
   httpMetrics:&lt;br /&gt;
     enabled: true&lt;br /&gt;
     containerPort: 8091&lt;br /&gt;
 ...&lt;br /&gt;
   podSecurityPolicy:&lt;br /&gt;
     enabled: true&lt;br /&gt;
 ...&lt;br /&gt;
 provisioner:&lt;br /&gt;
   replicaCount: 1&lt;br /&gt;
 ...&lt;br /&gt;
   podSecurityPolicy:&lt;br /&gt;
     enabled: true&lt;br /&gt;
 ...&lt;br /&gt;
Устанавливаем чарт&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f '''cephfs.yml'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем secret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano secret.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ---&lt;br /&gt;
 apiVersion: v1&lt;br /&gt;
 kind: Secret&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: csi-cephfs-secret&lt;br /&gt;
 stringData:&lt;br /&gt;
 # Required for dynamically provisioned volumes&lt;br /&gt;
   adminID: '''admin'''&lt;br /&gt;
   adminKey: '''AQAvoRlj44oJDhAApP3iMHMRBCdvh5Xr7346Jg=='''&lt;br /&gt;
Применяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl create -f secret.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем storageClass&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano storageclass.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 apiVersion: storage.k8s.io/v1&lt;br /&gt;
 kind: StorageClass&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: '''csi-cephfs-sc'''&lt;br /&gt;
 provisioner: cephfs.csi.ceph.com&lt;br /&gt;
 parameters:&lt;br /&gt;
   clusterID: '''33f476b0-2f4c-11ed-896a-00505682bc3e'''&lt;br /&gt;
   fsName: '''cephfs01'''&lt;br /&gt;
   csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret&lt;br /&gt;
   csi.storage.k8s.io/provisioner-secret-namespace: default&lt;br /&gt;
   csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret&lt;br /&gt;
   csi.storage.k8s.io/controller-expand-secret-namespace: default&lt;br /&gt;
   csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret&lt;br /&gt;
   csi.storage.k8s.io/node-stage-secret-namespace: default&lt;br /&gt;
 reclaimPolicy: Delete&lt;br /&gt;
 allowVolumeExpansion: true&lt;br /&gt;
 mountOptions:&lt;br /&gt;
 - debug&lt;br /&gt;
Применяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl create -f storageclass.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем PVC&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano pvc.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ---&lt;br /&gt;
 apiVersion: v1&lt;br /&gt;
 kind: PersistentVolumeClaim&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: '''csi-cephfs-pvc'''&lt;br /&gt;
 spec:&lt;br /&gt;
   accessModes:&lt;br /&gt;
   - ReadWriteMany&lt;br /&gt;
   resources:&lt;br /&gt;
     requests:&lt;br /&gt;
       storage: '''1Gi'''&lt;br /&gt;
   storageClassName: '''csi-cephfs-sc'''&lt;br /&gt;
Применяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl create -f pvc.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pvc&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE&lt;br /&gt;
     csi-cephfs-pvc   Bound    pvc-02520c2a-d5e9-40b6-ae96-5501bcee1c38   1Gi        RWX            csi-cephfs-sc   3m38s&lt;br /&gt;
     ...&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pv&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS    REASON   AGE&lt;br /&gt;
     pvc-02520c2a-d5e9-40b6-ae96-5501bcee1c38   1Gi        RWX            Delete           Bound    default/csi-cephfs-pvc   csi-cephfs-sc            3m33s&lt;br /&gt;
     ...&lt;br /&gt;
Разворачиваем deployment&lt;br /&gt;
&lt;br /&gt;
Деплоим тестовый деплой с подами&amp;lt;blockquote&amp;gt;Монтировать cephfs01 внутри пода будем по пути /code&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano nginx02.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
 apiVersion: apps/v1&lt;br /&gt;
 kind: Deployment&lt;br /&gt;
 metadata:&lt;br /&gt;
   name: nginx02&lt;br /&gt;
 spec:&lt;br /&gt;
   replicas: 2&lt;br /&gt;
   selector:&lt;br /&gt;
     matchLabels:&lt;br /&gt;
       app: nginx02&lt;br /&gt;
   strategy:&lt;br /&gt;
     rollingUpdate:&lt;br /&gt;
       maxSurge: 1&lt;br /&gt;
       maxUnavailable: 1&lt;br /&gt;
     type: RollingUpdate&lt;br /&gt;
   template:&lt;br /&gt;
     metadata:&lt;br /&gt;
       labels:&lt;br /&gt;
         app: nginx02&lt;br /&gt;
     spec:&lt;br /&gt;
       volumes:&lt;br /&gt;
       - name: '''csi-cephfs-pvc'''&lt;br /&gt;
         persistentVolumeClaim:&lt;br /&gt;
           claimName: '''csi-cephfs-pvc'''&lt;br /&gt;
       containers:&lt;br /&gt;
       - image: nginx:1.16&lt;br /&gt;
         name: nginx02&lt;br /&gt;
         volumeMounts:&lt;br /&gt;
         - name: '''csi-cephfs-pvc'''&lt;br /&gt;
           mountPath: '''/code'''&lt;br /&gt;
Применяем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f nginx02.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Зайдем в деплоймент и убедимся что /code смонтирован&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl exec -i -t deployments/nginx02 -- /bin/bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Запишем что-нибудь в /code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo test &amp;gt; /code/123.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь смонтируем на какой-нибудь машине нашу cephfs01 в /mnt/cephfs/ и увидим что по пути&lt;br /&gt;
 /mnt/cephfs/volumes/csi/csi-vol-b2af5ccc-53c5-11ed-9c10-3ef262910d56/5ba704e9-db75-4143-be0d-e621cbfd0064/&lt;br /&gt;
появился файл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /mnt/cephfs/volumes/csi/csi-vol-b2af5ccc-53c5-11ed-9c10-3ef262910d56/5ba704e9-db75-4143-be0d-e621cbfd0064/&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     -rw-r--r-- 1 root root  4 Oct 24 21:08 '''test.txt'''&lt;br /&gt;
     ...&lt;br /&gt;
Удалим и снова создадим деплоймент nginx02&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl delete deployments.apps nginx02&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f nginx02.yaml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Зайдем в контейнер и убедимся что наш файл на месте&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl exec -i -t deployments/nginx02 -- /bin/bash&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;   ls -lh /code/&amp;lt;/code&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         -rw-r--r-- 1 root root  4 Oct 24 18:08 test.txt&lt;br /&gt;
         ...&lt;br /&gt;
Таким образом мы создали постоянное хранилище CephFS для контейнеров&lt;br /&gt;
&lt;br /&gt;
== EMPTYDIR ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
apiVersion: v1&lt;br /&gt;
kind: Pod&lt;br /&gt;
metadata:&lt;br /&gt;
  name: redis&lt;br /&gt;
spec:&lt;br /&gt;
  containers:&lt;br /&gt;
  - name: redis&lt;br /&gt;
    image: redis&lt;br /&gt;
    volumeMounts:&lt;br /&gt;
    - name: redis-storage&lt;br /&gt;
      mountPath: /data/redis&lt;br /&gt;
  volumes:&lt;br /&gt;
  - name: redis-storage&lt;br /&gt;
    emptyDir: {}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Где именно хранятся данные: ===&lt;br /&gt;
&lt;br /&gt;
* Если не указано &amp;lt;code&amp;gt;medium: Memory&amp;lt;/code&amp;gt;, данные хранятся в директории на файловой системе ноды, обычно в &amp;lt;code&amp;gt;/var/lib/kubelet/pods/&amp;lt;pod-uid&amp;gt;/volumes/kubernetes.io~empty-dir/&amp;lt;volume-name&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Если используется &amp;lt;code&amp;gt;medium: Memory&amp;lt;/code&amp;gt;, данные хранятся в tmpfs, который монтируется в память.&lt;br /&gt;
&lt;br /&gt;
[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
[[Категория:Ceph]]&lt;br /&gt;
[[Категория:Samba]]&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1926</id>
		<title>Mail Server. AlmaLinux 8. Postfix + Dovecot + Postfixadmin + Roundcube Webmail</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1926"/>
		<updated>2025-03-16T19:30:24Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Mail]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Opensource Mail Server. Postfix + Dovecot + Postfixadmin + Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
https://www.dmosk.ru/instruktions.php?object=mailserver-centos8&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== DNS Server Global ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Add resource records to the dns server, which is serving your domains (at mikrotik, for example, but it can be any dns-record manager of the registrar, which provides you your new domain)&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - public external IP of the mail server&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''192.168.199.40''''' - local IP of this mail server in you local network&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Root domain MX-record, which point to the mail domain ===&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=yourdomain.ru mx-exchange=mail.yourdomain.ru. mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Domain for administration - mail02.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This should be the hostname of your physical mail server&lt;br /&gt;
&lt;br /&gt;
It's not your domain for mail, just for management&lt;br /&gt;
&lt;br /&gt;
If there will be other mail domains on that server, all emails still will be sended with source-host &amp;quot;mail02.yourdomain.ru&amp;quot; as mail sender&lt;br /&gt;
&lt;br /&gt;
This domain needs to be added to ISP's PTR-record as well&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail02.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mail domain - mail.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This is your first mail domain&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS Server Local ==&lt;br /&gt;
At the local '''DNS server''' (whose IP is registred in the file '''/etc/resolv.conf''' of this mail server) you have to register accordance of '''your domains''' and '''local IP''' in you local network of this server:&lt;br /&gt;
 ...&lt;br /&gt;
 192.168.199.42 mail.yourdomain.ru&lt;br /&gt;
 192.168.199.42 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Mail server ==&lt;br /&gt;
&lt;br /&gt;
=== General configuration ===&lt;br /&gt;
System update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hostname&amp;lt;blockquote&amp;gt;'''''mail02.yourdomain.ru''''' - mail server hostname&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - mail server public external IP&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/hosts&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 185.225.35.200 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
Check&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig A mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utils, firewall, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y chrony wget&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;timedatectl set-timezone Europe/Moscow&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable chronyd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp --add-port=22/tcp --add-port=10050/tcp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL Certs ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to choose whether you will use self-signed certs or letsencrypt certs or purchased certs. We will use it later for Webmail Interface (nginx), and for Mail Desktop Clients (postfix, dovecot)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certificates ====&lt;br /&gt;
''If you're going to purchase SSL certificates from CA:''&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''a few wildcard certs''' with main domain and wildcard subdomains (e.g., '''example.com''' and '''*.example.com''') for '''each mail domain'''.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''the only ONE''' multidomain certificate with '''ALL main domain certs and wildcard certificates of your main domain ('''e.g., '''example.com''' and '''*.example.com''' for each domain''')'''.&lt;br /&gt;
&lt;br /&gt;
==== Self-signed ====&lt;br /&gt;
Generate certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/ssl/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj &amp;quot;/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=mail02.yourdomain.ru&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Letsencrypt ====&lt;br /&gt;
Nginx will create /usr/share/nginx/html directory for letsencrypt challenges&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y certbot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to create cert for each domain. You can put all certs into one file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y &amp;lt;nowiki&amp;gt;http://rpms.remirepo.net/enterprise/remi-release-8.rpm&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf module install -y php:remi-7.4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # For more information on configuration, see:&lt;br /&gt;
 #   * Official English Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 #   * Official Russian Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/ru/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 user nginx;&lt;br /&gt;
 worker_processes auto;&lt;br /&gt;
 error_log /var/log/nginx/error.log;&lt;br /&gt;
 pid /run/nginx.pid;&lt;br /&gt;
 # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.&lt;br /&gt;
 include /usr/share/nginx/modules/*.conf;&lt;br /&gt;
 events {&lt;br /&gt;
    worker_connections 1024;&lt;br /&gt;
 }&lt;br /&gt;
 http {&lt;br /&gt;
    log_format  main  '$remote_addr - $remote_user [$time_local] &amp;quot;$request&amp;quot; '&lt;br /&gt;
                      '$status $body_bytes_sent &amp;quot;$http_referer&amp;quot; '&lt;br /&gt;
                      '&amp;quot;$http_user_agent&amp;quot; &amp;quot;$http_x_forwarded_for&amp;quot;';&lt;br /&gt;
    access_log  /var/log/nginx/access.log  main;&lt;br /&gt;
    sendfile            on;&lt;br /&gt;
    tcp_nopush          on;&lt;br /&gt;
    tcp_nodelay         on;&lt;br /&gt;
    keepalive_timeout   65;&lt;br /&gt;
    types_hash_max_size 2048;&lt;br /&gt;
    include             /etc/nginx/mime.types;&lt;br /&gt;
    default_type        application/octet-stream;&lt;br /&gt;
    # Load modular configuration files from the /etc/nginx/conf.d directory.&lt;br /&gt;
    # See &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/ngx_core_module.html#include&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    # for more information.&lt;br /&gt;
    include /etc/nginx/conf.d/*.conf;&lt;br /&gt;
 }&lt;br /&gt;
Redirect all HTTP-requests to HTTPS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 # Note: This file must be loaded before other virtual host config files,&lt;br /&gt;
 #&lt;br /&gt;
 # HTTP&lt;br /&gt;
 server {&lt;br /&gt;
    # Listen on ipv4&lt;br /&gt;
    listen 80;&lt;br /&gt;
    listen [::]:80;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    # Redirect all insecure http:// requests to https://&lt;br /&gt;
    return 301 &amp;lt;nowiki&amp;gt;https://$host$request_uri&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====HTTPS configuring====&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use self-signed or letsencrypt multidomain certificate (all domains and subdomains in one cert)=====&lt;br /&gt;
&lt;br /&gt;
Create a general config for HTTPS traffic (in order to use it with Roundcube Webmail and Postfixadmin)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2 default_server;&lt;br /&gt;
        listen       [::]:443 ssl http2 default_server;&lt;br /&gt;
        server_name  _;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
         &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate certificates, purchased from official CA or letsencrypt certs (separate cert for every mail domain)=====&lt;br /&gt;
&lt;br /&gt;
Backup /etc/nginx/conf.d/00-default_ssl.conf (or don't create it at all)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/conf.d/00-default_ssl.conf /etc/nginx/conf.d/00-default_ssl.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create separate config for each mail domain (in order to use it with Roundcube Webmail), and put in it the corresponding certificate path.&lt;br /&gt;
&lt;br /&gt;
Also you can create separate config for you management domain (in order to use it with Postfixadmin web-interface) in the same way (in our case mail02.yourdomain.ru). Or you can use any of our mail domains in order to get access to Postfixadmin web-interface. You also can use for that purpose letsencrypt cert or purchased cert.&lt;br /&gt;
&lt;br /&gt;
For example, this first config is for domain mail.don661.ru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/10-mail.don661.ru_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2;&lt;br /&gt;
        listen       [::]:443 ssl http2;&lt;br /&gt;
        server_name  mail.don661.ru;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
 &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
 &lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
        client_max_body_size 35M;&lt;br /&gt;
        client_body_timeout 300s;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable php-fpm --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MariaDB ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y mariadb-server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable mariadb --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysqladmin -u root password&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin/templates_c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DB creating&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -u root -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 # configuring is finished maker&lt;br /&gt;
 $CONF['configured'] = true;&lt;br /&gt;
 &lt;br /&gt;
 # default_language&lt;br /&gt;
 $CONF['default_language'] = 'en';&lt;br /&gt;
 &lt;br /&gt;
 # database_password&lt;br /&gt;
 $CONF['database_password'] = 'PassWord#1';&lt;br /&gt;
 &lt;br /&gt;
 # app checks domain during domains and mailboxes&lt;br /&gt;
 $CONF['emailcheck_resolve_domain']='NO';&lt;br /&gt;
 &lt;br /&gt;
 # amount of records (mailboxes, aliases) per page&lt;br /&gt;
 $CONF['page_size'] = '9999';&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter Setup password, copy generated HASH of the Setup password to config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['setup_password'] = '$2y$10$ZafzUSBaHy47kta5KfPAjF0aQBjH5i';&lt;br /&gt;
 ...&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with Setup password&lt;br /&gt;
&lt;br /&gt;
Create new admin at the footer of the page&lt;br /&gt;
     Администратор admin@yourdomain.ru успешно добавлен!&lt;br /&gt;
You are done with your basic setup. You can now login to PostfixAdmin using the account you just created.&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y postfix postfix-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
User to work with mail services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;groupadd -g 1024 vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;useradd -d /home/mail -g 1024 -u 1024 vmail -m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown vmail:vmail /home/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Main config ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Edit parameters&lt;br /&gt;
 ...&lt;br /&gt;
 # domain, that will be put in email during mail send if it doesn't point in mail's FROM&lt;br /&gt;
 &lt;br /&gt;
 myhostname = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 mydomain = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 myorigin = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 # domains for input emails&lt;br /&gt;
 mydestination = $myhostname, localhost.$mydomain, localhost, localhost.localdomain&lt;br /&gt;
 ...&lt;br /&gt;
 # where we can get local users&lt;br /&gt;
 local_recipient_maps = unix:passwd.byname $alias_maps&lt;br /&gt;
 ...&lt;br /&gt;
 # clients, that will send mail without auth at server. allow local server send emails&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 ...&lt;br /&gt;
 inet_interfaces = all&lt;br /&gt;
 ...&lt;br /&gt;
 inet_protocols = all&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # COMMENT OLD PARAMETERS&lt;br /&gt;
 #smtpd_tls_cert_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtpd_tls_key_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CApath = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CAfile = &amp;lt;...&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed certs&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_cert_file = /etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_key_file = /etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;###&amp;lt;/nowiki&amp;gt; OR&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt certs&lt;br /&gt;
 smtpd_tls_cert_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/cert.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 smtp_tls_CApath = /etc/letsencrypt/live/ALL-MAIL-DOMAINS&lt;br /&gt;
 smtp_tls_CAfile = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/chain.pem&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the primary certificate for the server, to be used for outgoing connections&lt;br /&gt;
 smtpd_tls_chain_files =&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/privkey.pem,&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the map to be used when SNI support is enabled&lt;br /&gt;
 tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
nano /etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; One host per line&lt;br /&gt;
 &lt;br /&gt;
 mail.yourprimarymailserverdomain.com /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 mail.yoursecondarymailserverdomain.com /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; add more domains with keys and certs as needed&lt;br /&gt;
&lt;br /&gt;
postmap -F hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
systemctl restart postfix&lt;br /&gt;
==== Main config again ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   virtual_mailbox_base — storage path for mailboxes&lt;br /&gt;
&lt;br /&gt;
   virtual_alias_maps — format and path of the aliases for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_domains — format and path of the virtual domains&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_maps — format and path of the mailboxes for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_minimum_uid — start UID number for users&lt;br /&gt;
&lt;br /&gt;
   virtual_uid_maps — user id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_gid_maps — group id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_transport — message deliver&lt;br /&gt;
&lt;br /&gt;
   dovecot_destination_recipient_limit — message transfer from Postfix to Dovecot in steps 1 (one) at a time&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_exceptions_networks — networks excepted from encryption&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl settings&lt;br /&gt;
&lt;br /&gt;
   broken_sasl_auth_clients — option for MS Outlook clients&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — auth type&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — Dovecot tmp files. Full or related (default /var/spool/postfix). Full path — /var/spool/postfix/private/auth&lt;br /&gt;
&lt;br /&gt;
   smtp_use_tls — smtp transfer mandatory&lt;br /&gt;
&lt;br /&gt;
   smtpd_use_tls — indicates to clients that TLS support is available&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_auth_only — use TLS only&lt;br /&gt;
&lt;br /&gt;
   smtpd_helo_required — request to start the session with a greeting&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /home/mail&lt;br /&gt;
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf&lt;br /&gt;
 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf&lt;br /&gt;
 '''### If you want to reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files), add the following option):'''&lt;br /&gt;
 '''# ''smtpd_reject_unlisted_sender = yes''&lt;br /&gt;
 '''### (You can try to send an email with non-existing user in field FROM, you will see a rejection in output:&lt;br /&gt;
 '''### ''echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)'''''&lt;br /&gt;
 virtual_minimum_uid = 1024&lt;br /&gt;
 virtual_uid_maps = static:1024&lt;br /&gt;
 virtual_gid_maps = static:1024&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_exceptions_networks = $mynetworks&lt;br /&gt;
 smtpd_sasl_security_options = noanonymous&lt;br /&gt;
 broken_sasl_auth_clients = yes&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/auth&lt;br /&gt;
 smtp_use_tls = yes&lt;br /&gt;
 smtpd_use_tls = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
Aliases config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_alias_maps.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * '''user, password''' — MySQL DB login and password; '''hosts''' — MySQL hostname; '''dbname''' — Mysql DB name; '''query''' — DB request template&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT goto FROM alias WHERE address='%s' AND active = '1'&lt;br /&gt;
Virtual domains config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_domains_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT domain FROM domain WHERE domain='%u'&lt;br /&gt;
Mailboxes config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_mailbox_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* you need to be sure that there's no any uncomment options for '''submission''', '''smtps''' и '''dovecot''' (by default there's no such uncomment options). In this config we configuring Postfix at ports 25, 465 и 587. In master.cf we configuring auxiliary services for Postfix: &lt;br /&gt;
&lt;br /&gt;
   submission   inet  n  -  n  -  -  smtpd:&lt;br /&gt;
&lt;br /&gt;
   submission — service name. In this example '''submission''' is used for MUA at port 587 during message sending.&lt;br /&gt;
&lt;br /&gt;
   inet — type of the service. Possible cases: inet (TCP/IP socket), unix (stream socket), unix-dgram (datagram socket), fifo (named queue channel), pass (stream socket UNIX).&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;n&amp;quot; — whether service private or limited. Possible cases: y or n. For inet service type it should be only n.&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;-&amp;quot; — whether service works with root rights. Possible cases: y, n or -. &amp;quot;-&amp;quot; means that this options doesn't applied to this service.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;n&amp;quot; — whether the service should work in chroot. Possible cases: y или n.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;-&amp;quot; — in what time the service should be awaked if one is inactive.&lt;br /&gt;
&lt;br /&gt;
   третий &amp;quot;-&amp;quot; — the maximum number of child processes of this service.&lt;br /&gt;
&lt;br /&gt;
   smtpd — running command.&lt;br /&gt;
&lt;br /&gt;
   * the following are the arguments for running the command:&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_security_level — TLS security level.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — sasl auth type.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — temp files path.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl options.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_local_domain — smtp-auth users' domain.&lt;br /&gt;
&lt;br /&gt;
   syslog_name — log prefix of the service in the syslog.&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_wrappermode — whether running service in custom mode (for TLS support).&lt;br /&gt;
&lt;br /&gt;
   smtpd_client_restrictions — limit clients' connections. allow only authorized clients.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the file&lt;br /&gt;
 submission   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=may&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_sasl_type=dovecot&lt;br /&gt;
   -o smtpd_sasl_path=/var/spool/postfix/private/auth&lt;br /&gt;
   -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
   -o smtpd_sasl_local_domain=$myhostname&lt;br /&gt;
 smtps   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o syslog_name=postfix/smtps&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
 dovecot   unix  -  n  n  -  -  pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient}&lt;br /&gt;
&lt;br /&gt;
Log configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postconf maillog_file=/var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable postfix --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot dovecot-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mailboxes path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
 mail_home = /home/mail/%d/%u&lt;br /&gt;
 ...&lt;br /&gt;
Listener for the auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* auth service and 2 listeners:&lt;br /&gt;
&lt;br /&gt;
'''/var/spool/postfix/private/auth''' for Dovecot auth ('''/var/spool/postfix/private/auth''' is a '''private/auth''' in Postfix),&lt;br /&gt;
&lt;br /&gt;
'''auth-userdb''' - '''dovecot-lda''' auth socket, '''666''' means any user can use it, '''user and group''' - socket owner&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 service auth {&lt;br /&gt;
   unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0666&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
   }&lt;br /&gt;
   unix_listener auth-userdb {&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * otherwise we will see an error: '''net_connect_unix(/var/run/dovecot/stats-writer) failed permission denied''', because vmail user doesn't has specific rights.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the conf&lt;br /&gt;
 &lt;br /&gt;
 service stats {&lt;br /&gt;
    unix_listener stats-reader {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
    unix_listener stats-writer {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Dovecot auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-auth.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * comment common auth and add sql-auth.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;!include auth-system.conf.ext&lt;br /&gt;
 !include auth-sql.conf.ext&lt;br /&gt;
 ...&lt;br /&gt;
Encryption configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_cert = &amp;lt;/etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_key = &amp;lt;/etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; TLS SNI (Server Name Indication) support (https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Individual cert for each domain&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; It is important to note that having multiple SSL certificates per IP will not be compatible with all clients, especially mobile ones. It is a TLS SNI limitation.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Default cert&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 &lt;br /&gt;
 local_name mail.ladavoronezh.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 local_name mail.don661.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dirs autocreation during the first login a mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 lda_mailbox_autocreate = yes&lt;br /&gt;
 ...&lt;br /&gt;
Connect to DB configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/auth-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * config for getting users' name and password. It's a default config.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 passdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 userdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Connect to mysql configure&amp;lt;blockquote&amp;gt;   * getting data from mysql (mariadb).&lt;br /&gt;
&lt;br /&gt;
'''password_query''' — request for getting password from the '''mailbox''' table;&lt;br /&gt;
&lt;br /&gt;
'''user_query''' — request for getting user's data (home dir, id 1024 (it's a '''vmail''' user id).&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&lt;br /&gt;
 driver = mysql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=PassWord#1&lt;br /&gt;
 default_pass_scheme = MD5-CRYPT&lt;br /&gt;
 password_query = SELECT password FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
Interface for dovecot listening&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 listen = *&lt;br /&gt;
 ...&lt;br /&gt;
 log_path = /var/log/dovecot.log&lt;br /&gt;
 info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
 debug_log_path = /var/log/dovecot-debug.log&lt;br /&gt;
 &lt;br /&gt;
 # debug log (DON'T ENABLE IT BY DEFAULT, ONLY IN DEBUG CASES)&lt;br /&gt;
 ###mail_debug = yes&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable dovecot --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/dovecot*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin. First domain and mailbox creating ===&lt;br /&gt;
Go to the Postfixadmin Web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/postfixadmin/public&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create domain yourdomain.ru&lt;br /&gt;
* Create Mailbox cless@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
=== Roundcube ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube Webmail config defaults.inc.php default parameters:&lt;br /&gt;
&lt;br /&gt;
https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://github.com/roundcube/roundcubemail/releases/download/1.6.1/roundcubemail-1.6.1-complete.tar.gz&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $config['db_dsnw'] = 'mysql://roundcube:PassWord#1@localhost/roundcubemail';&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 $config['enable_installer'] = true;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 // Comment&lt;br /&gt;
 &lt;br /&gt;
 //$config['smtp_host'] = 'localhost:587';&lt;br /&gt;
 //$config['smtp_user'] = '%u';&lt;br /&gt;
 //$config['smtp_pass'] = &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // Add&lt;br /&gt;
 &lt;br /&gt;
 $config['smtp_host'] = 'tls://localhost';&lt;br /&gt;
 $config['smtp_conn_options'] = array(&lt;br /&gt;
   'ssl' =&amp;gt; array(&lt;br /&gt;
   'verify_peer' =&amp;gt; false,&lt;br /&gt;
   'verify_peer_name' =&amp;gt; false,&lt;br /&gt;
 ),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
 # web session timeout (in minutes)&lt;br /&gt;
 $config['session_lifetime'] = 1440;&lt;br /&gt;
 ...&lt;br /&gt;
 // If true all folders will be checked during AUTO-REFRESH for recent messages (Otherwise only standard folders will be checked, like Inbox or SPAM)&lt;br /&gt;
 $config['check_all_folders'] = true;&lt;br /&gt;
 &lt;br /&gt;
 // default roundcube webmail interface language&lt;br /&gt;
 $config['language'] = 'ru_RU';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''$config['create_default_folders'] = true''' (creating dirs by default (if there's lack of ones)):&lt;br /&gt;
&lt;br /&gt;
'''Drafts''' — Messages drafts.&lt;br /&gt;
&lt;br /&gt;
'''Junk''' — SPAM.&lt;br /&gt;
&lt;br /&gt;
'''Sent''' — Sent messages.&lt;br /&gt;
&lt;br /&gt;
'''Trash''' — Trash bin for messages.&lt;br /&gt;
&lt;br /&gt;
* It's necessary to avoid errors, for example during receiving or deleting messages.&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# Add at the end of the file&lt;br /&gt;
&lt;br /&gt;
$config['drafts_mbox'] = 'Drafts';&lt;br /&gt;
$config['junk_mbox'] = 'Junk';&lt;br /&gt;
$config['sent_mbox'] = 'Sent';&lt;br /&gt;
$config['trash_mbox'] = 'Trash';&lt;br /&gt;
$config['create_default_folders'] = true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create roundcubemail DB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply template&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p roundcubemail &amp;lt; /usr/share/nginx/html/webmail/SQL/mysql.initial.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install php php-common php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-zip php-imagick php-gd php-fpm php php-pdo php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP configure&amp;lt;blockquote&amp;gt;* necessary to create message size limit&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 date.timezone = &amp;quot;Europe/Moscow&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 30M&lt;br /&gt;
 ...&lt;br /&gt;
 upload_max_filesize = 30M&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 http {&lt;br /&gt;
    ...&lt;br /&gt;
    client_max_body_size 30M;&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/webmail/installer/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After web installation - disable installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['enable_installer'] = false;&lt;br /&gt;
 ...&lt;br /&gt;
Remove installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\rm -R /usr/share/nginx/html/webmail/installer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quota Dovecot + PostfixAdmin ===&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=quota-dovecot-postfixadmin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * plugin to create quotas.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 mail_plugins = $mail_plugins quota&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-imap.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''mail_plugins'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {&lt;br /&gt;
   mail_plugins = $mail_plugins imap_quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 service dict {&lt;br /&gt;
    unix_listener dict {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-quota.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''quota = dict:User quota::proxy::quota'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 plugin {&lt;br /&gt;
   quota = dict:User quota::proxy::quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 dict {&lt;br /&gt;
   quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Create config file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-dict-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Mysql connection&lt;br /&gt;
&lt;br /&gt;
'''host''' — mysql server host;&lt;br /&gt;
&lt;br /&gt;
'''dbname''' — db containing postfix users;&lt;br /&gt;
&lt;br /&gt;
'''user''' — db user;&lt;br /&gt;
&lt;br /&gt;
'''password''' — db password.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 connect = '''host'''=localhost '''dbname'''=postfix '''user'''=postfix '''password'''=PassWord#1&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/storage&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/messages&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *if you have several '''user_query''' in your config, create query for the last one.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find &amp;quot;user_query&amp;quot; and put into this line: '''CONCAT('*:bytes=', quota) AS quota_rule'''&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid, '''''CONCAT('*:bytes=', quota) AS quota_rule''''' FROM mailbox WHERE username = '%u'&lt;br /&gt;
 ...&lt;br /&gt;
Check dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveconf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout-Login into Roundcube webmail.&lt;br /&gt;
&lt;br /&gt;
At the foot of the page there'll be a quota appear.&lt;br /&gt;
&lt;br /&gt;
=== Clamav + Amavisd ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavisd-new clamd perl-Digest-SHA1 perl-IO-stringy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rsyslog is necessary to write SPAM and VIRUS log to /var/log/maillog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y rsyslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now rsyslog.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $mydomain = 'yourdomain.ru';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 $log_level = 0;              # verbosity 0..5, -d&lt;br /&gt;
 $log_recip_templ = undef;    # disable by-recipient level-0 log entries&lt;br /&gt;
 $do_syslog = 1;              # log via syslogd (preferred)&lt;br /&gt;
 $syslog_facility = 'mail';   # Syslog facility as a string&lt;br /&gt;
            # e.g.: mail, daemon, user, local0, ... local7&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $myhostname = 'mail02.yourdomain.ru';&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add before line &amp;quot;'''''1;  # insure a defined return value'''''&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $allowed_header_tests{'multiple'} = 0;&lt;br /&gt;
 $allowed_header_tests{'missing'} = 0;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/clamd.d/scan.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Uncomment&lt;br /&gt;
 TCPSocket 3310&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable clamd@scan --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable amavisd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postfix settings&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''content_filter''' - point to application, which ьуфте to scan messages;&lt;br /&gt;
&lt;br /&gt;
'''receive_override_options''' - allow you to see original email addresses with viruses.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10024&lt;br /&gt;
 receive_override_options = no_address_mappings&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10025 (сервис без имени, он просто будет слушать на порту 10025 — это порт по умолчанию, на который отправляет сообщение amavis после выполнения проверки). Также, мы используем следующие опции:&lt;br /&gt;
&lt;br /&gt;
   smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.&lt;br /&gt;
&lt;br /&gt;
   smtp_enforce_tls — требовать ли TLS.&lt;br /&gt;
&lt;br /&gt;
   content_filter — приложение для сканирования. В данном примере сканирование отключено.&lt;br /&gt;
&lt;br /&gt;
   receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.&lt;br /&gt;
&lt;br /&gt;
   пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.&lt;br /&gt;
&lt;br /&gt;
   smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.&lt;br /&gt;
&lt;br /&gt;
   mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.&lt;br /&gt;
&lt;br /&gt;
   smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 scan   unix  -  -  n  -  16  smtp&lt;br /&gt;
   -o smtp_send_xforward_command=yes&lt;br /&gt;
   -o smtp_enforce_tls=no&lt;br /&gt;
 127.0.0.1:10025   inet  n  -  n  -  16  smtpd&lt;br /&gt;
   -o content_filter=&lt;br /&gt;
   -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
   -o smtpd_helo_restrictions=&lt;br /&gt;
   -o smtpd_client_restrictions=&lt;br /&gt;
   -o smtpd_sender_restrictions=&lt;br /&gt;
   -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
   # '''OR, if you want to restrict sending emails by users with inexistened local domains, etc.:'''&lt;br /&gt;
   # '''(You can see logs of PASSED o DROPPED emails in ''/var/log/maillog'' after sending them''')&lt;br /&gt;
   # '''-o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject'''&lt;br /&gt;
   -o mynetworks_style=host&lt;br /&gt;
   -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clamd update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y clamav-update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/freshclam.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Choose one of the update mirrors&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://clamav.jinr.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://packages.microsoft.com/clamav/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 DatabaseMirror pivotal-clamav-mirror.s3.amazonaws.com&lt;br /&gt;
 ...&lt;br /&gt;
Then remove the freshclam.dat file and restart the service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rm -f /var/lib/clamav/freshclam.dat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart clamav-freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Antispam DB update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sa-update --nogpg --verbose&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cron&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 15 3 * * * /bin/freshclam&lt;br /&gt;
 30 3 * * * /bin/sa-update&lt;br /&gt;
Antivirus checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&lt;br /&gt;
The email will never come, and you will see the following in the logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17688]: (17688-04) Blocked INFECTED (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... relay=127.0.0.1[127.0.0.1]:10024, delay=0.25, delays=0.19/0/0/0.06, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17688-04 - INFECTED: Eicar-Signature)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Redirect SPAM to user's SPAM-directory using Amavis service ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis dovecot-pigeonhole dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * закомментированная строка указывала, что файл с настройками находится в домашней директории каждого пользователя. Мы же будем делать централизованный конфиг в файле /etc/dovecot/sieve/default.sieve.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;sieve = file:~/sieve;active=~/.dovecot.sieve&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 sieve = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавили плагин sieve. Также необходимо со строки снять комментарий, если он был.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lda {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-lmtp.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * также мы добавили плагин sieve + необходимо со строки снять комментарий, если он есть.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lmtp {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/sieve/default.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы ищем в заголовках X-Spam-Flag и отправляем такие письма в папку Junk.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R vmail:vmail /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по умолчанию стоит значение D_DISCARD, что означает, что сообщения будут отклонятся. Нам же нужно D_PASS — пропускать.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $final_spam_destiny = D_PASS;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SPAM filter checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
The email will be appear inthe SPAM-directory, any you will see in the logs:&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17689]: (17689-04) Blocked SPAM {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... status=sent (250 2.7.0 Ok, discarded, id=17689-04 - spam)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Logrotate of mail logs ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/logrotate.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# see &amp;quot;man logrotate&amp;quot; for details&lt;br /&gt;
# rotate log files weekly&lt;br /&gt;
weekly&lt;br /&gt;
&lt;br /&gt;
# keep 4 weeks worth of backlogs&lt;br /&gt;
rotate 4&lt;br /&gt;
&lt;br /&gt;
# create new (empty) log files after rotating old ones&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
# use date as a suffix of the rotated file&lt;br /&gt;
dateext&lt;br /&gt;
&lt;br /&gt;
# uncomment this if you want your log files compressed&lt;br /&gt;
compress&lt;br /&gt;
&lt;br /&gt;
# RPM packages drop log rotation information into this directory&lt;br /&gt;
include /etc/logrotate.d&lt;br /&gt;
&lt;br /&gt;
# system-specific logs may be also be configured here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;nano /etc/logrotate.d/mail&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/var/log/dovecot-debug.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot-info.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/postfix.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/maillog {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Check a cron daily task. It should already exist&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/cron.daily/logrotate&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/logrotate /etc/logrotate.conf&lt;br /&gt;
EXITVALUE=$?&lt;br /&gt;
if [ $EXITVALUE != 0 ]; then&lt;br /&gt;
    /usr/bin/logger -t logrotate &amp;quot;ALERT exited abnormally with [$EXITVALUE]&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
exit $EXITVALUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Wait for a daily task to complete&lt;br /&gt;
&lt;br /&gt;
Or you can run the logrotate manually:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;logrotate -f /etc/logrotate.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Improving email deliverability (VERY IMPORTANT!) =&lt;br /&gt;
https://www.linuxbabe.com/mail-server/centos-7-iredmail-email-server&lt;br /&gt;
&lt;br /&gt;
To prevent your emails from being flagged as spam, you should set PTR, SPF, DKIM and DMARC records.&lt;br /&gt;
&lt;br /&gt;
=== PTR записи на DNS сервере ===&lt;br /&gt;
&lt;br /&gt;
==== Описание ====&lt;br /&gt;
Запись PTR прописывается _НЕ_ в ресурсных записях днс-сервера, к которому привязан ваш почтовый домен, это делает именно регистратор ip-адреса (провайдер или хостер, предоставляющий внешний ip-адрес)! Если провайдер ростелеком, пишем на электронку support@tmb.ru с просьбой зарегистрировать ptr-запись, штатная техподдержка отказывается предоставлять такую услугу&lt;br /&gt;
&lt;br /&gt;
Если у вас есть свой почтовый сервер, то необходимо, чтобы ваш провайдер (а точнее тот, кто выдал вам статические ip-адреса. если ваш внешний IP предоставил вам хостер, на котором у вас крутится VPS/VDS, то обращаемся в техподдержку хостера) зарегистрировал на своем DNS-сервере PTR записи для вашего почтового сервера (MX-записи). Иначе, подавляющая часть почтовых серверов интернета откажется принимать почту от вашего почтового сервера.&lt;br /&gt;
&lt;br /&gt;
Так же, многие почтовые сервера отвергают письма, если при проверке адреса отправителя в строке им выдается &amp;quot;dynamicip&amp;quot; или &amp;quot;dsl&amp;quot; или подобные слова означающие, что ваш адрес не статический или не совпадает с именем вашего домена.&lt;br /&gt;
&lt;br /&gt;
Если в ответе сервера на ваше отправленное письмо вы видите что-то типа:&lt;br /&gt;
&lt;br /&gt;
  mxs.mail.ru: 550 Sorry, we do not accept mail from hosts with dynamic IP or generic DNS PTR-records. Please get a custom reverse DNS name from your ISP for your host 215.54.54.54 or contact abuse@corp.mail.ru in case of error&lt;br /&gt;
&lt;br /&gt;
это значит, что вам необходимо корректно зарегистрировать PTR запись на DNS-сервере для вашего доменного имени.&lt;br /&gt;
&lt;br /&gt;
Для этого необходимо послать запрос тому, кто выдал вам статические ip-адреса (обычно, это ваш провайдер) с просьбой зарегистрировать PTR запись для вашего домена.&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть одна для одного IP (не нужно создавать две записи для основного домена (mydomain.ru) и почтового домена (mail.mydomain.ru) если оба они привязаны А-записью к одному IP)&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть создана именно для MX записи. То есть, если адреса домена и почтового обменника не совпадают, то PTR создаем именно для MX записи.&lt;br /&gt;
&lt;br /&gt;
Например, если домен mydomain.ru находится по адресу 22.11.33.44, а почтовый обменник (MX запись) создана для хоста mail.mydomain.ru, расположенного по адресу 11.22.33.44, то и PTR запись нужно создавать для mail.mydomain.ru:&lt;br /&gt;
       44.33.22.11.in-addr.arpa  mail.mydomain.ru&lt;br /&gt;
  Естественно, можно &amp;quot;до кучи&amp;quot; создать обратную запись и для самого домена mydomain.ru. Она так же не помешает:&lt;br /&gt;
       44.33.11.22.in-addr.arpa  mydomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Резюмируя, необходимо сделать следующее: ====&lt;br /&gt;
1. Необходимо прописать ресурсную запись MX (MX 10 mail.yourdomain.ru.) для основного домена &amp;quot;yourdomain.ru&amp;quot;, указав что почтовым доменом MX-сервера является &amp;quot;mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делаем мы.&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего yourdomain.ru - 1.2.3.4   &lt;br /&gt;
   A yourdomain.ru 1.2.3.4&lt;br /&gt;
   MX 10 mail.yourdomain.ru.&lt;br /&gt;
2. Создать PTR-запись на DNS сервере регистратора&lt;br /&gt;
&lt;br /&gt;
IP домена &amp;quot;mail.yourdomain.ru&amp;quot; необязательно должен совпадать с IP &amp;quot;yourdomain.ru&amp;quot;, но PTR-запись должна быть создана регистратором IP-адреса (5.6.7.8) домена &amp;quot;mail.yourdomain.ru&amp;quot;. Если у нас несколько почтовых доменов на одном почтовом сервере и все они выходят через единственный внешний IP, то PTR соответствие необходимо прописать для домена, которым именуется (hostname) сам физический почтовый сервер.&lt;br /&gt;
&lt;br /&gt;
Например, сама физическая машина именуется mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
(&lt;br /&gt;
&lt;br /&gt;
Также для этого необходимо прописать &amp;quot;mail.yourdomain.ru&amp;quot; в следующих местах:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname mail.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cоответствие внешнего IP, для которого создаем PTR-запись, и домена mail.yourdomain.ru прописываем в /etc/hosts)&lt;br /&gt;
 ...&lt;br /&gt;
 45.67.59.224 mail.yourdomain.ru&lt;br /&gt;
Изменить настройки postfix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 myhostname = mail.yourdomain.ru&lt;br /&gt;
 myorigin = mail.yourdomain.ru&lt;br /&gt;
 mydomain = mail.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
mail.yourdomain.ru не обязан вообще быть почтовым доменом, но он будет в поле &amp;quot;helo: mail.yourdomain.ru&amp;quot; при отправке письма с любого другого почтового домена, работающего на нашем почтовом сервере. поэтому создаем ptr-запись именно для mail.yourdomain.ru - &amp;quot;8.7.6.5.in-addr.arpa mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делает регистратор внешнего IP&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего mail.yourdomain.ru 5.6.7.8&lt;br /&gt;
   8.7.6.5.in-addr.arpa mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Проверки ====&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host 5.6.7.8&amp;lt;/code&amp;gt;&lt;br /&gt;
       ...&lt;br /&gt;
       8.7.6.5.in-addr.arpa domain name pointer mail.yourdomain.ru.&lt;br /&gt;
       ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
Например, для домена mydomain.ru с адресом 215.54.54.54, необходимо зарегистрировать следующую запись:&lt;br /&gt;
       54.54.54.215.in-addr.arpa name=mydomain.ru&lt;br /&gt;
А если почтовый сервер сидит на отдельном адресе, например, mail.mydomain.ru имеет адрес 215.54.54.55, то необходимо зарегистрировать еще одну PTR запись:&lt;br /&gt;
       55.54.54.215.in-addr.arpa name=mail.mydomain.ru&lt;br /&gt;
Проверить наличие PTR записи на сервере DNS можно с помощью интерфейса команды NSLOOKUP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nslookup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь подключаемся к DNS-серверу провайдера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;server 215.54.54.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Устанавливаем тип ресурсной записи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set type=PTR&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Делаем запрос на интересующий нас адрес:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;215.54.54.54&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ответ мы должны получить имя своего домена mydomain.ru&lt;br /&gt;
&lt;br /&gt;
=== SPF ===&lt;br /&gt;
SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain. In your DNS management interface, create a new TXT record like below.&lt;br /&gt;
&lt;br /&gt;
Add TXT-record to your main domain (for example &amp;quot;yourdomain.ru&amp;quot;, _NOT_ subdomain &amp;quot;mail.yourdomain.ru&amp;quot;!)&lt;br /&gt;
 A yourdomain.ru 45.67.59.224&lt;br /&gt;
 MX 10 mail.yourdomain.ru.&lt;br /&gt;
 TXT v=spf1 mx ~all&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   yourdomain.ru.              10      IN      TXT     &amp;quot;v=spf1 mx ~all&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DKIM ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Add first mail domain ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to add second and following as well as the first&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/lib/dkim&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate PEM for our domain&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; domain.ru - the first domain, for wich we generated dkim&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;amavisd genrsa /var/lib/dkim/dmosk.ru.pem 1024&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown amavis:amavis /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 0400 /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;$inet_socket_port = 10024;&lt;br /&gt;
 &lt;br /&gt;
 # Add&lt;br /&gt;
 &lt;br /&gt;
 $inet_socket_port = [10024,10026];&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find this string (its value must be &amp;quot;1&amp;quot;)&lt;br /&gt;
 $enable_dkim_verification = 1;  # enable DKIM signatures verification&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; After the string above add following&lt;br /&gt;
 &lt;br /&gt;
 dkim_key('yourdomain.ru', &amp;quot;dkim&amp;quot;, &amp;quot;/var/lib/dkim/yourdomain.ru.pem&amp;quot;);&lt;br /&gt;
 @dkim_signature_options_bysender_maps = ( {&lt;br /&gt;
   &amp;quot;yourdomain.ru&amp;quot; =&amp;gt; { d =&amp;gt; &amp;quot;yourdomain.ru&amp;quot;, a =&amp;gt; 'rsa-sha256', ttl =&amp;gt; 10*24*3600 },&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; FIND THIS STRING. ITS VALUE MUST BE &amp;quot;1&amp;quot;&lt;br /&gt;
 $enable_dkim_signing = 1;    # load DKIM signing code, keys defined by dkim_key&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generate record for DNS server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf showkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   dkim._domainkey.yourdomain.ru.      3600 TXT (&lt;br /&gt;
   &amp;quot;v=DKIM1; p=&amp;quot;&lt;br /&gt;
   &amp;quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz&amp;quot;&lt;br /&gt;
   &amp;quot;3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUg&amp;quot;&lt;br /&gt;
   &amp;quot;jOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0J&amp;quot;&lt;br /&gt;
   &amp;quot;xfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9O&amp;quot;&lt;br /&gt;
   &amp;quot;YO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61N&amp;quot;&lt;br /&gt;
   &amp;quot;rJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVh&amp;quot;&lt;br /&gt;
   &amp;quot;kwIDAQAB&amp;quot;)&lt;br /&gt;
   ...&lt;br /&gt;
Copy it from &amp;quot;&amp;quot;v=DKIM1...&amp;quot; to &amp;quot;...kwIDAQAB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove all &amp;quot;&amp;quot; and line breaks&lt;br /&gt;
&lt;br /&gt;
You'll get something like this (in one line):&lt;br /&gt;
 v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Create subdomain &amp;quot;dkim._domainkey&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;dkim._domainkey&amp;quot; subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 TXT v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test at mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf testkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   TESTING#1 yourdomain.ru: dkim._domainkey.yourdomain.ru =&amp;gt; pass&lt;br /&gt;
   ...&lt;br /&gt;
Test on arbitrary server in internet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig dkim._domainkey.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   dkim._domainkey.yourdomain.ru. 10   IN      TXT     &amp;quot;v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjz&amp;quot; &amp;quot;zr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DMARC ===&lt;br /&gt;
DMARC stands for Domain-based Message Authentication, Reporting and Conformance. DMARC can help receiving email servers to identify legitimate emails and prevent your domain name from being used by email spoofing.&lt;br /&gt;
&lt;br /&gt;
To create a DMARC record, go to your DNS manager and add a TXT record. In the name field, enter _dmarc. In the value field, enter the following. (You should create the dmarc@your-domain.com email address.)&lt;br /&gt;
&lt;br /&gt;
Create subdomain &amp;quot;_dmarc&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;_dmarc&amp;quot; (_dmarc.yourdomain.ru) subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 A 45.67.59.224&lt;br /&gt;
 TXT v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig _dmarc.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
  �;; ANSWER SECTION:&lt;br /&gt;
   _dmarc.yourdomain.ru.       10      IN      TXT     &amp;quot;v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
General deliverability test&lt;br /&gt;
&lt;br /&gt;
Go to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://www.mail-tester.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send email from your mail account of your new mail server to randomly generated service's mail address (test-avlwah6p3@srv1.mail-tester.com, for example)&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Затем проверьте оценку&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wait for tests passed&lt;br /&gt;
&lt;br /&gt;
If your score higher than 8, congratulations! &lt;br /&gt;
&lt;br /&gt;
= Add additional mail domain =&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
Root domain and MX-record, which point to the for mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=cless.pro mx-exchange=mail.cless.pro mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.cless.pro address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL certs ===&lt;br /&gt;
&lt;br /&gt;
==== Lentencrypt ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail.cless.pro,mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certs ====&lt;br /&gt;
Add additional cert configs for a new domain for '''Nginx''', '''Postfix''' and '''Dovecot'''.&lt;br /&gt;
&lt;br /&gt;
=== Improving email deliverability ===&lt;br /&gt;
Check the '''Improving email deliverability''' section of this manual and do corresponding actions.&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin web panel ===&lt;br /&gt;
&lt;br /&gt;
* Create domain cless.pro&lt;br /&gt;
* Create mailbox cless@cless.pro&lt;br /&gt;
&lt;br /&gt;
=== Roundcube webmail ===&lt;br /&gt;
Login to Roundcube webmail&lt;br /&gt;
&lt;br /&gt;
Send/Receive email&lt;br /&gt;
&lt;br /&gt;
= Autodiscover Mail Server settings for Mail Clients =&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=autodiscover-mail&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
It provides mail clients Mail Server connection info during configuring Mail Client mailbox&lt;br /&gt;
&lt;br /&gt;
=== Thinderbird ===&lt;br /&gt;
Механизм автонастройки от Mozilla похож на Microsoft. Необходимые настройки должны отдаваться веб-сервером в виде XML-документа. Однако запрос не https, а http; и не POST, а GET. Также обращение идет сначала в формате '''server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain''', и если ответ не будет получен — '''autoconfig.server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain'''.&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;Create А-record (or CNAME) for root domain (example.com):&amp;lt;blockquote&amp;gt;''* где  '''111.111.111.111''' — IP-address of web server, with XML.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 autoconfig    IN      A       111.111.111.111&lt;br /&gt;
&lt;br /&gt;
==== Nginx config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/910-autodiscover_example.ru.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
# HTTP&lt;br /&gt;
server {&lt;br /&gt;
    listen 80;&lt;br /&gt;
    server_name autoconfig.example.com;&lt;br /&gt;
    root /usr/share/nginx/html/autodiscover/example.com;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autodiscover config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /usr/share/nginx/html/autodiscover/example.ru/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/autodiscover/example.ru/mail/config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;emailProvider id=&amp;quot;example.com&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;domain&amp;gt;example.com&amp;lt;/domain&amp;gt;&lt;br /&gt;
                &amp;lt;displayName&amp;gt;Mail example.com&amp;lt;/displayName&amp;gt;&lt;br /&gt;
                &amp;lt;displayShortName&amp;gt;example.com&amp;lt;/displayShortName&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;143&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;pop&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;pop.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;995&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;SSL&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;587&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/outgoingServer&amp;gt;&lt;br /&gt;
        &amp;lt;/emailProvider&amp;gt;&lt;br /&gt;
&amp;lt;/clientConfig&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simpliest method according to the RFC standard (I'm not sure that it works) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;It works in unstable way. The mail client usually managed to get mail server info, but not everything. Mail client gets '''hosts''' (for example, imap.yourdomain.ru), but not the '''ports'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
You need to add ''subdomains'' for your ''main domain'' '''yourdomain.ru''' and create '''SRV''' records&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
 _&amp;lt;service name&amp;gt;._&amp;lt;protocol&amp;gt; &amp;lt;priority&amp;gt; &amp;lt;weight&amp;gt; &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;&lt;br /&gt;
Examples&lt;br /&gt;
 _smtp._tcp              IN SRV  10 0 25  smtp.yourdomain.ru.&lt;br /&gt;
 _pop3._tcp              IN SRV  20 0 110 pop.yourdomain.ru.&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _smtps._tcp             IN SRV   0 0 465 smtp.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
 _imaps._tcp             IN SRV   0 0 993 imap.yourdomain.ru.&lt;br /&gt;
 _pop3s._tcp             IN SRV  10 0 995 pop.yourdomain.ru.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
To give your mail clients info about '''imap''' and '''smtp''' settings of your mail server:&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
&lt;br /&gt;
= Full-text search =&lt;br /&gt;
&lt;br /&gt;
== Fts-xapian ('''It works good!''') ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://github.com/grosjo/fts-xapian]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/#community-developed-plugins]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/settings/plugin/fts-plugin/]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin]&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
Dovecot has some problems with email searching if there's a huge amount of emails in the mailbox. It can perodically throw an error &amp;quot;Server error&amp;quot; during the search.&lt;br /&gt;
&lt;br /&gt;
To avoid such problems we can use Full-text search.&lt;br /&gt;
&lt;br /&gt;
=== Build plugin ===&lt;br /&gt;
&lt;br /&gt;
==== Variant 1. Build plugin at the same machine ====&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
==== Variant 2. Build plugin at the another machine with the same arch and apps versions, and copy compiled plugin to the mail server ====&lt;br /&gt;
&lt;br /&gt;
===== Another machine for building =====&lt;br /&gt;
Build plugin at the another machine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy plugin to the mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rsync -avPh /usr/lib64/dovecot/lib21_fts_xapian_plugin.* root@&amp;lt;mail-server-IP&amp;gt;:/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== Configure plugin at the mail server ===&lt;br /&gt;
Check the installed plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /usr/lib64/dovecot/lib21_fts_xapian_plugin.*&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     -rw-r--r-- 1 root root 2.9M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.a&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.1K Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.la&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.2M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.so&lt;br /&gt;
     ...&lt;br /&gt;
Add plugin to the common conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
mail_plugins = $mail_plugins &amp;lt;...&amp;gt; fts fts_xapian&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Add plugin config&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/95-fts.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;partial=2 - the minimum length of the search string&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
plugin {&lt;br /&gt;
    fts = xapian&lt;br /&gt;
    fts_xapian = partial=2 full=20 attachments=0 verbose=0&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex = yes&lt;br /&gt;
    fts_enforced = yes&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex_exclude = \Trash&lt;br /&gt;
&lt;br /&gt;
    # Index attachements&lt;br /&gt;
    fts_decoder = decode2text&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service indexer-worker {&lt;br /&gt;
    # Increase vsz_limit to 2GB or above.&lt;br /&gt;
    # Or 0 if you have rather large memory usable on your server, which is preferred for performance)&lt;br /&gt;
    vsz_limit = 2G&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service decode2text {&lt;br /&gt;
    executable = script /usr/libexec/dovecot/decode2text.sh&lt;br /&gt;
    user = dovecot&lt;br /&gt;
    unix_listener decode2text {&lt;br /&gt;
        mode = 0666&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot and check the service status. There shouldn't be errors or warnings in the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's necessary to index all the mailboxes if you have already had productive and filled mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm index -u $i \*; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm index -u user@domain.ru \*&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
       '''fts optimize'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts optimize [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
&lt;br /&gt;
       '''fts rescan'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts rescan [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Scan what mails exist in the full text search index and compare those to what actually exist in mailboxes.  This removes mails from the index that have already been expunged and makes sure&lt;br /&gt;
&lt;br /&gt;
           that  the  next  doveadm index will index all the missing mails (if any). Note that currently most FTS backends do not implement this properly, but instead they delete all the FTS indexes.&lt;br /&gt;
&lt;br /&gt;
           This may change in the future versions.&amp;lt;/blockquote&amp;gt;Place the task to optimize your xapian indexes into the crontab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
 0 4 * * * for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts optimize -u $i; done&lt;br /&gt;
 ...&lt;br /&gt;
Optionally&amp;lt;blockquote&amp;gt;I'm not sure this is really necessary&lt;br /&gt;
&lt;br /&gt;
It takes a lot of time and during this process the search doesn't work&lt;br /&gt;
&lt;br /&gt;
Also, after the rescan, the directories &amp;quot;/home/mail/&amp;lt;domain&amp;gt;/&amp;lt;user&amp;gt;/xapian-indexes/db_*&amp;quot; will be deleted, and they will be created only after a user will click on the directories in the web-interface. It takes also a lot of time&lt;br /&gt;
&lt;br /&gt;
You can rescan indexes of your mailboxes&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts rescan -u $i; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm fts rescan -u user@domain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the console&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y telnet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;telnet localhost imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a login user@don661.ru PassWord#1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a select Inbox&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a SEARCH text &amp;quot;test&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the '''Roundcube Webmail'''&amp;lt;blockquote&amp;gt;In '''Roundcube Webmail''' for the searching of text in the message body it's necessary to click on the arrow right to the search field and to check &amp;quot;'''Message body'''&amp;quot; as a search source!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SOLR ('''I didn't test it!''') ==&lt;br /&gt;
https://doc.dovecot.org/configuration_manual/fts/solr/&lt;br /&gt;
&lt;br /&gt;
== Fts-elastic ('''I didn't test it!''') ==&lt;br /&gt;
https://github.com/filiphanes/fts-elastic&lt;br /&gt;
&lt;br /&gt;
= Postfix limits (I didn't test it!) =&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=postfix-limits#mailbox-size&lt;br /&gt;
&lt;br /&gt;
= Desktop mail clients =&lt;br /&gt;
&lt;br /&gt;
=== Thunderbird ===&lt;br /&gt;
'''IMAP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 143&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
'''SMTP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 587&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
= Hints =&lt;br /&gt;
&lt;br /&gt;
== Mail queue check ==&lt;br /&gt;
&amp;lt;code&amp;gt;mailq&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show connected users ==&lt;br /&gt;
Users IMAP (via mail clients)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm who&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users WEB Roundcube&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;netstat -an | grep :443 | grep -v TIME_WAIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restrict sending emails by local users with non-existing local domains in the field ''FROM'' ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 -o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject&lt;br /&gt;
 ...&lt;br /&gt;
You can see logs of PASSED o DROPPED emails in '''/var/log/maillog''' after sending them.&lt;br /&gt;
&lt;br /&gt;
== Reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files) ==&lt;br /&gt;
https://serverfault.com/questions/694511/postfix-how-to-reject-sender-addresses-that-dont-exist-only-for-local-domains&lt;br /&gt;
&lt;br /&gt;
Add the following option to '''/etc/postfix/main.cf''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 smtpd_reject_unlisted_sender = yes&lt;br /&gt;
 ...&lt;br /&gt;
You can try to send an email with non-existing user in field FROM, and you will see a rejection in output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)&amp;lt;/code&amp;gt;&lt;br /&gt;
== Message size limit (message size itself + attached file size) ==&lt;br /&gt;
You have to set limits in the each following entity.&lt;br /&gt;
&lt;br /&gt;
In this example we make limit at about ~30MB for attachment&lt;br /&gt;
&lt;br /&gt;
==== Postfix limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 message_size_limit = 46080000 # ~30MB (10240000 - ~10MB)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Roundcube limit ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube preserves some percentage of the max message size (search 1.33 on this page, so if you set the max to 100M, it tells you only 75MB is allowed (100 / 1.33). This is better because email messsage will be encoded before sending to MTA and the encoded attachment is larger than the original file.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['max_message_size'] = '40M'; # max summ message size (not file)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
==== Nginx limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 server {&lt;br /&gt;
     ...&lt;br /&gt;
     client_max_body_size 35M; # max size of a message&lt;br /&gt;
     client_body_timeout 300s; # timeout while upload attachment, otherwise upload may be canceled by timeout in case of a low upload speed, for example&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PHP limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 35M;&lt;br /&gt;
 upload_max_filesize = 35M;&lt;br /&gt;
 ...&lt;br /&gt;
reboot &lt;br /&gt;
&lt;br /&gt;
== Amount of attached files in an email ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; Maximum number of files that can be uploaded via a single request&lt;br /&gt;
 max_file_uploads = 50&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx.service php-fpm.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating users via CLI ==&lt;br /&gt;
&lt;br /&gt;
=== A single mailbox creation ===&lt;br /&gt;
Postfixadmin-cli installation&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;if you have already had installed postfixadmin, you don't have to do the following&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Help&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comment password validation limits (e.g. &amp;quot;# must contain at least 2 digits&amp;quot; or something you needed) in the array 'password_validation' of the postfix config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['password_validation'] = array(&lt;br /&gt;
 ...&lt;br /&gt;
 #    '/([0-9].*){2}/'        =&amp;gt; 'password_no_digits 2',      # must contain at least 2 digits&lt;br /&gt;
 ...&lt;br /&gt;
Create user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-cli mailbox add prod@domain123.ru --password &amp;quot;AlefStudioS*100&amp;quot; --password2 &amp;quot;AlefStudioS*100&amp;quot; --name &amp;quot;Компания AlefStudio&amp;quot; --quota &amp;quot;4096&amp;quot; --active --welcome-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mass mailboxes creation ===&lt;br /&gt;
Mailboxes list file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./mailboxes.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 john@domain.ru|pass1|John Smith&lt;br /&gt;
 ann@domain.ru|pass2|Анна Паста Бродерик-Иванова&lt;br /&gt;
Milbox creation script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Mass postfixadmin mailboxes creation by @ClessAlvein&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# VARS&lt;br /&gt;
&lt;br /&gt;
mailboxesListFile=&amp;quot;./USERS_lada-tambovavtocity.ru.txt&amp;quot;&lt;br /&gt;
mailboxQuota=&amp;quot;2048&amp;quot;&lt;br /&gt;
pfCli=&amp;quot;/usr/share/nginx/html/postfixadmin/scripts/postfixadmin-cli&amp;quot;&lt;br /&gt;
dateTimeCurrent=`date +%Y-%m-%d_%H-%M-%S`&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# SCRIPT START&lt;br /&gt;
&lt;br /&gt;
# declare array with mailbox data in the each line&lt;br /&gt;
declare -A arrayMailboxes;&lt;br /&gt;
&lt;br /&gt;
# getting each line from the file with each user's data&lt;br /&gt;
while IFS= read -r line || [[ &amp;quot;$line&amp;quot; ]];&lt;br /&gt;
do&lt;br /&gt;
  # getting user, pass, name from the line and put it to the assoc array key=value&lt;br /&gt;
  while IFS=&amp;quot;|&amp;quot; read &amp;quot;mailboxUserFromFile&amp;quot; &amp;quot;mailboxPassFromFile&amp;quot; &amp;quot;mailboxNameFromFile&amp;quot;;&lt;br /&gt;
  do&lt;br /&gt;
    # makeup&lt;br /&gt;
    echo &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # debug&lt;br /&gt;
    #echo &amp;quot;${mailboxUser}, ${mailboxPass}, ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # declare assoc array with each key as a bit mailbox's data&lt;br /&gt;
    declare -A arrayMailbox;&lt;br /&gt;
&lt;br /&gt;
    # each key is a bit of the mailbox's data&lt;br /&gt;
    arrayMailbox[arrayMailboxUser]=${mailboxUserFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxPass]=${mailboxPassFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxName]=${mailboxNameFromFile};&lt;br /&gt;
&lt;br /&gt;
    # for each bit of mailbox's data create var (user,pass,name)&lt;br /&gt;
    for key in &amp;quot;${!arrayMailbox[@]}&amp;quot;;&lt;br /&gt;
    do&lt;br /&gt;
      case $key in&lt;br /&gt;
      arrayMailboxUser)&lt;br /&gt;
        mailboxUser=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxPass)&lt;br /&gt;
        mailboxPass=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxName)&lt;br /&gt;
        mailboxName=${arrayMailbox[${key}]};;&lt;br /&gt;
      esac&lt;br /&gt;
    done&lt;br /&gt;
  done &amp;lt; &amp;lt;( echo ${line} )&lt;br /&gt;
&lt;br /&gt;
  # if ${mailboxName} is empty&lt;br /&gt;
  if [ -z &amp;quot;${mailboxName}&amp;quot; ]; then&lt;br /&gt;
    mailboxName=${mailboxUser}&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  # debug&lt;br /&gt;
  echo &amp;quot;mailboxUser: ${mailboxUser}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxPass: ${mailboxPass}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxName: ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  # create each mailbox&lt;br /&gt;
  ${pfCli} mailbox add ${mailboxUser} \&lt;br /&gt;
    --password &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --password2 &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --name &amp;quot;${mailboxName}&amp;quot; \&lt;br /&gt;
    --quota &amp;quot;${mailboxQuota}&amp;quot; \&lt;br /&gt;
    --active --welcome-mail \&lt;br /&gt;
    | tee -a ./log_${dateTimeCurrent}&lt;br /&gt;
&lt;br /&gt;
done &amp;lt; ${mailboxesListFile}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Create mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Roundcube Filter plugin (for email forwarding, sending copy of emails to another email, and other actions) ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=roundcube-managesieve&lt;br /&gt;
&lt;br /&gt;
We will use '''Roundcube managesieve plugin''' for that purpose&amp;lt;blockquote&amp;gt;* First off, check that there's no directory &amp;quot;sieve&amp;quot; in the &amp;quot;/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   * if you have already had '''mail_home = /home/vmail/%d/%u''' in this config, you have to edit it as deliberately '''mail_home = /home/vmail/%d/%u/sieve'''&lt;br /&gt;
&lt;br /&gt;
   * мы задаем опцию mail_home с путем до каталогов с почтой. Обратите внимание, что на вашем сервере настройка может быть другая и необходимо указать правильное значение. Переменные %d и %u указывают, соответственно, на имя домена и учетной записи.&lt;br /&gt;
 ...&lt;br /&gt;
 mail_home = /home/vmail/%d/%u/sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавляем плагин sieve, который должен теперь использоваться локальным агентом доставки lda.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocol lda {&lt;br /&gt;
   # Space separated list of plugins to load (default is global mail_plugins).&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-managesieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по аналогии с protocol lda, мы указываем на необходимость использования sieve&lt;br /&gt;
&lt;br /&gt;
   * мы указываем, что наш сервис будет работать на порту 4190&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocols = $protocols sieve&lt;br /&gt;
 ...&lt;br /&gt;
 service managesieve-login {&lt;br /&gt;
   inet_listener sieve {&lt;br /&gt;
     port = 4190&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *sieve — путь до файла с правилами. Указывается для каждого ящика с помощью переменных.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_path — путь до общего файла с правилами. Используется, если отсутствует файл по пути sieve.&lt;br /&gt;
&lt;br /&gt;
   *sieve_dir — путь до каталога с подключаемыми скриптами-правилами. Указывается для каждого почтового ящика.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_dir — путь до общего каталога с подключаемыми правилами. Используется, если отсутствует sieve_dir.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 plugin {&lt;br /&gt;
   sieve = /home/mail/%d/%u/sieve/dovecot.sieve&lt;br /&gt;
   sieve_global_path = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
   sieve_dir = /home/mail/%d/%u/sieve&lt;br /&gt;
   sieve_global_dir = /etc/dovecot/sieve/global/&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''!!! I'm not sure that the following is necessary'''&lt;br /&gt;
&lt;br /&gt;
'''!!! At first try not to make this actions'''&lt;br /&gt;
&lt;br /&gt;
'''!!! If everything works without it - nevermind'''&lt;br /&gt;
&lt;br /&gt;
   Create dir for global rules sieve_global_dir:&lt;br /&gt;
&lt;br /&gt;
       mkdir -p /etc/dovecot/sieve/global&lt;br /&gt;
&lt;br /&gt;
   Chown dir:&lt;br /&gt;
&lt;br /&gt;
       chown dovecot:dovecot -R /etc/dovecot/sieve&amp;lt;/blockquote&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Roundcube config edit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * At first, check that there's the &amp;quot;managesieve&amp;quot; plugin in the plugin directoty: &amp;quot;/usr/share/nginx/html/webmail/plugins/&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['managesieve_host'] = 'localhost';&lt;br /&gt;
 ...&lt;br /&gt;
 $config['plugins'] = [&lt;br /&gt;
     ...&lt;br /&gt;
     'managesieve',&lt;br /&gt;
 ];&lt;br /&gt;
 ...&lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
Go to Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
Create test filter (for example), copy message to another email after it will be received&lt;br /&gt;
 '''Settings''' - '''Filter''' - Filter &amp;quot;'''Roundcube'''&amp;quot; - &amp;quot;'''+'''&amp;quot;&lt;br /&gt;
     '''Filter name''': mail_forward&lt;br /&gt;
     '''Area''': ALL messages&lt;br /&gt;
     '''Action''': send copy to - xxx@mail.ru&lt;br /&gt;
         '''Save'''&lt;br /&gt;
Now you can see the brand new files in the directory &amp;quot;'''/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/sieve/'''&amp;quot; (config '''roundcube.sieve''' and symlink '''dovecot.sieve''' (config '''/etc/dovecot/conf.d/90-sieve.conf''' point to '''dovecot.sieve'''))&lt;br /&gt;
     ...&lt;br /&gt;
     dovecot.sieve -&amp;gt; roundcube.sieve&lt;br /&gt;
     roundcube.sieve&lt;br /&gt;
     ...&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
Send email to yourself&lt;br /&gt;
&lt;br /&gt;
The message will be received and will be sent to xxx@mail.ru as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, in that case, if you have a private per-user sieve script ('''/home/mail/%d/%u/sieve/dovecot.sieve''', we have already configured it), the global sieve script '''WON'T WORK'''!&lt;br /&gt;
&lt;br /&gt;
To make the private per-user script and the global script work at the same time, we need to do following.&lt;br /&gt;
&lt;br /&gt;
In this example we will filter all mail for all users, and put SPAM to the Junk directory.&lt;br /&gt;
&lt;br /&gt;
https://talk.plesk.com/threads/global-dovecot-sieve-rule.341552/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;*This rule filter SPAM (we have already configured spamassasin above, right?) and put it to Junk dir&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
     fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
Create the new global sieve configuration directive for Dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/37-custom-global-sieve.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 plugin {&lt;br /&gt;
 # Make sure to run &amp;quot;sievec&amp;quot; on this file after creating it:&lt;br /&gt;
 sieve_after = /etc/dovecot/conf.d/custom-sieve/global_after.sieve&lt;br /&gt;
 }&lt;br /&gt;
Run this to compile the new sieve, it will create a binary rule in the same directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sievec /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart the Dovecot services&amp;lt;blockquote&amp;gt;You don't have to start spamassasin service to make spam filter work. Amavisd does it!&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
If you have already configured Spamassassin in this manual above - send email to yourself with following in the message body: '''XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'''&lt;br /&gt;
&lt;br /&gt;
The message wil be put in the Junk directory and the copy of this message will be sent to xxx@mail.ru&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Apr 23 20:39:54 mail amavis[1696]: (01696-01) Passed SPAM {RelayedTaggedInternal,Quarantined}, MYNETS LOCAL [::1]:50042 &amp;lt;admin@alef-studio.ru&amp;gt; -&amp;gt; &amp;lt;admin@alef-studio.ru&amp;gt;, Queue-ID: BE39DE013B, Message-ID: &amp;lt;223db76d330a882501d9b6584e72e16b@alef-studio.ru&amp;gt;, mail_id: qx51q6idSWsl, Hits: 998.992, size: 1158, queued_as: 8850CE0A8A, 709 ms&lt;br /&gt;
     ...&lt;br /&gt;
Now we can configure the private filter rules for each user, and our global SPAM filter will work as well!&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Create new messages with HTML-EDITOR by default ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['htmleditor'] = 1;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Roundcube Pugin. Viewer Office Docs (DOC, XLS, ODT, ODS, etc.) ==&lt;br /&gt;
https://github.com/jfcherng-roundcube/plugin-cloudview&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Address-book from Windows AD DC on-line ==&lt;br /&gt;
&lt;br /&gt;
=== At Windows AD DC Server ===&lt;br /&gt;
Go to &amp;quot;'''Domain Users and Computers'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First off, you need to have a user &amp;quot;'''admin'''&amp;quot; with Administrator's permissions to connect to the AD DC from Roundcube&lt;br /&gt;
&lt;br /&gt;
Create a user in group &amp;quot;'''Users'''&amp;quot; with an email in (! '''You won't see any user at all in Roundcube web-interface if you don't add an email address to the specific users's field !''')&lt;br /&gt;
&lt;br /&gt;
Get a LDAP/AD Administartor's &amp;quot;'''admin'''&amp;quot; Distinguished Name for connect to AD from the Mail Server (we will use it later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;C:\Users\Администратор.WIN-RMJC4R0JMJR&amp;gt; '''dsquery user -name admin'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 '''&amp;quot;CN=admin,CN=Users,DC=alf,DC=local&amp;quot;'''&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== At Mail Server ===&lt;br /&gt;
Add to the Roundcube config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
//Разрешить поиск и автодополнение из массива AD&lt;br /&gt;
$rcmail_config['autocomplete_addressbooks'] = array('sql','AD');&lt;br /&gt;
&lt;br /&gt;
$config['ldap_public'] = array(&lt;br /&gt;
//Имя массива, в котором выполняется поиск&lt;br /&gt;
    'AD' =&amp;gt;array (&lt;br /&gt;
        'name' =&amp;gt; 'ALF', //Отображаемое имя в интерфейсе WEBMail Roundcube&lt;br /&gt;
        'hosts' =&amp;gt; array('10.100.199.21'), //IP адрес или ДНС имя AD DC&lt;br /&gt;
        'sizelimit' =&amp;gt; 600,&lt;br /&gt;
        'port' =&amp;gt; 389,&lt;br /&gt;
        'use_tls' =&amp;gt; false,&lt;br /&gt;
        'user_specific' =&amp;gt; false,&lt;br /&gt;
        'base_dn' =&amp;gt; 'DC=alf,DC=local', //Где выполнять поиск&lt;br /&gt;
        'bind_dn' =&amp;gt; 'admin@alf.local', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'bind_pass' =&amp;gt; 'PassWord#1', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'writable' =&amp;gt; false,&lt;br /&gt;
        'ldap_version' =&amp;gt; 3,&lt;br /&gt;
        'search_fields' =&amp;gt; array(&lt;br /&gt;
           'mail',&lt;br /&gt;
           'cn',&lt;br /&gt;
        ),&lt;br /&gt;
        'name_field' =&amp;gt; 'cn',&lt;br /&gt;
        'email_field' =&amp;gt; 'mail',&lt;br /&gt;
        'surname_field' =&amp;gt; 'sn',&lt;br /&gt;
        'firstname_field' =&amp;gt; 'givenName',&lt;br /&gt;
        //Можно добавить немного дополнительной информации в адресной книге&lt;br /&gt;
        'organization_field'     =&amp;gt; 'company',&lt;br /&gt;
        'jobtitle_field'    =&amp;gt; 'title',&lt;br /&gt;
        'department_field'   =&amp;gt; 'department',&lt;br /&gt;
        //Порядок сортировки&lt;br /&gt;
        'sort' =&amp;gt; 'sn',&lt;br /&gt;
        'scope' =&amp;gt; 'sub', //Выполнять поиск по всему каталогу LDAP // search mode: sub|base|list&lt;br /&gt;
        'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectClass=user)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        //'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectcategory=person)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        'global_search' =&amp;gt; true,&lt;br /&gt;
        'fuzzy_search' =&amp;gt; true&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// LDAP&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache'.&lt;br /&gt;
$config['ldap_cache'] = 'db';&lt;br /&gt;
// Lifetime of LDAP cache. Possible units: s, m, h, d, w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Go to Roundcube web-interface - Contacts&lt;br /&gt;
&lt;br /&gt;
You will see new section &amp;quot;ALF&amp;quot; and contact in there&lt;br /&gt;
&lt;br /&gt;
You can debug if something goes wrong:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /usr/share/nginx/html/webmail/logs/errors.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Amavis blocks some inbound emails addresses with error &amp;quot;'''Blocked BAD-HEADER-0'''&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
https://sourceforge.net/p/amavis/mailman/message/16755074/&lt;br /&gt;
&lt;br /&gt;
https://www.habibza.in/amavisd-whitelist-or-allowed-mail-from-blocked-bad-header/&lt;br /&gt;
&lt;br /&gt;
https://forum.iredmail.org/topic4681-solved-how-to-bypass-amavisd-for-some-senders.html&lt;br /&gt;
&lt;br /&gt;
=== Solution 1 ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $final_bad_header_destiny = D_PASS;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ??? Solution 2. DOESN'T WORK ??? ===&lt;br /&gt;
Create whitelist of emails or even domains, which you want to allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/whitelist-badheader&amp;lt;/code&amp;gt;&lt;br /&gt;
 user@somedomain.com&lt;br /&gt;
 somedomain.com&lt;br /&gt;
Edit amavis config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # white list, which will allow inbound emails with BAD-HEADER-0&lt;br /&gt;
 @bypass_header_checks_maps = (&lt;br /&gt;
    read_hash(&amp;quot;/etc/amavisd/whitelist-badheader&amp;quot;),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
Restart services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logging users' action (e.g. copying, erasing users' emails), which users perform via any IMAP/POP3 mail clients, via Dovecot MDA logging ==&lt;br /&gt;
Enable mail plugins in Dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_plugins = $mail_plugins mail_log notify&lt;br /&gt;
 ...&lt;br /&gt;
Enable plugins '''mail_log_events, mail_log_fields'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/conf.d/90-plugin.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
plugin {&lt;br /&gt;
  #setting_name = value&lt;br /&gt;
&lt;br /&gt;
  # Events to log. Defined in src/plugins/mail-log/mail-log-plugin.c - also available: flag_change save mailbox_create&lt;br /&gt;
  # autoexpunge is included in expunge&lt;br /&gt;
  mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename&lt;br /&gt;
&lt;br /&gt;
  # Also available: Defined in src/plugins/mail-log/mail-log-plugin.c - flags vsize from subject&lt;br /&gt;
  mail_log_fields = uid box msgid from subject&lt;br /&gt;
&lt;br /&gt;
  # Don't log fields that require opening the email (v2.2.28+).&lt;br /&gt;
  #mail_log_cached_only = yes&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make some actions in the user's mailbox (e.g. move email to the Trash and then delete it completely)&lt;br /&gt;
&lt;br /&gt;
Now you can look in the logs ('''expunge = delete''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat '''/var/log/dovecot-info.log''' | grep &amp;quot;'''Info: expunge'''\|'''Info: copy'''&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
 May 11 10:53:56 imap(admin@don661.ru)&amp;lt;259523&amp;gt;&amp;lt;aw5K9CgY6oN/AAAB&amp;gt;: Info: '''copy''' from INBOX: box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 May 11 10:54:13 imap(admin@don661.ru)&amp;lt;259531&amp;gt;&amp;lt;JGZG9SgYLKZ/AAAB&amp;gt;: Info: '''expunge''': box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 May 11 11:08:21 pop3(admin@don661.ru)&amp;lt;259979&amp;gt;&amp;lt;Mz/SJykYIdpOhIjD&amp;gt;: Info: '''expunge''': box=INBOX, uid=10, msgid=&amp;lt;65e7897f-b08d-4f13-8655-73d08485b2f2@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
&lt;br /&gt;
== Block particular senders (emails, domains) - inbox mail (Заблокировать конкретные ящики-отправители или домены - входящую почту) ==&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/header_checks&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 /^From:.*baduser@example.com/ REJECT&lt;br /&gt;
 /^From:.*@spamdomain.com/ REJECT&lt;br /&gt;
 /^From:.*@scientamicron.com/ REJECT&lt;br /&gt;
 /^From:.*@ip-223-6.dataclub.info/ REJECT&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; BLOCK SENDERS LIST&lt;br /&gt;
 header_checks = regexp:/etc/postfix/header_checks&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send an email from the blocked user (user01@gmail.com)&lt;br /&gt;
&lt;br /&gt;
Check logs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Mar 16 22:11:27 mail postfix/cleanup[3119]: 0D83BE1E24: reject: header From: &amp;quot;user01@gmail.com&amp;quot; &amp;lt;user01@gmail.com&amp;gt; from mail-lj1-f176.google.com[209.85.208.176]; from=&amp;lt;user01@gmail.com&amp;gt; to=&amp;lt;call.center2@lada-tambovavtocity.ru&amp;gt; proto=ESMTP helo=&amp;lt;mail-lj1-f176.google.com&amp;gt;: 5.7.1 message content rejected&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
= Errors =&lt;br /&gt;
&lt;br /&gt;
=== Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat ./dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
        ...&lt;br /&gt;
        Feb 16 16:18:17 lda(cless@yourdomain.ru)&amp;lt;2571&amp;gt;&amp;lt;B0HqGhkt7mMLCgAA1XGFgw&amp;gt;: Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database&lt;br /&gt;
        ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
    mail_home = /home/mail/%d/%u&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         Feb 27 00:56:40 imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem&lt;br /&gt;
         ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: '''&amp;quot;Connection error (failed to reach the server) roundcube&amp;quot;''' at Roundcube Webmail web-interface during sending a message, if the size of the message is 10MB+ (a huge sign with pictures, for example) ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
The update from '''PHP-7.3''' to '''PHP-7.4''' has solved the issue.&lt;br /&gt;
&lt;br /&gt;
=== ERROR: PHP-ImageMagick module creates huge files, which use all disk space in / partition ===&lt;br /&gt;
https://github.com/ImageMagick/ImageMagick/issues/395&lt;br /&gt;
&lt;br /&gt;
PHP-ImageMagick module creates huge files, which use all disk space in / partition&lt;br /&gt;
 /tmp/systemd-private-78b2a42fd129405aa1e735b61bf8fb72-php-fpm.service-Icx1Wg/tmp/magick-*&lt;br /&gt;
??? SOLUTION ???&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 1:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/ImageMagick-7/policy.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;policymap&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;memory&amp;quot; value=&amp;quot;2GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;disk&amp;quot; value=&amp;quot;1GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;cache&amp;quot; name=&amp;quot;synchronize&amp;quot; value=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/policymap&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 2:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the following cron jobs for automatic cleanup. The first 2 lines will clean up old files based on their age.&lt;br /&gt;
&lt;br /&gt;
In one case this was still insufficient, since a user was uploading a lot of very large images within a short time, causing the /tmp folder to fill up very quickly. Therefore the last line removes images which are at a certain filesize treshold. I picked a treshold just below the usual size of the magick-* files (see list in first post).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Temporary solution to prevent /tmp from being filled with 200+ MB ImageMagick files&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'magick-*' -delete&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'php*' -delete&lt;br /&gt;
 */5 * * * * find /tmp/ -mmin +5 -type f -name 'magick-*' -size +200M -delete&lt;br /&gt;
&lt;br /&gt;
=== Error in '''Roundcube Webmail during the searching for emails''': '''(Server error)''' ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
It's necessary to Install Full-text search.&lt;br /&gt;
&lt;br /&gt;
Proceed to the according section of this manual: '''Fts-xapian'''.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1925</id>
		<title>Mail Server. AlmaLinux 8. Postfix + Dovecot + Postfixadmin + Roundcube Webmail</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Mail_Server._AlmaLinux_8._Postfix_%2B_Dovecot_%2B_Postfixadmin_%2B_Roundcube_Webmail&amp;diff=1925"/>
		<updated>2025-03-16T19:28:13Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Mail]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Opensource Mail Server. Postfix + Dovecot + Postfixadmin + Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
https://www.dmosk.ru/instruktions.php?object=mailserver-centos8&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== DNS Server Global ==&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Add resource records to the dns server, which is serving your domains (at mikrotik, for example, but it can be any dns-record manager of the registrar, which provides you your new domain)&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - public external IP of the mail server&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''192.168.199.40''''' - local IP of this mail server in you local network&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Root domain MX-record, which point to the mail domain ===&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=yourdomain.ru mx-exchange=mail.yourdomain.ru. mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Domain for administration - mail02.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This should be the hostname of your physical mail server&lt;br /&gt;
&lt;br /&gt;
It's not your domain for mail, just for management&lt;br /&gt;
&lt;br /&gt;
If there will be other mail domains on that server, all emails still will be sended with source-host &amp;quot;mail02.yourdomain.ru&amp;quot; as mail sender&lt;br /&gt;
&lt;br /&gt;
This domain needs to be added to ISP's PTR-record as well&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail02.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mail domain - mail.yourdomain.ru ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;This is your first mail domain&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.yourdomain.ru address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DNS Server Local ==&lt;br /&gt;
At the local '''DNS server''' (whose IP is registred in the file '''/etc/resolv.conf''' of this mail server) you have to register accordance of '''your domains''' and '''local IP''' in you local network of this server:&lt;br /&gt;
 ...&lt;br /&gt;
 192.168.199.42 mail.yourdomain.ru&lt;br /&gt;
 192.168.199.42 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Mail server ==&lt;br /&gt;
&lt;br /&gt;
=== General configuration ===&lt;br /&gt;
System update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hostname&amp;lt;blockquote&amp;gt;'''''mail02.yourdomain.ru''''' - mail server hostname&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;'''''185.225.35.200''''' - mail server public external IP&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;hostnamectl set-hostname mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/hosts&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 185.225.35.200 mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
Check&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig A mail02.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Utils, firewall, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y chrony wget&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;timedatectl set-timezone Europe/Moscow&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable chronyd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp --add-port=22/tcp --add-port=10050/tcp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;firewall-cmd --reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL Certs ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to choose whether you will use self-signed certs or letsencrypt certs or purchased certs. We will use it later for Webmail Interface (nginx), and for Mail Desktop Clients (postfix, dovecot)&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certificates ====&lt;br /&gt;
''If you're going to purchase SSL certificates from CA:''&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''a few wildcard certs''' with main domain and wildcard subdomains (e.g., '''example.com''' and '''*.example.com''') for '''each mail domain'''.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
* You have to purchase '''the only ONE''' multidomain certificate with '''ALL main domain certs and wildcard certificates of your main domain ('''e.g., '''example.com''' and '''*.example.com''' for each domain''')'''.&lt;br /&gt;
&lt;br /&gt;
==== Self-signed ====&lt;br /&gt;
Generate certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/ssl/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj &amp;quot;/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=mail02.yourdomain.ru&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Letsencrypt ====&lt;br /&gt;
Nginx will create /usr/share/nginx/html directory for letsencrypt challenges&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y certbot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You don't have to create cert for each domain. You can put all certs into one file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nginx ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable nginx --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y &amp;lt;nowiki&amp;gt;http://rpms.remirepo.net/enterprise/remi-release-8.rpm&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf module install -y php:remi-7.4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # For more information on configuration, see:&lt;br /&gt;
 #   * Official English Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 #   * Official Russian Documentation: &amp;lt;nowiki&amp;gt;http://nginx.org/ru/docs/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 user nginx;&lt;br /&gt;
 worker_processes auto;&lt;br /&gt;
 error_log /var/log/nginx/error.log;&lt;br /&gt;
 pid /run/nginx.pid;&lt;br /&gt;
 # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.&lt;br /&gt;
 include /usr/share/nginx/modules/*.conf;&lt;br /&gt;
 events {&lt;br /&gt;
    worker_connections 1024;&lt;br /&gt;
 }&lt;br /&gt;
 http {&lt;br /&gt;
    log_format  main  '$remote_addr - $remote_user [$time_local] &amp;quot;$request&amp;quot; '&lt;br /&gt;
                      '$status $body_bytes_sent &amp;quot;$http_referer&amp;quot; '&lt;br /&gt;
                      '&amp;quot;$http_user_agent&amp;quot; &amp;quot;$http_x_forwarded_for&amp;quot;';&lt;br /&gt;
    access_log  /var/log/nginx/access.log  main;&lt;br /&gt;
    sendfile            on;&lt;br /&gt;
    tcp_nopush          on;&lt;br /&gt;
    tcp_nodelay         on;&lt;br /&gt;
    keepalive_timeout   65;&lt;br /&gt;
    types_hash_max_size 2048;&lt;br /&gt;
    include             /etc/nginx/mime.types;&lt;br /&gt;
    default_type        application/octet-stream;&lt;br /&gt;
    # Load modular configuration files from the /etc/nginx/conf.d directory.&lt;br /&gt;
    # See &amp;lt;nowiki&amp;gt;http://nginx.org/en/docs/ngx_core_module.html#include&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    # for more information.&lt;br /&gt;
    include /etc/nginx/conf.d/*.conf;&lt;br /&gt;
 }&lt;br /&gt;
Redirect all HTTP-requests to HTTPS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 #&lt;br /&gt;
 # Note: This file must be loaded before other virtual host config files,&lt;br /&gt;
 #&lt;br /&gt;
 # HTTP&lt;br /&gt;
 server {&lt;br /&gt;
    # Listen on ipv4&lt;br /&gt;
    listen 80;&lt;br /&gt;
    listen [::]:80;&lt;br /&gt;
    server_name _;&lt;br /&gt;
    # Redirect all insecure http:// requests to https://&lt;br /&gt;
    return 301 &amp;lt;nowiki&amp;gt;https://$host$request_uri&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====HTTPS configuring====&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use self-signed or letsencrypt multidomain certificate (all domains and subdomains in one cert)=====&lt;br /&gt;
&lt;br /&gt;
Create a general config for HTTPS traffic (in order to use it with Roundcube Webmail and Postfixadmin)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2 default_server;&lt;br /&gt;
        listen       [::]:443 ssl http2 default_server;&lt;br /&gt;
        server_name  _;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
         &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&amp;quot;;&lt;br /&gt;
         &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate certificates, purchased from official CA or letsencrypt certs (separate cert for every mail domain)=====&lt;br /&gt;
&lt;br /&gt;
Backup /etc/nginx/conf.d/00-default_ssl.conf (or don't create it at all)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv /etc/nginx/conf.d/00-default_ssl.conf /etc/nginx/conf.d/00-default_ssl.conf.ORIG&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create separate config for each mail domain (in order to use it with Roundcube Webmail), and put in it the corresponding certificate path.&lt;br /&gt;
&lt;br /&gt;
Also you can create separate config for you management domain (in order to use it with Postfixadmin web-interface) in the same way (in our case mail02.yourdomain.ru). Or you can use any of our mail domains in order to get access to Postfixadmin web-interface. You also can use for that purpose letsencrypt cert or purchased cert.&lt;br /&gt;
&lt;br /&gt;
For example, this first config is for domain mail.don661.ru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/10-mail.don661.ru_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Settings for a TLS enabled server.&lt;br /&gt;
    server {&lt;br /&gt;
        listen       443 ssl http2;&lt;br /&gt;
        listen       [::]:443 ssl http2;&lt;br /&gt;
        server_name  mail.don661.ru;&lt;br /&gt;
        root         /usr/share/nginx/html;&lt;br /&gt;
 &lt;br /&gt;
        # CERTS. SELF-SIGNED OR LETSENCRYPT&lt;br /&gt;
 &lt;br /&gt;
        # self-signed&lt;br /&gt;
        #ssl_certificate &amp;quot;/etc/pki/nginx/server.crt&amp;quot;;&lt;br /&gt;
        #ssl_certificate_key &amp;quot;/etc/pki/nginx/private/server.key&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        # letsencrypt&lt;br /&gt;
        ssl_certificate &amp;quot;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&amp;quot;;&lt;br /&gt;
        ssl_certificate_key &amp;quot;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
        ssl_session_cache shared:SSL:1m;&lt;br /&gt;
        ssl_session_timeout  10m;&lt;br /&gt;
        ssl_ciphers PROFILE=SYSTEM;&lt;br /&gt;
        ssl_prefer_server_ciphers on;&lt;br /&gt;
 &lt;br /&gt;
        # Load configuration files for the default server block.&lt;br /&gt;
        include /etc/nginx/default.d/*.conf;&lt;br /&gt;
 &lt;br /&gt;
        #location / {&lt;br /&gt;
        #}&lt;br /&gt;
 &lt;br /&gt;
        # REDIRECT *.*.ru (ROOT SUBDOMAIN) TO *.*.ru/webmail (ROUNDCUBE).&lt;br /&gt;
        # FOR EXAMPLE: &amp;lt;nowiki&amp;gt;https://mail.domain123.ru&amp;lt;/nowiki&amp;gt; TO &amp;lt;nowiki&amp;gt;https://mail.domain123.ru/webmail&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
        location = / {&lt;br /&gt;
            return 301 &amp;lt;nowiki&amp;gt;https://$host/webmail&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
        }&lt;br /&gt;
        error_page 404 /404.html;&lt;br /&gt;
            location = /40x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        error_page 500 502 503 504 /50x.html;&lt;br /&gt;
            location = /50x.html {&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        # PHP&lt;br /&gt;
        location ~ \.php$ {&lt;br /&gt;
            set $root_path /usr/share/nginx/html;&lt;br /&gt;
            fastcgi_pass unix:/run/php-fpm/www.sock;&lt;br /&gt;
            fastcgi_index index.php;&lt;br /&gt;
            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;&lt;br /&gt;
            include fastcgi_params;&lt;br /&gt;
            fastcgi_param DOCUMENT_ROOT $root_path;&lt;br /&gt;
        }&lt;br /&gt;
        client_max_body_size 35M;&lt;br /&gt;
        client_body_timeout 300s;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable php-fpm --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MariaDB ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y mariadb-server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable mariadb --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysqladmin -u root password&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin ===&lt;br /&gt;
Installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin/templates_c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DB creating&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -u root -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 # configuring is finished maker&lt;br /&gt;
 $CONF['configured'] = true;&lt;br /&gt;
 &lt;br /&gt;
 # default_language&lt;br /&gt;
 $CONF['default_language'] = 'en';&lt;br /&gt;
 &lt;br /&gt;
 # database_password&lt;br /&gt;
 $CONF['database_password'] = 'PassWord#1';&lt;br /&gt;
 &lt;br /&gt;
 # app checks domain during domains and mailboxes&lt;br /&gt;
 $CONF['emailcheck_resolve_domain']='NO';&lt;br /&gt;
 &lt;br /&gt;
 # amount of records (mailboxes, aliases) per page&lt;br /&gt;
 $CONF['page_size'] = '9999';&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter Setup password, copy generated HASH of the Setup password to config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.local.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['setup_password'] = '$2y$10$ZafzUSBaHy47kta5KfPAjF0aQBjH5i';&lt;br /&gt;
 ...&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/setup.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Login with Setup password&lt;br /&gt;
&lt;br /&gt;
Create new admin at the footer of the page&lt;br /&gt;
     Администратор admin@yourdomain.ru успешно добавлен!&lt;br /&gt;
You are done with your basic setup. You can now login to PostfixAdmin using the account you just created.&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://192.168.199.42/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://mail02.yourdomain.ru/postfixadmin/public/login.php&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfix ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y postfix postfix-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
User to work with mail services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;groupadd -g 1024 vmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;useradd -d /home/mail -g 1024 -u 1024 vmail -m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown vmail:vmail /home/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Main config ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Edit parameters&lt;br /&gt;
 ...&lt;br /&gt;
 # domain, that will be put in email during mail send if it doesn't point in mail's FROM&lt;br /&gt;
 &lt;br /&gt;
 myhostname = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 mydomain = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 myorigin = mail02.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
 # domains for input emails&lt;br /&gt;
 mydestination = $myhostname, localhost.$mydomain, localhost, localhost.localdomain&lt;br /&gt;
 ...&lt;br /&gt;
 # where we can get local users&lt;br /&gt;
 local_recipient_maps = unix:passwd.byname $alias_maps&lt;br /&gt;
 ...&lt;br /&gt;
 # clients, that will send mail without auth at server. allow local server send emails&lt;br /&gt;
 mynetworks = 127.0.0.0/8&lt;br /&gt;
 ...&lt;br /&gt;
 inet_interfaces = all&lt;br /&gt;
 ...&lt;br /&gt;
 inet_protocols = all&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # COMMENT OLD PARAMETERS&lt;br /&gt;
 #smtpd_tls_cert_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtpd_tls_key_file = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CApath = &amp;lt;...&amp;gt;&lt;br /&gt;
 #smtp_tls_CAfile = &amp;lt;...&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed certs&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_cert_file = /etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;smtpd_tls_key_file = /etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;###&amp;lt;/nowiki&amp;gt; OR&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt certs&lt;br /&gt;
 smtpd_tls_cert_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/cert.pem&lt;br /&gt;
 smtpd_tls_key_file = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 smtp_tls_CApath = /etc/letsencrypt/live/ALL-MAIL-DOMAINS&lt;br /&gt;
 smtp_tls_CAfile = /etc/letsencrypt/live/ALL-MAIL-DOMAINS/chain.pem&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the primary certificate for the server, to be used for outgoing connections&lt;br /&gt;
 smtpd_tls_chain_files =&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/privkey.pem,&lt;br /&gt;
  /etc/letsencrypt/live/servername.serverdom.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Provide the map to be used when SNI support is enabled&lt;br /&gt;
 tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
nano /etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; One host per line&lt;br /&gt;
 &lt;br /&gt;
 mail.yourprimarymailserverdomain.com /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yourprimarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 mail.yoursecondarymailserverdomain.com /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/privkey.pem /etc/letsencrypt/live/mail.yoursecondarymailserverdomain.com/fullchain.pem&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; add more domains with keys and certs as needed&lt;br /&gt;
&lt;br /&gt;
postmap -F hash:/etc/postfix/vmail_ssl.map&lt;br /&gt;
&lt;br /&gt;
systemctl restart postfix&lt;br /&gt;
==== Main config again ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   virtual_mailbox_base — storage path for mailboxes&lt;br /&gt;
&lt;br /&gt;
   virtual_alias_maps — format and path of the aliases for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_domains — format and path of the virtual domains&lt;br /&gt;
&lt;br /&gt;
   virtual_mailbox_maps — format and path of the mailboxes for virtual users&lt;br /&gt;
&lt;br /&gt;
   virtual_minimum_uid — start UID number for users&lt;br /&gt;
&lt;br /&gt;
   virtual_uid_maps — user id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_gid_maps — group id, which write messages&lt;br /&gt;
&lt;br /&gt;
   virtual_transport — message deliver&lt;br /&gt;
&lt;br /&gt;
   dovecot_destination_recipient_limit — message transfer from Postfix to Dovecot in steps 1 (one) at a time&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_exceptions_networks — networks excepted from encryption&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl settings&lt;br /&gt;
&lt;br /&gt;
   broken_sasl_auth_clients — option for MS Outlook clients&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — auth type&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — Dovecot tmp files. Full or related (default /var/spool/postfix). Full path — /var/spool/postfix/private/auth&lt;br /&gt;
&lt;br /&gt;
   smtp_use_tls — smtp transfer mandatory&lt;br /&gt;
&lt;br /&gt;
   smtpd_use_tls — indicates to clients that TLS support is available&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_auth_only — use TLS only&lt;br /&gt;
&lt;br /&gt;
   smtpd_helo_required — request to start the session with a greeting&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add parameters at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 virtual_mailbox_base = /home/mail&lt;br /&gt;
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf&lt;br /&gt;
 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf&lt;br /&gt;
 virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf&lt;br /&gt;
 '''### If you want to reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files), add the following option):'''&lt;br /&gt;
 '''# ''smtpd_reject_unlisted_sender = yes''&lt;br /&gt;
 '''### (You can try to send an email with non-existing user in field FROM, you will see a rejection in output:&lt;br /&gt;
 '''### ''echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)'''''&lt;br /&gt;
 virtual_minimum_uid = 1024&lt;br /&gt;
 virtual_uid_maps = static:1024&lt;br /&gt;
 virtual_gid_maps = static:1024&lt;br /&gt;
 virtual_transport = dovecot&lt;br /&gt;
 dovecot_destination_recipient_limit = 1&lt;br /&gt;
 smtpd_sasl_auth_enable = yes&lt;br /&gt;
 smtpd_sasl_exceptions_networks = $mynetworks&lt;br /&gt;
 smtpd_sasl_security_options = noanonymous&lt;br /&gt;
 broken_sasl_auth_clients = yes&lt;br /&gt;
 smtpd_sasl_type = dovecot&lt;br /&gt;
 smtpd_sasl_path = private/auth&lt;br /&gt;
 smtp_use_tls = yes&lt;br /&gt;
 smtpd_use_tls = yes&lt;br /&gt;
 smtpd_tls_auth_only = yes&lt;br /&gt;
 smtpd_helo_required = yes&lt;br /&gt;
Aliases config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_alias_maps.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * '''user, password''' — MySQL DB login and password; '''hosts''' — MySQL hostname; '''dbname''' — Mysql DB name; '''query''' — DB request template&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT goto FROM alias WHERE address='%s' AND active = '1'&lt;br /&gt;
Virtual domains config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_domains_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT domain FROM domain WHERE domain='%u'&lt;br /&gt;
Mailboxes config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/mysql_virtual_mailbox_maps.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 user = postfix&lt;br /&gt;
 password = PassWord#1&lt;br /&gt;
 hosts = localhost&lt;br /&gt;
 dbname = postfix&lt;br /&gt;
 query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* you need to be sure that there's no any uncomment options for '''submission''', '''smtps''' и '''dovecot''' (by default there's no such uncomment options). In this config we configuring Postfix at ports 25, 465 и 587. In master.cf we configuring auxiliary services for Postfix: &lt;br /&gt;
&lt;br /&gt;
   submission   inet  n  -  n  -  -  smtpd:&lt;br /&gt;
&lt;br /&gt;
   submission — service name. In this example '''submission''' is used for MUA at port 587 during message sending.&lt;br /&gt;
&lt;br /&gt;
   inet — type of the service. Possible cases: inet (TCP/IP socket), unix (stream socket), unix-dgram (datagram socket), fifo (named queue channel), pass (stream socket UNIX).&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;n&amp;quot; — whether service private or limited. Possible cases: y or n. For inet service type it should be only n.&lt;br /&gt;
&lt;br /&gt;
   первый &amp;quot;-&amp;quot; — whether service works with root rights. Possible cases: y, n or -. &amp;quot;-&amp;quot; means that this options doesn't applied to this service.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;n&amp;quot; — whether the service should work in chroot. Possible cases: y или n.&lt;br /&gt;
&lt;br /&gt;
   второй &amp;quot;-&amp;quot; — in what time the service should be awaked if one is inactive.&lt;br /&gt;
&lt;br /&gt;
   третий &amp;quot;-&amp;quot; — the maximum number of child processes of this service.&lt;br /&gt;
&lt;br /&gt;
   smtpd — running command.&lt;br /&gt;
&lt;br /&gt;
   * the following are the arguments for running the command:&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_security_level — TLS security level.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_auth_enable — sasl auth enable.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_type — sasl auth type.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_path — temp files path.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_security_options — additional sasl options.&lt;br /&gt;
&lt;br /&gt;
   smtpd_sasl_local_domain — smtp-auth users' domain.&lt;br /&gt;
&lt;br /&gt;
   syslog_name — log prefix of the service in the syslog.&lt;br /&gt;
&lt;br /&gt;
   smtpd_tls_wrappermode — whether running service in custom mode (for TLS support).&lt;br /&gt;
&lt;br /&gt;
   smtpd_client_restrictions — limit clients' connections. allow only authorized clients.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the file&lt;br /&gt;
 submission   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o smtpd_tls_security_level=may&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_sasl_type=dovecot&lt;br /&gt;
   -o smtpd_sasl_path=/var/spool/postfix/private/auth&lt;br /&gt;
   -o smtpd_sasl_security_options=noanonymous&lt;br /&gt;
   -o smtpd_sasl_local_domain=$myhostname&lt;br /&gt;
 smtps   inet  n  -  n  -  -  smtpd&lt;br /&gt;
   -o syslog_name=postfix/smtps&lt;br /&gt;
   -o smtpd_tls_wrappermode=yes&lt;br /&gt;
   -o smtpd_sasl_auth_enable=yes&lt;br /&gt;
   -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;
 dovecot   unix  -  n  n  -  -  pipe&lt;br /&gt;
   flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient}&lt;br /&gt;
&lt;br /&gt;
Log configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;postconf maillog_file=/var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable postfix --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dovecot ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot dovecot-mysql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mailboxes path&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
 mail_home = /home/mail/%d/%u&lt;br /&gt;
 ...&lt;br /&gt;
Listener for the auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;* auth service and 2 listeners:&lt;br /&gt;
&lt;br /&gt;
'''/var/spool/postfix/private/auth''' for Dovecot auth ('''/var/spool/postfix/private/auth''' is a '''private/auth''' in Postfix),&lt;br /&gt;
&lt;br /&gt;
'''auth-userdb''' - '''dovecot-lda''' auth socket, '''666''' means any user can use it, '''user and group''' - socket owner&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 service auth {&lt;br /&gt;
   unix_listener /var/spool/postfix/private/auth {&lt;br /&gt;
    mode = 0666&lt;br /&gt;
    user = postfix&lt;br /&gt;
    group = postfix&lt;br /&gt;
   }&lt;br /&gt;
   unix_listener auth-userdb {&lt;br /&gt;
    mode = 0600&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * otherwise we will see an error: '''net_connect_unix(/var/run/dovecot/stats-writer) failed permission denied''', because vmail user doesn't has specific rights.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add to the end of the conf&lt;br /&gt;
 &lt;br /&gt;
 service stats {&lt;br /&gt;
    unix_listener stats-reader {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
    unix_listener stats-writer {&lt;br /&gt;
        user = vmail&lt;br /&gt;
        group = vmail&lt;br /&gt;
        mode = 0660&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Dovecot auth&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-auth.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * comment common auth and add sql-auth.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;!include auth-system.conf.ext&lt;br /&gt;
 !include auth-sql.conf.ext&lt;br /&gt;
 ...&lt;br /&gt;
Encryption configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Case 1. If you are going to use the only one certificate for all mail domains (multidomain cert)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; self-signed&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_cert = &amp;lt;/etc/ssl/mail/public.pem&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;ssl_key = &amp;lt;/etc/ssl/mail/private.key&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; letsencrypt&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/ALL-MAIL-DOMAINS/privkey.pem&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=====Case 2. If you are going to use separate cert for each domain (TLS SNI (Server Name Indication) support)=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 ssl = required&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; TLS SNI (Server Name Indication) support (https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Individual cert for each domain&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; It is important to note that having multiple SSL certificates per IP will not be compatible with all clients, especially mobile ones. It is a TLS SNI limitation.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Default cert&lt;br /&gt;
 ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
 ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 &lt;br /&gt;
 local_name mail.ladavoronezh.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.ladavoronezh.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 local_name mail.don661.ru {&lt;br /&gt;
   ssl_cert = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/fullchain.pem&lt;br /&gt;
   ssl_key = &amp;lt;/etc/letsencrypt/live/mail.don661.ru/privkey.pem&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dirs autocreation during the first login a mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 lda_mailbox_autocreate = yes&lt;br /&gt;
 ...&lt;br /&gt;
Connect to DB configure&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/auth-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * config for getting users' name and password. It's a default config.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit parameters&lt;br /&gt;
 &lt;br /&gt;
 passdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 userdb {&lt;br /&gt;
   ...&lt;br /&gt;
   args = /etc/dovecot/dovecot-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Connect to mysql configure&amp;lt;blockquote&amp;gt;   * getting data from mysql (mariadb).&lt;br /&gt;
&lt;br /&gt;
'''password_query''' — request for getting password from the '''mailbox''' table;&lt;br /&gt;
&lt;br /&gt;
'''user_query''' — request for getting user's data (home dir, id 1024 (it's a '''vmail''' user id).&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&lt;br /&gt;
 driver = mysql&lt;br /&gt;
 connect = host=localhost dbname=postfix user=postfix password=PassWord#1&lt;br /&gt;
 default_pass_scheme = MD5-CRYPT&lt;br /&gt;
 password_query = SELECT password FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'&lt;br /&gt;
Interface for dovecot listening&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 listen = *&lt;br /&gt;
 ...&lt;br /&gt;
 log_path = /var/log/dovecot.log&lt;br /&gt;
 info_log_path = /var/log/dovecot-info.log&lt;br /&gt;
 debug_log_path = /var/log/dovecot-debug.log&lt;br /&gt;
 &lt;br /&gt;
 # debug log (DON'T ENABLE IT BY DEFAULT, ONLY IN DEBUG CASES)&lt;br /&gt;
 ###mail_debug = yes&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable dovecot --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 777 /var/log/dovecot*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin. First domain and mailbox creating ===&lt;br /&gt;
Go to the Postfixadmin Web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/postfixadmin/public&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Create domain yourdomain.ru&lt;br /&gt;
* Create Mailbox cless@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
=== Roundcube ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube Webmail config defaults.inc.php default parameters:&lt;br /&gt;
&lt;br /&gt;
https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://github.com/roundcube/roundcubemail/releases/download/1.6.1/roundcubemail-1.6.1-complete.tar.gz&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $config['db_dsnw'] = 'mysql://roundcube:PassWord#1@localhost/roundcubemail';&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 $config['enable_installer'] = true;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 // Comment&lt;br /&gt;
 &lt;br /&gt;
 //$config['smtp_host'] = 'localhost:587';&lt;br /&gt;
 //$config['smtp_user'] = '%u';&lt;br /&gt;
 //$config['smtp_pass'] = &amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;;&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // Add&lt;br /&gt;
 &lt;br /&gt;
 $config['smtp_host'] = 'tls://localhost';&lt;br /&gt;
 $config['smtp_conn_options'] = array(&lt;br /&gt;
   'ssl' =&amp;gt; array(&lt;br /&gt;
   'verify_peer' =&amp;gt; false,&lt;br /&gt;
   'verify_peer_name' =&amp;gt; false,&lt;br /&gt;
 ),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
 # web session timeout (in minutes)&lt;br /&gt;
 $config['session_lifetime'] = 1440;&lt;br /&gt;
 ...&lt;br /&gt;
 // If true all folders will be checked during AUTO-REFRESH for recent messages (Otherwise only standard folders will be checked, like Inbox or SPAM)&lt;br /&gt;
 $config['check_all_folders'] = true;&lt;br /&gt;
 &lt;br /&gt;
 // default roundcube webmail interface language&lt;br /&gt;
 $config['language'] = 'ru_RU';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''$config['create_default_folders'] = true''' (creating dirs by default (if there's lack of ones)):&lt;br /&gt;
&lt;br /&gt;
'''Drafts''' — Messages drafts.&lt;br /&gt;
&lt;br /&gt;
'''Junk''' — SPAM.&lt;br /&gt;
&lt;br /&gt;
'''Sent''' — Sent messages.&lt;br /&gt;
&lt;br /&gt;
'''Trash''' — Trash bin for messages.&lt;br /&gt;
&lt;br /&gt;
* It's necessary to avoid errors, for example during receiving or deleting messages.&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
# Add at the end of the file&lt;br /&gt;
&lt;br /&gt;
$config['drafts_mbox'] = 'Drafts';&lt;br /&gt;
$config['junk_mbox'] = 'Junk';&lt;br /&gt;
$config['sent_mbox'] = 'Sent';&lt;br /&gt;
$config['trash_mbox'] = 'Trash';&lt;br /&gt;
$config['create_default_folders'] = true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;chown -R apache:apache /usr/share/nginx/html/webmail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create roundcubemail DB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'PassWord#1';&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; \q&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apply template&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mysql -uroot -p roundcubemail &amp;lt; /usr/share/nginx/html/webmail/SQL/mysql.initial.sql&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install php php-common php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-zip php-imagick php-gd php-fpm php php-pdo php-mysqli php-mbstring php-imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PHP configure&amp;lt;blockquote&amp;gt;* necessary to create message size limit&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 date.timezone = &amp;quot;Europe/Moscow&amp;quot;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 30M&lt;br /&gt;
 ...&lt;br /&gt;
 upload_max_filesize = 30M&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/nginx.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 http {&lt;br /&gt;
    ...&lt;br /&gt;
    client_max_body_size 30M;&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Go to web&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://mail02.yourdomain.ru/webmail/installer/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After web installation - disable installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['enable_installer'] = false;&lt;br /&gt;
 ...&lt;br /&gt;
Remove installer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\rm -R /usr/share/nginx/html/webmail/installer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quota Dovecot + PostfixAdmin ===&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=quota-dovecot-postfixadmin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * plugin to create quotas.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 mail_plugins = $mail_plugins quota&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-imap.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''mail_plugins'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol imap {&lt;br /&gt;
   mail_plugins = $mail_plugins imap_quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-master.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 service dict {&lt;br /&gt;
    unix_listener dict {&lt;br /&gt;
    mode = 0660&lt;br /&gt;
    user = vmail&lt;br /&gt;
    group = vmail&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-quota.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * uncomment '''quota = dict:User quota::proxy::quota'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 plugin {&lt;br /&gt;
   quota = dict:User quota::proxy::quota&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 dict {&lt;br /&gt;
   quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
Create config file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-dict-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Mysql connection&lt;br /&gt;
&lt;br /&gt;
'''host''' — mysql server host;&lt;br /&gt;
&lt;br /&gt;
'''dbname''' — db containing postfix users;&lt;br /&gt;
&lt;br /&gt;
'''user''' — db user;&lt;br /&gt;
&lt;br /&gt;
'''password''' — db password.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 connect = '''host'''=localhost '''dbname'''=postfix '''user'''=postfix '''password'''=PassWord#1&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/storage&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = bytes&lt;br /&gt;
 }&lt;br /&gt;
 map {&lt;br /&gt;
   pattern = priv/quota/messages&lt;br /&gt;
   table = quota2&lt;br /&gt;
   username_field = username&lt;br /&gt;
   value_field = messages&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/dovecot-sql.conf.ext&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *if you have several '''user_query''' in your config, create query for the last one.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find &amp;quot;user_query&amp;quot; and put into this line: '''CONCAT('*:bytes=', quota) AS quota_rule'''&lt;br /&gt;
 user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid, '''''CONCAT('*:bytes=', quota) AS quota_rule''''' FROM mailbox WHERE username = '%u'&lt;br /&gt;
 ...&lt;br /&gt;
Check dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveconf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logout-Login into Roundcube webmail.&lt;br /&gt;
&lt;br /&gt;
At the foot of the page there'll be a quota appear.&lt;br /&gt;
&lt;br /&gt;
=== Clamav + Amavisd ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavisd-new clamd perl-Digest-SHA1 perl-IO-stringy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rsyslog is necessary to write SPAM and VIRUS log to /var/log/maillog&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y rsyslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now rsyslog.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $mydomain = 'yourdomain.ru';&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 # Edit&lt;br /&gt;
 &lt;br /&gt;
 $log_level = 0;              # verbosity 0..5, -d&lt;br /&gt;
 $log_recip_templ = undef;    # disable by-recipient level-0 log entries&lt;br /&gt;
 $do_syslog = 1;              # log via syslogd (preferred)&lt;br /&gt;
 $syslog_facility = 'mail';   # Syslog facility as a string&lt;br /&gt;
            # e.g.: mail, daemon, user, local0, ... local7&lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $myhostname = 'mail02.yourdomain.ru';&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add before line &amp;quot;'''''1;  # insure a defined return value'''''&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $allowed_header_tests{'multiple'} = 0;&lt;br /&gt;
 $allowed_header_tests{'missing'} = 0;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/clamd.d/scan.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Uncomment&lt;br /&gt;
 TCPSocket 3310&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable clamd@scan --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable amavisd --now&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Postfix settings&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''content_filter''' - point to application, which ьуфте to scan messages;&lt;br /&gt;
&lt;br /&gt;
'''receive_override_options''' - allow you to see original email addresses with viruses.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 content_filter = scan:[127.0.0.1]:10024&lt;br /&gt;
 receive_override_options = no_address_mappings&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10025 (сервис без имени, он просто будет слушать на порту 10025 — это порт по умолчанию, на который отправляет сообщение amavis после выполнения проверки). Также, мы используем следующие опции:&lt;br /&gt;
&lt;br /&gt;
   smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.&lt;br /&gt;
&lt;br /&gt;
   smtp_enforce_tls — требовать ли TLS.&lt;br /&gt;
&lt;br /&gt;
   content_filter — приложение для сканирования. В данном примере сканирование отключено.&lt;br /&gt;
&lt;br /&gt;
   receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.&lt;br /&gt;
&lt;br /&gt;
   пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.&lt;br /&gt;
&lt;br /&gt;
   smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.&lt;br /&gt;
&lt;br /&gt;
   mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.&lt;br /&gt;
&lt;br /&gt;
   smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add at the end of the file&lt;br /&gt;
 &lt;br /&gt;
 scan   unix  -  -  n  -  16  smtp&lt;br /&gt;
   -o smtp_send_xforward_command=yes&lt;br /&gt;
   -o smtp_enforce_tls=no&lt;br /&gt;
 127.0.0.1:10025   inet  n  -  n  -  16  smtpd&lt;br /&gt;
   -o content_filter=&lt;br /&gt;
   -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks&lt;br /&gt;
   -o smtpd_helo_restrictions=&lt;br /&gt;
   -o smtpd_client_restrictions=&lt;br /&gt;
   -o smtpd_sender_restrictions=&lt;br /&gt;
   -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;
   # '''OR, if you want to restrict sending emails by users with inexistened local domains, etc.:'''&lt;br /&gt;
   # '''(You can see logs of PASSED o DROPPED emails in ''/var/log/maillog'' after sending them''')&lt;br /&gt;
   # '''-o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject'''&lt;br /&gt;
   -o mynetworks_style=host&lt;br /&gt;
   -o smtpd_authorized_xforward_hosts=127.0.0.0/8&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clamd update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y clamav-update&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/freshclam.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Choose one of the update mirrors&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://clamav.jinr.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;DatabaseMirror &amp;lt;nowiki&amp;gt;https://packages.microsoft.com/clamav/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 DatabaseMirror pivotal-clamav-mirror.s3.amazonaws.com&lt;br /&gt;
 ...&lt;br /&gt;
Then remove the freshclam.dat file and restart the service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rm -f /var/lib/clamav/freshclam.dat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart clamav-freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;freshclam&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Antispam DB update&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sa-update --nogpg --verbose&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cron&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 15 3 * * * /bin/freshclam&lt;br /&gt;
 30 3 * * * /bin/sa-update&lt;br /&gt;
Antivirus checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*&lt;br /&gt;
The email will never come, and you will see the following in the logs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/postfix.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   -OR-&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17688]: (17688-04) Blocked INFECTED (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... relay=127.0.0.1[127.0.0.1]:10024, delay=0.25, delays=0.19/0/0/0.06, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17688-04 - INFECTED: Eicar-Signature)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Redirect SPAM to user's SPAM-directory using Amavis service ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis dovecot-pigeonhole dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * закомментированная строка указывала, что файл с настройками находится в домашней директории каждого пользователя. Мы же будем делать централизованный конфиг в файле /etc/dovecot/sieve/default.sieve.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;sieve = file:~/sieve;active=~/.dovecot.sieve&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add&lt;br /&gt;
 &lt;br /&gt;
 sieve = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавили плагин sieve. Также необходимо со строки снять комментарий, если он был.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lda {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-lmtp.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * также мы добавили плагин sieve + необходимо со строки снять комментарий, если он есть.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 protocol lmtp {&lt;br /&gt;
   ...&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/sieve/default.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы ищем в заголовках X-Spam-Flag и отправляем такие письма в папку Junk.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
    fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;code&amp;gt;chown -R vmail:vmail /etc/dovecot/sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по умолчанию стоит значение D_DISCARD, что означает, что сообщения будут отклонятся. Нам же нужно D_PASS — пропускать.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Edit&lt;br /&gt;
 &lt;br /&gt;
 $final_spam_destiny = D_PASS;&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SPAM filter checking&lt;br /&gt;
&lt;br /&gt;
At your mail server (in Roundcube webmail) send an email to youself with following content:&lt;br /&gt;
    XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X&lt;br /&gt;
The email will be appear inthe SPAM-directory, any you will see in the logs:&lt;br /&gt;
    ...&lt;br /&gt;
    ... amavis[17689]: (17689-04) Blocked SPAM {DiscardedOutbound,Quarantined}, MYNETS LOCAL ...&lt;br /&gt;
    ... status=sent (250 2.7.0 Ok, discarded, id=17689-04 - spam)&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
=== Logrotate of mail logs ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/logrotate.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# see &amp;quot;man logrotate&amp;quot; for details&lt;br /&gt;
# rotate log files weekly&lt;br /&gt;
weekly&lt;br /&gt;
&lt;br /&gt;
# keep 4 weeks worth of backlogs&lt;br /&gt;
rotate 4&lt;br /&gt;
&lt;br /&gt;
# create new (empty) log files after rotating old ones&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
# use date as a suffix of the rotated file&lt;br /&gt;
dateext&lt;br /&gt;
&lt;br /&gt;
# uncomment this if you want your log files compressed&lt;br /&gt;
compress&lt;br /&gt;
&lt;br /&gt;
# RPM packages drop log rotation information into this directory&lt;br /&gt;
include /etc/logrotate.d&lt;br /&gt;
&lt;br /&gt;
# system-specific logs may be also be configured here.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;nano /etc/logrotate.d/mail&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/var/log/dovecot-debug.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot-info.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/dovecot.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/postfix.log {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/var/log/maillog {&lt;br /&gt;
    rotate 7&lt;br /&gt;
    missingok&lt;br /&gt;
    notifempty&lt;br /&gt;
    size 1M&lt;br /&gt;
    weekly&lt;br /&gt;
    create 0777 root root&lt;br /&gt;
    postrotate&lt;br /&gt;
        service rsyslog restart &amp;gt; /dev/null&lt;br /&gt;
    endscript&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Check a cron daily task. It should already exist&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/cron.daily/logrotate&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
/usr/sbin/logrotate /etc/logrotate.conf&lt;br /&gt;
EXITVALUE=$?&lt;br /&gt;
if [ $EXITVALUE != 0 ]; then&lt;br /&gt;
    /usr/bin/logger -t logrotate &amp;quot;ALERT exited abnormally with [$EXITVALUE]&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
exit $EXITVALUE&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Wait for a daily task to complete&lt;br /&gt;
&lt;br /&gt;
Or you can run the logrotate manually:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;logrotate -f /etc/logrotate.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Improving email deliverability (VERY IMPORTANT!) =&lt;br /&gt;
https://www.linuxbabe.com/mail-server/centos-7-iredmail-email-server&lt;br /&gt;
&lt;br /&gt;
To prevent your emails from being flagged as spam, you should set PTR, SPF, DKIM and DMARC records.&lt;br /&gt;
&lt;br /&gt;
=== PTR записи на DNS сервере ===&lt;br /&gt;
&lt;br /&gt;
==== Описание ====&lt;br /&gt;
Запись PTR прописывается _НЕ_ в ресурсных записях днс-сервера, к которому привязан ваш почтовый домен, это делает именно регистратор ip-адреса (провайдер или хостер, предоставляющий внешний ip-адрес)! Если провайдер ростелеком, пишем на электронку support@tmb.ru с просьбой зарегистрировать ptr-запись, штатная техподдержка отказывается предоставлять такую услугу&lt;br /&gt;
&lt;br /&gt;
Если у вас есть свой почтовый сервер, то необходимо, чтобы ваш провайдер (а точнее тот, кто выдал вам статические ip-адреса. если ваш внешний IP предоставил вам хостер, на котором у вас крутится VPS/VDS, то обращаемся в техподдержку хостера) зарегистрировал на своем DNS-сервере PTR записи для вашего почтового сервера (MX-записи). Иначе, подавляющая часть почтовых серверов интернета откажется принимать почту от вашего почтового сервера.&lt;br /&gt;
&lt;br /&gt;
Так же, многие почтовые сервера отвергают письма, если при проверке адреса отправителя в строке им выдается &amp;quot;dynamicip&amp;quot; или &amp;quot;dsl&amp;quot; или подобные слова означающие, что ваш адрес не статический или не совпадает с именем вашего домена.&lt;br /&gt;
&lt;br /&gt;
Если в ответе сервера на ваше отправленное письмо вы видите что-то типа:&lt;br /&gt;
&lt;br /&gt;
  mxs.mail.ru: 550 Sorry, we do not accept mail from hosts with dynamic IP or generic DNS PTR-records. Please get a custom reverse DNS name from your ISP for your host 215.54.54.54 or contact abuse@corp.mail.ru in case of error&lt;br /&gt;
&lt;br /&gt;
это значит, что вам необходимо корректно зарегистрировать PTR запись на DNS-сервере для вашего доменного имени.&lt;br /&gt;
&lt;br /&gt;
Для этого необходимо послать запрос тому, кто выдал вам статические ip-адреса (обычно, это ваш провайдер) с просьбой зарегистрировать PTR запись для вашего домена.&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть одна для одного IP (не нужно создавать две записи для основного домена (mydomain.ru) и почтового домена (mail.mydomain.ru) если оба они привязаны А-записью к одному IP)&lt;br /&gt;
&lt;br /&gt;
PTR запись должна быть создана именно для MX записи. То есть, если адреса домена и почтового обменника не совпадают, то PTR создаем именно для MX записи.&lt;br /&gt;
&lt;br /&gt;
Например, если домен mydomain.ru находится по адресу 22.11.33.44, а почтовый обменник (MX запись) создана для хоста mail.mydomain.ru, расположенного по адресу 11.22.33.44, то и PTR запись нужно создавать для mail.mydomain.ru:&lt;br /&gt;
       44.33.22.11.in-addr.arpa  mail.mydomain.ru&lt;br /&gt;
  Естественно, можно &amp;quot;до кучи&amp;quot; создать обратную запись и для самого домена mydomain.ru. Она так же не помешает:&lt;br /&gt;
       44.33.11.22.in-addr.arpa  mydomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Резюмируя, необходимо сделать следующее: ====&lt;br /&gt;
1. Необходимо прописать ресурсную запись MX (MX 10 mail.yourdomain.ru.) для основного домена &amp;quot;yourdomain.ru&amp;quot;, указав что почтовым доменом MX-сервера является &amp;quot;mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делаем мы.&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего yourdomain.ru - 1.2.3.4   &lt;br /&gt;
   A yourdomain.ru 1.2.3.4&lt;br /&gt;
   MX 10 mail.yourdomain.ru.&lt;br /&gt;
2. Создать PTR-запись на DNS сервере регистратора&lt;br /&gt;
&lt;br /&gt;
IP домена &amp;quot;mail.yourdomain.ru&amp;quot; необязательно должен совпадать с IP &amp;quot;yourdomain.ru&amp;quot;, но PTR-запись должна быть создана регистратором IP-адреса (5.6.7.8) домена &amp;quot;mail.yourdomain.ru&amp;quot;. Если у нас несколько почтовых доменов на одном почтовом сервере и все они выходят через единственный внешний IP, то PTR соответствие необходимо прописать для домена, которым именуется (hostname) сам физический почтовый сервер.&lt;br /&gt;
&lt;br /&gt;
Например, сама физическая машина именуется mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
(&lt;br /&gt;
&lt;br /&gt;
Также для этого необходимо прописать &amp;quot;mail.yourdomain.ru&amp;quot; в следующих местах:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname mail.yourdomain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cоответствие внешнего IP, для которого создаем PTR-запись, и домена mail.yourdomain.ru прописываем в /etc/hosts)&lt;br /&gt;
 ...&lt;br /&gt;
 45.67.59.224 mail.yourdomain.ru&lt;br /&gt;
Изменить настройки postfix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 myhostname = mail.yourdomain.ru&lt;br /&gt;
 myorigin = mail.yourdomain.ru&lt;br /&gt;
 mydomain = mail.yourdomain.ru&lt;br /&gt;
 ...&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
mail.yourdomain.ru не обязан вообще быть почтовым доменом, но он будет в поле &amp;quot;helo: mail.yourdomain.ru&amp;quot; при отправке письма с любого другого почтового домена, работающего на нашем почтовом сервере. поэтому создаем ptr-запись именно для mail.yourdomain.ru - &amp;quot;8.7.6.5.in-addr.arpa mail.yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Это делает регистратор внешнего IP&lt;br /&gt;
&lt;br /&gt;
Например, IP нашего mail.yourdomain.ru 5.6.7.8&lt;br /&gt;
   8.7.6.5.in-addr.arpa mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
==== Проверки ====&lt;br /&gt;
1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;host 5.6.7.8&amp;lt;/code&amp;gt;&lt;br /&gt;
       ...&lt;br /&gt;
       8.7.6.5.in-addr.arpa domain name pointer mail.yourdomain.ru.&lt;br /&gt;
       ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
&lt;br /&gt;
Например, для домена mydomain.ru с адресом 215.54.54.54, необходимо зарегистрировать следующую запись:&lt;br /&gt;
       54.54.54.215.in-addr.arpa name=mydomain.ru&lt;br /&gt;
А если почтовый сервер сидит на отдельном адресе, например, mail.mydomain.ru имеет адрес 215.54.54.55, то необходимо зарегистрировать еще одну PTR запись:&lt;br /&gt;
       55.54.54.215.in-addr.arpa name=mail.mydomain.ru&lt;br /&gt;
Проверить наличие PTR записи на сервере DNS можно с помощью интерфейса команды NSLOOKUP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nslookup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь подключаемся к DNS-серверу провайдера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;server 215.54.54.1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Устанавливаем тип ресурсной записи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set type=PTR&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Делаем запрос на интересующий нас адрес:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;215.54.54.54&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ответ мы должны получить имя своего домена mydomain.ru&lt;br /&gt;
&lt;br /&gt;
=== SPF ===&lt;br /&gt;
SPF (Sender Policy Framework) record specifies which hosts or IP addresses are allowed to send emails on behalf of a domain. You should allow only your own email server or your ISP’s server to send emails for your domain. In your DNS management interface, create a new TXT record like below.&lt;br /&gt;
&lt;br /&gt;
Add TXT-record to your main domain (for example &amp;quot;yourdomain.ru&amp;quot;, _NOT_ subdomain &amp;quot;mail.yourdomain.ru&amp;quot;!)&lt;br /&gt;
 A yourdomain.ru 45.67.59.224&lt;br /&gt;
 MX 10 mail.yourdomain.ru.&lt;br /&gt;
 TXT v=spf1 mx ~all&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   yourdomain.ru.              10      IN      TXT     &amp;quot;v=spf1 mx ~all&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DKIM ===&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y dnf-plugins-core&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum config-manager --set-enabled powertools&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y amavis&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Add first mail domain ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to add second and following as well as the first&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /var/lib/dkim&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generate PEM for our domain&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; domain.ru - the first domain, for wich we generated dkim&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;amavisd genrsa /var/lib/dkim/dmosk.ru.pem 1024&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown amavis:amavis /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 0400 /var/lib/dkim/*.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Comment&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt;$inet_socket_port = 10024;&lt;br /&gt;
 &lt;br /&gt;
 # Add&lt;br /&gt;
 &lt;br /&gt;
 $inet_socket_port = [10024,10026];&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Find this string (its value must be &amp;quot;1&amp;quot;)&lt;br /&gt;
 $enable_dkim_verification = 1;  # enable DKIM signatures verification&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; After the string above add following&lt;br /&gt;
 &lt;br /&gt;
 dkim_key('yourdomain.ru', &amp;quot;dkim&amp;quot;, &amp;quot;/var/lib/dkim/yourdomain.ru.pem&amp;quot;);&lt;br /&gt;
 @dkim_signature_options_bysender_maps = ( {&lt;br /&gt;
   &amp;quot;yourdomain.ru&amp;quot; =&amp;gt; { d =&amp;gt; &amp;quot;yourdomain.ru&amp;quot;, a =&amp;gt; 'rsa-sha256', ttl =&amp;gt; 10*24*3600 },&lt;br /&gt;
 });&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; FIND THIS STRING. ITS VALUE MUST BE &amp;quot;1&amp;quot;&lt;br /&gt;
 $enable_dkim_signing = 1;    # load DKIM signing code, keys defined by dkim_key&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; Add &amp;quot;&amp;quot;&amp;quot;, &amp;quot;yourdomain.ru&amp;quot; &amp;quot;&amp;quot;&amp;quot; IN THIS STRING&lt;br /&gt;
 &lt;br /&gt;
 @local_domains_maps = ( [&amp;quot;.$mydomain&amp;quot;], &amp;quot;yourdomain.ru&amp;quot; );&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generate record for DNS server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf showkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   dkim._domainkey.yourdomain.ru.      3600 TXT (&lt;br /&gt;
   &amp;quot;v=DKIM1; p=&amp;quot;&lt;br /&gt;
   &amp;quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz&amp;quot;&lt;br /&gt;
   &amp;quot;3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUg&amp;quot;&lt;br /&gt;
   &amp;quot;jOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0J&amp;quot;&lt;br /&gt;
   &amp;quot;xfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9O&amp;quot;&lt;br /&gt;
   &amp;quot;YO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61N&amp;quot;&lt;br /&gt;
   &amp;quot;rJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVh&amp;quot;&lt;br /&gt;
   &amp;quot;kwIDAQAB&amp;quot;)&lt;br /&gt;
   ...&lt;br /&gt;
Copy it from &amp;quot;&amp;quot;v=DKIM1...&amp;quot; to &amp;quot;...kwIDAQAB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Remove all &amp;quot;&amp;quot; and line breaks&lt;br /&gt;
&lt;br /&gt;
You'll get something like this (in one line):&lt;br /&gt;
 v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Create subdomain &amp;quot;dkim._domainkey&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;dkim._domainkey&amp;quot; subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 TXT v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjzzr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test at mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;amavisd -c /etc/amavisd/amavisd.conf testkeys&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   TESTING#1 yourdomain.ru: dkim._domainkey.yourdomain.ru =&amp;gt; pass&lt;br /&gt;
   ...&lt;br /&gt;
Test on arbitrary server in internet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig dkim._domainkey.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   ;; ANSWER SECTION:&lt;br /&gt;
   dkim._domainkey.yourdomain.ru. 10   IN      TXT     &amp;quot;v=DKIM1; p= MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6L+HQnFMEzYH+aETHbz3WYbOBXLoF/4+NHiSgXXyErE7IYkvwu4Nu02WPHczNAUCue0qRWMB5cr5b2NNoUgjOsjv/bHFxvrZK4/mW7Yy/8MDpbkUN/dVdeJmw8W6962woxe+YXZd5HVuBg3Xn0JxfqpsLBzzEGU0f+EZ/VA7yAKsuikKKWbT5Y46mj3JB548Hg2qjz&amp;quot; &amp;quot;zr9J2GjSQ6I9OYO3RcteaRTrtJpwckKv1dLT2GUK2jGlKDkSVlAuiPmVgfarZvSqvhP0qWTXSE61NrJHRa0Spo54U2qJBIflQ1oymY3dzHzJ7A08Vx3NJByzLbmRLQM1yuQqfrUbfPEVhkwIDAQAB&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
=== DMARC ===&lt;br /&gt;
DMARC stands for Domain-based Message Authentication, Reporting and Conformance. DMARC can help receiving email servers to identify legitimate emails and prevent your domain name from being used by email spoofing.&lt;br /&gt;
&lt;br /&gt;
To create a DMARC record, go to your DNS manager and add a TXT record. In the name field, enter _dmarc. In the value field, enter the following. (You should create the dmarc@your-domain.com email address.)&lt;br /&gt;
&lt;br /&gt;
Create subdomain &amp;quot;_dmarc&amp;quot; for your main domain &amp;quot;yourdomain.ru&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Create TXT-record in &amp;quot;_dmarc&amp;quot; (_dmarc.yourdomain.ru) subdomain (_NOT_ for main domain &amp;quot;yourdomain.ru&amp;quot; or subdomain &amp;quot;mail.yourdomain.ru&amp;quot;:&lt;br /&gt;
 A 45.67.59.224&lt;br /&gt;
 TXT v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 '''''^^^ THIS RECORD'''''&lt;br /&gt;
Wait 5-10 minutes!&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dig _dmarc.yourdomain.ru txt&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
  �;; ANSWER SECTION:&lt;br /&gt;
   _dmarc.yourdomain.ru.       10      IN      TXT     &amp;quot;v=DMARC1; p=none; pct=100; rua=&amp;lt;nowiki&amp;gt;mailto:dmarc@yourdomain.ru&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
General deliverability test&lt;br /&gt;
&lt;br /&gt;
Go to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://www.mail-tester.com/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Send email from your mail account of your new mail server to randomly generated service's mail address (test-avlwah6p3@srv1.mail-tester.com, for example)&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Затем проверьте оценку&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wait for tests passed&lt;br /&gt;
&lt;br /&gt;
If your score higher than 8, congratulations! &lt;br /&gt;
&lt;br /&gt;
= Add additional mail domain =&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
Root domain and MX-record, which point to the for mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=cless.pro mx-exchange=mail.cless.pro mx-preference=10 ttl=1m type=MX&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mail domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/ip dns static&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;add name=mail.cless.pro address=185.225.35.200 ttl=1m&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SSL certs ===&lt;br /&gt;
&lt;br /&gt;
==== Lentencrypt ====&lt;br /&gt;
&amp;lt;code&amp;gt;certbot certonly --webroot --agree-tos -d mail.cless.pro,mail02.yourdomain.ru,mail.yourdomain.ru --cert-name ALL-MAIL-DOMAINS --email cless@yourdomain.ru -w /usr/share/nginx/html&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Purchased certs ====&lt;br /&gt;
Add additional cert configs for a new domain for '''Nginx''', '''Postfix''' and '''Dovecot'''.&lt;br /&gt;
&lt;br /&gt;
=== Improving email deliverability ===&lt;br /&gt;
Check the '''Improving email deliverability''' section of this manual and do corresponding actions.&lt;br /&gt;
&lt;br /&gt;
=== Postfixadmin web panel ===&lt;br /&gt;
&lt;br /&gt;
* Create domain cless.pro&lt;br /&gt;
* Create mailbox cless@cless.pro&lt;br /&gt;
&lt;br /&gt;
=== Roundcube webmail ===&lt;br /&gt;
Login to Roundcube webmail&lt;br /&gt;
&lt;br /&gt;
Send/Receive email&lt;br /&gt;
&lt;br /&gt;
= Autodiscover Mail Server settings for Mail Clients =&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=autodiscover-mail&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
It provides mail clients Mail Server connection info during configuring Mail Client mailbox&lt;br /&gt;
&lt;br /&gt;
=== Thinderbird ===&lt;br /&gt;
Механизм автонастройки от Mozilla похож на Microsoft. Необходимые настройки должны отдаваться веб-сервером в виде XML-документа. Однако запрос не https, а http; и не POST, а GET. Также обращение идет сначала в формате '''server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain''', и если ответ не будет получен — '''autoconfig.server.domain/mail/config-v1.1.xml?emailaddress=user@server.domain'''.&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;Create А-record (or CNAME) for root domain (example.com):&amp;lt;blockquote&amp;gt;''* где  '''111.111.111.111''' — IP-address of web server, with XML.''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 autoconfig    IN      A       111.111.111.111&lt;br /&gt;
&lt;br /&gt;
==== Nginx config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/910-autodiscover_example.ru.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
# HTTP&lt;br /&gt;
server {&lt;br /&gt;
    listen 80;&lt;br /&gt;
    server_name autoconfig.example.com;&lt;br /&gt;
    root /usr/share/nginx/html/autodiscover/example.com;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autodiscover config ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;You have to create following config for each mail domain at the server&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkdir -p /usr/share/nginx/html/autodiscover/example.ru/mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/autodiscover/example.ru/mail/config-v1.1.xml&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;clientConfig version=&amp;quot;1.1&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;emailProvider id=&amp;quot;example.com&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;domain&amp;gt;example.com&amp;lt;/domain&amp;gt;&lt;br /&gt;
                &amp;lt;displayName&amp;gt;Mail example.com&amp;lt;/displayName&amp;gt;&lt;br /&gt;
                &amp;lt;displayShortName&amp;gt;example.com&amp;lt;/displayShortName&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;imap&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;143&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;incomingServer type=&amp;quot;pop&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;pop.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;995&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;SSL&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/incomingServer&amp;gt;&lt;br /&gt;
                &amp;lt;outgoingServer type=&amp;quot;smtp&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;hostname&amp;gt;mail.example.com&amp;lt;/hostname&amp;gt;&lt;br /&gt;
                        &amp;lt;port&amp;gt;587&amp;lt;/port&amp;gt;&lt;br /&gt;
                        &amp;lt;socketType&amp;gt;STARTTLS&amp;lt;/socketType&amp;gt;&lt;br /&gt;
                        &amp;lt;authentication&amp;gt;password-cleartext&amp;lt;/authentication&amp;gt;&lt;br /&gt;
                        &amp;lt;username&amp;gt;%EMAILADDRESS%&amp;lt;/username&amp;gt;&lt;br /&gt;
                &amp;lt;/outgoingServer&amp;gt;&lt;br /&gt;
        &amp;lt;/emailProvider&amp;gt;&lt;br /&gt;
&amp;lt;/clientConfig&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simpliest method according to the RFC standard (I'm not sure that it works) ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;It works in unstable way. The mail client usually managed to get mail server info, but not everything. Mail client gets '''hosts''' (for example, imap.yourdomain.ru), but not the '''ports'''.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DNS Server ====&lt;br /&gt;
You need to add ''subdomains'' for your ''main domain'' '''yourdomain.ru''' and create '''SRV''' records&lt;br /&gt;
&lt;br /&gt;
Templates&lt;br /&gt;
 _&amp;lt;service name&amp;gt;._&amp;lt;protocol&amp;gt; &amp;lt;priority&amp;gt; &amp;lt;weight&amp;gt; &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;&lt;br /&gt;
Examples&lt;br /&gt;
 _smtp._tcp              IN SRV  10 0 25  smtp.yourdomain.ru.&lt;br /&gt;
 _pop3._tcp              IN SRV  20 0 110 pop.yourdomain.ru.&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _smtps._tcp             IN SRV   0 0 465 smtp.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
 _imaps._tcp             IN SRV   0 0 993 imap.yourdomain.ru.&lt;br /&gt;
 _pop3s._tcp             IN SRV  10 0 995 pop.yourdomain.ru.&lt;br /&gt;
Example&lt;br /&gt;
&lt;br /&gt;
To give your mail clients info about '''imap''' and '''smtp''' settings of your mail server:&lt;br /&gt;
 _imap._tcp              IN SRV  10 0 143 imap.yourdomain.ru.&lt;br /&gt;
 _submission._tcp        IN SRV   0 0 587 smtp.yourdomain.ru.&lt;br /&gt;
&lt;br /&gt;
= Full-text search =&lt;br /&gt;
&lt;br /&gt;
== Fts-xapian ('''It works good!''') ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://github.com/grosjo/fts-xapian]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/#community-developed-plugins]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/settings/plugin/fts-plugin/]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/grosjo/fts-xapianhttps://doc.dovecot.org/configuration_manual/fts/#community-developed-pluginshttps://doc.dovecot.org/settings/plugin/fts-plugin/https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin https://doc.dovecot.org/configuration_manual/fts/dovecot/?highlight=trash%20plugin]&lt;br /&gt;
&lt;br /&gt;
=== Description ===&lt;br /&gt;
Dovecot has some problems with email searching if there's a huge amount of emails in the mailbox. It can perodically throw an error &amp;quot;Server error&amp;quot; during the search.&lt;br /&gt;
&lt;br /&gt;
To avoid such problems we can use Full-text search.&lt;br /&gt;
&lt;br /&gt;
=== Build plugin ===&lt;br /&gt;
&lt;br /&gt;
==== Variant 1. Build plugin at the same machine ====&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
==== Variant 2. Build plugin at the another machine with the same arch and apps versions, and copy compiled plugin to the mail server ====&lt;br /&gt;
&lt;br /&gt;
===== Another machine for building =====&lt;br /&gt;
Build plugin at the another machine&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y autoconf automake make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y dovecot-devel git&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf group install -y &amp;quot;Development Tools&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/grosjo/fts-xapian&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd fts-xapian&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoupdate&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;autoreconf -vi&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure --with-dovecot=/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;make install&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy plugin to the mail server&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rsync -avPh /usr/lib64/dovecot/lib21_fts_xapian_plugin.* root@&amp;lt;mail-server-IP&amp;gt;:/usr/lib64/dovecot/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mail server =====&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y sqlite-devel libicu-devel xapian-core-devel&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Now proceed to the &amp;quot;'''Configure plugin at the mail server'''&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
=== Configure plugin at the mail server ===&lt;br /&gt;
Check the installed plugin&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /usr/lib64/dovecot/lib21_fts_xapian_plugin.*&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     -rw-r--r-- 1 root root 2.9M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.a&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.1K Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.la&lt;br /&gt;
     -rwxr-xr-x 1 root root 1.2M Nov  5 19:31 /usr/lib64/dovecot/lib21_fts_xapian_plugin.so&lt;br /&gt;
     ...&lt;br /&gt;
Add plugin to the common conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
mail_plugins = $mail_plugins &amp;lt;...&amp;gt; fts fts_xapian&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Add plugin config&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/95-fts.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;partial=2 - the minimum length of the search string&amp;lt;/blockquote&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
plugin {&lt;br /&gt;
    fts = xapian&lt;br /&gt;
    fts_xapian = partial=2 full=20 attachments=0 verbose=0&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex = yes&lt;br /&gt;
    fts_enforced = yes&lt;br /&gt;
&lt;br /&gt;
    fts_autoindex_exclude = \Trash&lt;br /&gt;
&lt;br /&gt;
    # Index attachements&lt;br /&gt;
    fts_decoder = decode2text&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service indexer-worker {&lt;br /&gt;
    # Increase vsz_limit to 2GB or above.&lt;br /&gt;
    # Or 0 if you have rather large memory usable on your server, which is preferred for performance)&lt;br /&gt;
    vsz_limit = 2G&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
service decode2text {&lt;br /&gt;
    executable = script /usr/libexec/dovecot/decode2text.sh&lt;br /&gt;
    user = dovecot&lt;br /&gt;
    unix_listener decode2text {&lt;br /&gt;
        mode = 0666&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot and check the service status. There shouldn't be errors or warnings in the output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's necessary to index all the mailboxes if you have already had productive and filled mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm index -u $i \*; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm index -u user@domain.ru \*&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''COMMANDS'''&lt;br /&gt;
&lt;br /&gt;
       '''fts optimize'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts optimize [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
&lt;br /&gt;
       '''fts rescan'''&lt;br /&gt;
&lt;br /&gt;
           doveadm fts rescan [-u user|-A|-F file] [-S socket_path] [namespace]&lt;br /&gt;
&lt;br /&gt;
           Scan what mails exist in the full text search index and compare those to what actually exist in mailboxes.  This removes mails from the index that have already been expunged and makes sure&lt;br /&gt;
&lt;br /&gt;
           that  the  next  doveadm index will index all the missing mails (if any). Note that currently most FTS backends do not implement this properly, but instead they delete all the FTS indexes.&lt;br /&gt;
&lt;br /&gt;
           This may change in the future versions.&amp;lt;/blockquote&amp;gt;Place the task to optimize your xapian indexes into the crontab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # Optimize the full text search index.  This is also done automatically by the full text search engines, but this enforces it to happen.&lt;br /&gt;
 0 4 * * * for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts optimize -u $i; done&lt;br /&gt;
 ...&lt;br /&gt;
Optionally&amp;lt;blockquote&amp;gt;I'm not sure this is really necessary&lt;br /&gt;
&lt;br /&gt;
It takes a lot of time and during this process the search doesn't work&lt;br /&gt;
&lt;br /&gt;
Also, after the rescan, the directories &amp;quot;/home/mail/&amp;lt;domain&amp;gt;/&amp;lt;user&amp;gt;/xapian-indexes/db_*&amp;quot; will be deleted, and they will be created only after a user will click on the directories in the web-interface. It takes also a lot of time&lt;br /&gt;
&lt;br /&gt;
You can rescan indexes of your mailboxes&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;for i in `mysql -h127.0.0.1 -N -uroot -p'''&amp;lt;mysqlRootPassword&amp;gt;''' postfix -e &amp;quot;SELECT username FROM mailbox;&amp;quot;`; do doveadm fts rescan -u $i; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or do it just for only one mailbox&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm fts rescan -u user@domain.ru&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the console&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y telnet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;telnet localhost imap&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a login user@don661.ru PassWord#1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a select Inbox&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;a SEARCH text &amp;quot;test&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check the search in the '''Roundcube Webmail'''&amp;lt;blockquote&amp;gt;In '''Roundcube Webmail''' for the searching of text in the message body it's necessary to click on the arrow right to the search field and to check &amp;quot;'''Message body'''&amp;quot; as a search source!&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SOLR ('''I didn't test it!''') ==&lt;br /&gt;
https://doc.dovecot.org/configuration_manual/fts/solr/&lt;br /&gt;
&lt;br /&gt;
== Fts-elastic ('''I didn't test it!''') ==&lt;br /&gt;
https://github.com/filiphanes/fts-elastic&lt;br /&gt;
&lt;br /&gt;
= Postfix limits (I didn't test it!) =&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=postfix-limits#mailbox-size&lt;br /&gt;
&lt;br /&gt;
= Desktop mail clients =&lt;br /&gt;
&lt;br /&gt;
=== Thunderbird ===&lt;br /&gt;
'''IMAP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 143&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
'''SMTP''':&lt;br /&gt;
&lt;br /&gt;
  '''Domain''': mail.yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
  '''Port''': 587&lt;br /&gt;
&lt;br /&gt;
  '''Encryption type''': STARTTLS&lt;br /&gt;
&lt;br /&gt;
'''  Username''': user@yourdomain.ru&lt;br /&gt;
&lt;br /&gt;
= Hints =&lt;br /&gt;
&lt;br /&gt;
== Mail queue check ==&lt;br /&gt;
&amp;lt;code&amp;gt;mailq&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Show connected users ==&lt;br /&gt;
Users IMAP (via mail clients)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;doveadm who&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Users WEB Roundcube&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;netstat -an | grep :443 | grep -v TIME_WAIT&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restrict sending emails by local users with non-existing local domains in the field ''FROM'' ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/master.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 -o smtpd_recipient_restrictions=reject_invalid_hostname,reject_non_fqdn_sender,reject_unknown_sender_domain,reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,reject&lt;br /&gt;
 ...&lt;br /&gt;
You can see logs of PASSED o DROPPED emails in '''/var/log/maillog''' after sending them.&lt;br /&gt;
&lt;br /&gt;
== Reject users-senders (in ''FROM'' field), who are not in the users list (it reads from mysql_virtual_* files) ==&lt;br /&gt;
https://serverfault.com/questions/694511/postfix-how-to-reject-sender-addresses-that-dont-exist-only-for-local-domains&lt;br /&gt;
&lt;br /&gt;
Add the following option to '''/etc/postfix/main.cf''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 smtpd_reject_unlisted_sender = yes&lt;br /&gt;
 ...&lt;br /&gt;
You can try to send an email with non-existing user in field FROM, and you will see a rejection in output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;Test text&amp;quot; | mail -v -s &amp;quot;Test title&amp;quot; -S smtp=&amp;quot;mail.don661.ru:587&amp;quot; -S smtp-use-starttls -S smtp-auth=plain -S smtp-auth-user=&amp;quot;admin@don661.ru&amp;quot; -S smtp-auth-password=&amp;quot;PassWord&amp;quot; -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from=NON-EXIST-USER@don661.ru admin@alef-studio.ru)&amp;lt;/code&amp;gt;&lt;br /&gt;
== Message size limit (message size itself + attached file size) ==&lt;br /&gt;
You have to set limits in the each following entity.&lt;br /&gt;
&lt;br /&gt;
In this example we make limit at about ~30MB for attachment&lt;br /&gt;
&lt;br /&gt;
==== Postfix limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/postfix/main.cf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 message_size_limit = 46080000 # ~30MB (10240000 - ~10MB)&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Roundcube limit ====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Roundcube preserves some percentage of the max message size (search 1.33 on this page, so if you set the max to 100M, it tells you only 75MB is allowed (100 / 1.33). This is better because email messsage will be encoded before sending to MTA and the encoded attachment is larger than the original file.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['max_message_size'] = '40M'; # max summ message size (not file)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
==== Nginx limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/nginx/conf.d/00-default_ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 server {&lt;br /&gt;
     ...&lt;br /&gt;
     client_max_body_size 35M; # max size of a message&lt;br /&gt;
     client_body_timeout 300s; # timeout while upload attachment, otherwise upload may be canceled by timeout in case of a low upload speed, for example&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PHP limit ====&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 post_max_size = 35M;&lt;br /&gt;
 upload_max_filesize = 35M;&lt;br /&gt;
 ...&lt;br /&gt;
reboot &lt;br /&gt;
&lt;br /&gt;
== Amount of attached files in an email ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/php.ini&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; Maximum number of files that can be uploaded via a single request&lt;br /&gt;
 max_file_uploads = 50&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx.service php-fpm.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating users via CLI ==&lt;br /&gt;
&lt;br /&gt;
=== A single mailbox creation ===&lt;br /&gt;
Postfixadmin-cli installation&amp;lt;blockquote&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;if you have already had installed postfixadmin, you don't have to do the following&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;wget &amp;lt;nowiki&amp;gt;https://sourceforge.net/projects/postfixadmin/files/latest/download&amp;lt;/nowiki&amp;gt; -O postfixadmin.tar.gz&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /usr/share/nginx/html/postfixadmin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Help&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comment password validation limits (e.g. &amp;quot;# must contain at least 2 digits&amp;quot; or something you needed) in the array 'password_validation' of the postfix config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/postfixadmin/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $CONF['password_validation'] = array(&lt;br /&gt;
 ...&lt;br /&gt;
 #    '/([0-9].*){2}/'        =&amp;gt; 'password_no_digits 2',      # must contain at least 2 digits&lt;br /&gt;
 ...&lt;br /&gt;
Create user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /usr/share/nginx/html/postfixadmin/scripts&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-cli mailbox add prod@domain123.ru --password &amp;quot;AlefStudioS*100&amp;quot; --password2 &amp;quot;AlefStudioS*100&amp;quot; --name &amp;quot;Компания AlefStudio&amp;quot; --quota &amp;quot;4096&amp;quot; --active --welcome-mail&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mass mailboxes creation ===&lt;br /&gt;
Mailboxes list file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./mailboxes.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
 john@domain.ru|pass1|John Smith&lt;br /&gt;
 ann@domain.ru|pass2|Анна Паста Бродерик-Иванова&lt;br /&gt;
Milbox creation script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
#####&lt;br /&gt;
#&lt;br /&gt;
# Mass postfixadmin mailboxes creation by @ClessAlvein&lt;br /&gt;
#&lt;br /&gt;
#####&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# VARS&lt;br /&gt;
&lt;br /&gt;
mailboxesListFile=&amp;quot;./USERS_lada-tambovavtocity.ru.txt&amp;quot;&lt;br /&gt;
mailboxQuota=&amp;quot;2048&amp;quot;&lt;br /&gt;
pfCli=&amp;quot;/usr/share/nginx/html/postfixadmin/scripts/postfixadmin-cli&amp;quot;&lt;br /&gt;
dateTimeCurrent=`date +%Y-%m-%d_%H-%M-%S`&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# SCRIPT START&lt;br /&gt;
&lt;br /&gt;
# declare array with mailbox data in the each line&lt;br /&gt;
declare -A arrayMailboxes;&lt;br /&gt;
&lt;br /&gt;
# getting each line from the file with each user's data&lt;br /&gt;
while IFS= read -r line || [[ &amp;quot;$line&amp;quot; ]];&lt;br /&gt;
do&lt;br /&gt;
  # getting user, pass, name from the line and put it to the assoc array key=value&lt;br /&gt;
  while IFS=&amp;quot;|&amp;quot; read &amp;quot;mailboxUserFromFile&amp;quot; &amp;quot;mailboxPassFromFile&amp;quot; &amp;quot;mailboxNameFromFile&amp;quot;;&lt;br /&gt;
  do&lt;br /&gt;
    # makeup&lt;br /&gt;
    echo &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # debug&lt;br /&gt;
    #echo &amp;quot;${mailboxUser}, ${mailboxPass}, ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # declare assoc array with each key as a bit mailbox's data&lt;br /&gt;
    declare -A arrayMailbox;&lt;br /&gt;
&lt;br /&gt;
    # each key is a bit of the mailbox's data&lt;br /&gt;
    arrayMailbox[arrayMailboxUser]=${mailboxUserFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxPass]=${mailboxPassFromFile};&lt;br /&gt;
    arrayMailbox[arrayMailboxName]=${mailboxNameFromFile};&lt;br /&gt;
&lt;br /&gt;
    # for each bit of mailbox's data create var (user,pass,name)&lt;br /&gt;
    for key in &amp;quot;${!arrayMailbox[@]}&amp;quot;;&lt;br /&gt;
    do&lt;br /&gt;
      case $key in&lt;br /&gt;
      arrayMailboxUser)&lt;br /&gt;
        mailboxUser=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxPass)&lt;br /&gt;
        mailboxPass=${arrayMailbox[${key}]};;&lt;br /&gt;
      arrayMailboxName)&lt;br /&gt;
        mailboxName=${arrayMailbox[${key}]};;&lt;br /&gt;
      esac&lt;br /&gt;
    done&lt;br /&gt;
  done &amp;lt; &amp;lt;( echo ${line} )&lt;br /&gt;
&lt;br /&gt;
  # if ${mailboxName} is empty&lt;br /&gt;
  if [ -z &amp;quot;${mailboxName}&amp;quot; ]; then&lt;br /&gt;
    mailboxName=${mailboxUser}&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  # debug&lt;br /&gt;
  echo &amp;quot;mailboxUser: ${mailboxUser}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxPass: ${mailboxPass}&amp;quot;;&lt;br /&gt;
  echo &amp;quot;mailboxName: ${mailboxName}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  # create each mailbox&lt;br /&gt;
  ${pfCli} mailbox add ${mailboxUser} \&lt;br /&gt;
    --password &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --password2 &amp;quot;${mailboxPass}&amp;quot; \&lt;br /&gt;
    --name &amp;quot;${mailboxName}&amp;quot; \&lt;br /&gt;
    --quota &amp;quot;${mailboxQuota}&amp;quot; \&lt;br /&gt;
    --active --welcome-mail \&lt;br /&gt;
    | tee -a ./log_${dateTimeCurrent}&lt;br /&gt;
&lt;br /&gt;
done &amp;lt; ${mailboxesListFile}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Create mailboxes&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./postfixadmin-mass-mailboxes-create.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Roundcube Filter plugin (for email forwarding, sending copy of emails to another email, and other actions) ==&lt;br /&gt;
https://www.dmosk.ru/miniinstruktions.php?mini=roundcube-managesieve&lt;br /&gt;
&lt;br /&gt;
We will use '''Roundcube managesieve plugin''' for that purpose&amp;lt;blockquote&amp;gt;* First off, check that there's no directory &amp;quot;sieve&amp;quot; in the &amp;quot;/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   * if you have already had '''mail_home = /home/vmail/%d/%u''' in this config, you have to edit it as deliberately '''mail_home = /home/vmail/%d/%u/sieve'''&lt;br /&gt;
&lt;br /&gt;
   * мы задаем опцию mail_home с путем до каталогов с почтой. Обратите внимание, что на вашем сервере настройка может быть другая и необходимо указать правильное значение. Переменные %d и %u указывают, соответственно, на имя домена и учетной записи.&lt;br /&gt;
 ...&lt;br /&gt;
 mail_home = /home/vmail/%d/%u/sieve&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/15-lda.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * в данном примере мы добавляем плагин sieve, который должен теперь использоваться локальным агентом доставки lda.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocol lda {&lt;br /&gt;
   # Space separated list of plugins to load (default is global mail_plugins).&lt;br /&gt;
   mail_plugins = $mail_plugins sieve&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/20-managesieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * по аналогии с protocol lda, мы указываем на необходимость использования sieve&lt;br /&gt;
&lt;br /&gt;
   * мы указываем, что наш сервис будет работать на порту 4190&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 protocols = $protocols sieve&lt;br /&gt;
 ...&lt;br /&gt;
 service managesieve-login {&lt;br /&gt;
   inet_listener sieve {&lt;br /&gt;
     port = 4190&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/90-sieve.conf&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   *sieve — путь до файла с правилами. Указывается для каждого ящика с помощью переменных.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_path — путь до общего файла с правилами. Используется, если отсутствует файл по пути sieve.&lt;br /&gt;
&lt;br /&gt;
   *sieve_dir — путь до каталога с подключаемыми скриптами-правилами. Указывается для каждого почтового ящика.&lt;br /&gt;
&lt;br /&gt;
   *sieve_global_dir — путь до общего каталога с подключаемыми правилами. Используется, если отсутствует sieve_dir.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 plugin {&lt;br /&gt;
   sieve = /home/mail/%d/%u/sieve/dovecot.sieve&lt;br /&gt;
   sieve_global_path = /etc/dovecot/sieve/default.sieve&lt;br /&gt;
   sieve_dir = /home/mail/%d/%u/sieve&lt;br /&gt;
   sieve_global_dir = /etc/dovecot/sieve/global/&lt;br /&gt;
   ...&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''!!! I'm not sure that the following is necessary'''&lt;br /&gt;
&lt;br /&gt;
'''!!! At first try not to make this actions'''&lt;br /&gt;
&lt;br /&gt;
'''!!! If everything works without it - nevermind'''&lt;br /&gt;
&lt;br /&gt;
   Create dir for global rules sieve_global_dir:&lt;br /&gt;
&lt;br /&gt;
       mkdir -p /etc/dovecot/sieve/global&lt;br /&gt;
&lt;br /&gt;
   Chown dir:&lt;br /&gt;
&lt;br /&gt;
       chown dovecot:dovecot -R /etc/dovecot/sieve&amp;lt;/blockquote&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Roundcube config edit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   * At first, check that there's the &amp;quot;managesieve&amp;quot; plugin in the plugin directoty: &amp;quot;/usr/share/nginx/html/webmail/plugins/&amp;quot;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['managesieve_host'] = 'localhost';&lt;br /&gt;
 ...&lt;br /&gt;
 $config['plugins'] = [&lt;br /&gt;
     ...&lt;br /&gt;
     'managesieve',&lt;br /&gt;
 ];&lt;br /&gt;
 ...&lt;br /&gt;
 // it's necessary for the correct redirection of emails&lt;br /&gt;
 // to folders with Cyrillic names using sieve&lt;br /&gt;
 // &amp;lt;nowiki&amp;gt;https://github.com/Mailu/Mailu/issues/2258&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $config['managesieve_mbox_encoding'] = 'UTF-8';&lt;br /&gt;
 ...&lt;br /&gt;
Go to Roundcube Webmail&lt;br /&gt;
&lt;br /&gt;
Create test filter (for example), copy message to another email after it will be received&lt;br /&gt;
 '''Settings''' - '''Filter''' - Filter &amp;quot;'''Roundcube'''&amp;quot; - &amp;quot;'''+'''&amp;quot;&lt;br /&gt;
     '''Filter name''': mail_forward&lt;br /&gt;
     '''Area''': ALL messages&lt;br /&gt;
     '''Action''': send copy to - xxx@mail.ru&lt;br /&gt;
         '''Save'''&lt;br /&gt;
Now you can see the brand new files in the directory &amp;quot;'''/home/mail/&amp;lt;DOMAIN&amp;gt;/&amp;lt;USER&amp;gt;/sieve/'''&amp;quot; (config '''roundcube.sieve''' and symlink '''dovecot.sieve''' (config '''/etc/dovecot/conf.d/90-sieve.conf''' point to '''dovecot.sieve'''))&lt;br /&gt;
     ...&lt;br /&gt;
     dovecot.sieve -&amp;gt; roundcube.sieve&lt;br /&gt;
     roundcube.sieve&lt;br /&gt;
     ...&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
Send email to yourself&lt;br /&gt;
&lt;br /&gt;
The message will be received and will be sent to xxx@mail.ru as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, in that case, if you have a private per-user sieve script ('''/home/mail/%d/%u/sieve/dovecot.sieve''', we have already configured it), the global sieve script '''WON'T WORK'''!&lt;br /&gt;
&lt;br /&gt;
To make the private per-user script and the global script work at the same time, we need to do following.&lt;br /&gt;
&lt;br /&gt;
In this example we will filter all mail for all users, and put SPAM to the Junk directory.&lt;br /&gt;
&lt;br /&gt;
https://talk.plesk.com/threads/global-dovecot-sieve-rule.341552/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/dovecot/conf.d/custom-sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;*This rule filter SPAM (we have already configured spamassasin above, right?) and put it to Junk dir&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 require &amp;quot;fileinto&amp;quot;;&lt;br /&gt;
 if header :contains &amp;quot;X-Spam-Flag&amp;quot; &amp;quot;YES&amp;quot; {&lt;br /&gt;
     fileinto &amp;quot;Junk&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
Create the new global sieve configuration directive for Dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/37-custom-global-sieve.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 plugin {&lt;br /&gt;
 # Make sure to run &amp;quot;sievec&amp;quot; on this file after creating it:&lt;br /&gt;
 sieve_after = /etc/dovecot/conf.d/custom-sieve/global_after.sieve&lt;br /&gt;
 }&lt;br /&gt;
Run this to compile the new sieve, it will create a binary rule in the same directory&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sievec /etc/dovecot/conf.d/custom-sieve/global_after.sieve&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restart the Dovecot services&amp;lt;blockquote&amp;gt;You don't have to start spamassasin service to make spam filter work. Amavisd does it!&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test it&lt;br /&gt;
&lt;br /&gt;
If you have already configured Spamassassin in this manual above - send email to yourself with following in the message body: '''XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'''&lt;br /&gt;
&lt;br /&gt;
The message wil be put in the Junk directory and the copy of this message will be sent to xxx@mail.ru&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;tail /var/log/maillog&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Apr 23 20:39:54 mail amavis[1696]: (01696-01) Passed SPAM {RelayedTaggedInternal,Quarantined}, MYNETS LOCAL [::1]:50042 &amp;lt;admin@alef-studio.ru&amp;gt; -&amp;gt; &amp;lt;admin@alef-studio.ru&amp;gt;, Queue-ID: BE39DE013B, Message-ID: &amp;lt;223db76d330a882501d9b6584e72e16b@alef-studio.ru&amp;gt;, mail_id: qx51q6idSWsl, Hits: 998.992, size: 1158, queued_as: 8850CE0A8A, 709 ms&lt;br /&gt;
     ...&lt;br /&gt;
Now we can configure the private filter rules for each user, and our global SPAM filter will work as well!&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Create new messages with HTML-EDITOR by default ==&lt;br /&gt;
&amp;lt;code&amp;gt;nano /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $config['htmleditor'] = 1;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== Roundcube Pugin. Viewer Office Docs (DOC, XLS, ODT, ODS, etc.) ==&lt;br /&gt;
https://github.com/jfcherng-roundcube/plugin-cloudview&lt;br /&gt;
&lt;br /&gt;
== Roundcube. Address-book from Windows AD DC on-line ==&lt;br /&gt;
&lt;br /&gt;
=== At Windows AD DC Server ===&lt;br /&gt;
Go to &amp;quot;'''Domain Users and Computers'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
First off, you need to have a user &amp;quot;'''admin'''&amp;quot; with Administrator's permissions to connect to the AD DC from Roundcube&lt;br /&gt;
&lt;br /&gt;
Create a user in group &amp;quot;'''Users'''&amp;quot; with an email in (! '''You won't see any user at all in Roundcube web-interface if you don't add an email address to the specific users's field !''')&lt;br /&gt;
&lt;br /&gt;
Get a LDAP/AD Administartor's &amp;quot;'''admin'''&amp;quot; Distinguished Name for connect to AD from the Mail Server (we will use it later)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;C:\Users\Администратор.WIN-RMJC4R0JMJR&amp;gt; '''dsquery user -name admin'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 '''&amp;quot;CN=admin,CN=Users,DC=alf,DC=local&amp;quot;'''&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
=== At Mail Server ===&lt;br /&gt;
Add to the Roundcube config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /usr/share/nginx/html/webmail/config/config.inc.php&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
//Разрешить поиск и автодополнение из массива AD&lt;br /&gt;
$rcmail_config['autocomplete_addressbooks'] = array('sql','AD');&lt;br /&gt;
&lt;br /&gt;
$config['ldap_public'] = array(&lt;br /&gt;
//Имя массива, в котором выполняется поиск&lt;br /&gt;
    'AD' =&amp;gt;array (&lt;br /&gt;
        'name' =&amp;gt; 'ALF', //Отображаемое имя в интерфейсе WEBMail Roundcube&lt;br /&gt;
        'hosts' =&amp;gt; array('10.100.199.21'), //IP адрес или ДНС имя AD DC&lt;br /&gt;
        'sizelimit' =&amp;gt; 600,&lt;br /&gt;
        'port' =&amp;gt; 389,&lt;br /&gt;
        'use_tls' =&amp;gt; false,&lt;br /&gt;
        'user_specific' =&amp;gt; false,&lt;br /&gt;
        'base_dn' =&amp;gt; 'DC=alf,DC=local', //Где выполнять поиск&lt;br /&gt;
        'bind_dn' =&amp;gt; 'admin@alf.local', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'bind_pass' =&amp;gt; 'PassWord#1', //Авторизация admin@alf.local на контроллере домена&lt;br /&gt;
        'writable' =&amp;gt; false,&lt;br /&gt;
        'ldap_version' =&amp;gt; 3,&lt;br /&gt;
        'search_fields' =&amp;gt; array(&lt;br /&gt;
           'mail',&lt;br /&gt;
           'cn',&lt;br /&gt;
        ),&lt;br /&gt;
        'name_field' =&amp;gt; 'cn',&lt;br /&gt;
        'email_field' =&amp;gt; 'mail',&lt;br /&gt;
        'surname_field' =&amp;gt; 'sn',&lt;br /&gt;
        'firstname_field' =&amp;gt; 'givenName',&lt;br /&gt;
        //Можно добавить немного дополнительной информации в адресной книге&lt;br /&gt;
        'organization_field'     =&amp;gt; 'company',&lt;br /&gt;
        'jobtitle_field'    =&amp;gt; 'title',&lt;br /&gt;
        'department_field'   =&amp;gt; 'department',&lt;br /&gt;
        //Порядок сортировки&lt;br /&gt;
        'sort' =&amp;gt; 'sn',&lt;br /&gt;
        'scope' =&amp;gt; 'sub', //Выполнять поиск по всему каталогу LDAP // search mode: sub|base|list&lt;br /&gt;
        'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectClass=user)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        //'filter' =&amp;gt; '(&amp;amp;(mail=*)(|(&amp;amp;(objectcategory=person)(!(objectClass=computer)))(objectClass=group)))',&lt;br /&gt;
        'global_search' =&amp;gt; true,&lt;br /&gt;
        'fuzzy_search' =&amp;gt; true&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// LDAP&lt;br /&gt;
// ----------------------------------&lt;br /&gt;
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache'.&lt;br /&gt;
$config['ldap_cache'] = 'db';&lt;br /&gt;
// Lifetime of LDAP cache. Possible units: s, m, h, d, w&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Go to Roundcube web-interface - Contacts&lt;br /&gt;
&lt;br /&gt;
You will see new section &amp;quot;ALF&amp;quot; and contact in there&lt;br /&gt;
&lt;br /&gt;
You can debug if something goes wrong:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /usr/share/nginx/html/webmail/logs/errors.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Amavis blocks some inbound emails addresses with error &amp;quot;'''Blocked BAD-HEADER-0'''&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
https://sourceforge.net/p/amavis/mailman/message/16755074/&lt;br /&gt;
&lt;br /&gt;
https://www.habibza.in/amavisd-whitelist-or-allowed-mail-from-blocked-bad-header/&lt;br /&gt;
&lt;br /&gt;
https://forum.iredmail.org/topic4681-solved-how-to-bypass-amavisd-for-some-senders.html&lt;br /&gt;
&lt;br /&gt;
=== Solution 1 ===&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 $final_bad_header_destiny = D_PASS;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ??? Solution 2. DOESN'T WORK ??? ===&lt;br /&gt;
Create whitelist of emails or even domains, which you want to allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/whitelist-badheader&amp;lt;/code&amp;gt;&lt;br /&gt;
 user@somedomain.com&lt;br /&gt;
 somedomain.com&lt;br /&gt;
Edit amavis config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/amavisd/amavisd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 # white list, which will allow inbound emails with BAD-HEADER-0&lt;br /&gt;
 @bypass_header_checks_maps = (&lt;br /&gt;
    read_hash(&amp;quot;/etc/amavisd/whitelist-badheader&amp;quot;),&lt;br /&gt;
 );&lt;br /&gt;
 ...&lt;br /&gt;
Restart services&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart amavisd postfix&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Logging users' action (e.g. copying, erasing users' emails), which users perform via any IMAP/POP3 mail clients, via Dovecot MDA logging ==&lt;br /&gt;
Enable mail plugins in Dovecot config&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/dovecot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 mail_plugins = $mail_plugins mail_log notify&lt;br /&gt;
 ...&lt;br /&gt;
Enable plugins '''mail_log_events, mail_log_fields'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/dovecot/conf.d/90-plugin.conf&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
plugin {&lt;br /&gt;
  #setting_name = value&lt;br /&gt;
&lt;br /&gt;
  # Events to log. Defined in src/plugins/mail-log/mail-log-plugin.c - also available: flag_change save mailbox_create&lt;br /&gt;
  # autoexpunge is included in expunge&lt;br /&gt;
  mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename&lt;br /&gt;
&lt;br /&gt;
  # Also available: Defined in src/plugins/mail-log/mail-log-plugin.c - flags vsize from subject&lt;br /&gt;
  mail_log_fields = uid box msgid from subject&lt;br /&gt;
&lt;br /&gt;
  # Don't log fields that require opening the email (v2.2.28+).&lt;br /&gt;
  #mail_log_cached_only = yes&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Restart dovecot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make some actions in the user's mailbox (e.g. move email to the Trash and then delete it completely)&lt;br /&gt;
&lt;br /&gt;
Now you can look in the logs ('''expunge = delete''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat '''/var/log/dovecot-info.log''' | grep &amp;quot;'''Info: expunge'''\|'''Info: copy'''&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
 May 11 10:53:56 imap(admin@don661.ru)&amp;lt;259523&amp;gt;&amp;lt;aw5K9CgY6oN/AAAB&amp;gt;: Info: '''copy''' from INBOX: box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 May 11 10:54:13 imap(admin@don661.ru)&amp;lt;259531&amp;gt;&amp;lt;JGZG9SgYLKZ/AAAB&amp;gt;: Info: '''expunge''': box=Trash, uid=1, msgid=&amp;lt;7a46aa92-72e0-4d55-83a2-6932cdee4906@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
 &lt;br /&gt;
 May 11 11:08:21 pop3(admin@don661.ru)&amp;lt;259979&amp;gt;&amp;lt;Mz/SJykYIdpOhIjD&amp;gt;: Info: '''expunge''': box=INBOX, uid=10, msgid=&amp;lt;65e7897f-b08d-4f13-8655-73d08485b2f2@gmail.com&amp;gt;, from=&amp;quot;clesssalvein@gmail.com&amp;quot; &amp;lt;clesssalvein@gmail.com&amp;gt;, subject=test&lt;br /&gt;
&lt;br /&gt;
== BLOCK PARTICULAR SENDERS (EMAILS, DOMAINS) - INBOX MAIL ==&lt;br /&gt;
(ЗАБЛОКИРОВАТЬ КОНКРЕТНЫЕ ЯЩИКИ-ОТПРАВИТЕЛИ ИЛИ ДОМЕНЫ - ВХОДЯЩУЮ ПОЧТУ)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-----&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
vim /etc/postfix/header_checks&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/^From:.*baduser@example.com/ REJECT&lt;br /&gt;
&lt;br /&gt;
/^From:.*@spamdomain.com/ REJECT&lt;br /&gt;
&lt;br /&gt;
/^From:.*@scientamicron.com/ REJECT&lt;br /&gt;
&lt;br /&gt;
/^From:.*@ip-223-6.dataclub.info/ REJECT&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
/etc/postfix/main.cf&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; BLOCK SENDERS LIST&lt;br /&gt;
&lt;br /&gt;
header_checks = regexp:/etc/postfix/header_checks&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
systemctl restart postfix.service&lt;br /&gt;
&lt;br /&gt;
Send an email from the blocked user (user01@gmail.com)&lt;br /&gt;
&lt;br /&gt;
cat /var/log/postfix.log&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Mar 16 22:11:27 mail postfix/cleanup[3119]: 0D83BE1E24: reject: header From: &amp;quot;user01@gmail.com&amp;quot; &amp;lt;user01@gmail.com&amp;gt; from mail-lj1-f176.google.com[209.85.208.176]; from=&amp;lt;user01@gmail.com&amp;gt; to=&amp;lt;call.center2@lada-tambovavtocity.ru&amp;gt; proto=ESMTP helo=&amp;lt;mail-lj1-f176.google.com&amp;gt;: 5.7.1 message content rejected&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
= Errors =&lt;br /&gt;
&lt;br /&gt;
=== Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat ./dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
        ...&lt;br /&gt;
        Feb 16 16:18:17 lda(cless@yourdomain.ru)&amp;lt;2571&amp;gt;&amp;lt;B0HqGhkt7mMLCgAA1XGFgw&amp;gt;: Error: User cless@yourdomain.ru doesn't have home dir set, disabling duplicate database&lt;br /&gt;
        ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-mail.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    mail_location = maildir:/home/mail/%d/%u/&lt;br /&gt;
    mail_home = /home/mail/%d/%u&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem ===&lt;br /&gt;
ERROR&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/dovecot.log&amp;lt;/code&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         Feb 27 00:56:40 imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssl_dh=&amp;lt;/path/to/dh.pem&lt;br /&gt;
         ...&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/dovecot/conf.d/10-ssl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ssl_dh = &amp;lt;/etc/dovecot/dh.pem&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart dovecot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Error: '''&amp;quot;Connection error (failed to reach the server) roundcube&amp;quot;''' at Roundcube Webmail web-interface during sending a message, if the size of the message is 10MB+ (a huge sign with pictures, for example) ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
The update from '''PHP-7.3''' to '''PHP-7.4''' has solved the issue.&lt;br /&gt;
&lt;br /&gt;
=== ERROR: PHP-ImageMagick module creates huge files, which use all disk space in / partition ===&lt;br /&gt;
https://github.com/ImageMagick/ImageMagick/issues/395&lt;br /&gt;
&lt;br /&gt;
PHP-ImageMagick module creates huge files, which use all disk space in / partition&lt;br /&gt;
 /tmp/systemd-private-78b2a42fd129405aa1e735b61bf8fb72-php-fpm.service-Icx1Wg/tmp/magick-*&lt;br /&gt;
??? SOLUTION ???&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 1:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/ImageMagick-7/policy.xml&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;policymap&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;memory&amp;quot; value=&amp;quot;2GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;resource&amp;quot; name=&amp;quot;disk&amp;quot; value=&amp;quot;1GiB&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;policy domain=&amp;quot;cache&amp;quot; name=&amp;quot;synchronize&amp;quot; value=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
 &amp;lt;/policymap&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart nginx php-fpm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Variant 2:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the following cron jobs for automatic cleanup. The first 2 lines will clean up old files based on their age.&lt;br /&gt;
&lt;br /&gt;
In one case this was still insufficient, since a user was uploading a lot of very large images within a short time, causing the /tmp folder to fill up very quickly. Therefore the last line removes images which are at a certain filesize treshold. I picked a treshold just below the usual size of the magick-* files (see list in first post).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;crontab -e&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Temporary solution to prevent /tmp from being filled with 200+ MB ImageMagick files&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'magick-*' -delete&lt;br /&gt;
 0 * * * * find /tmp/ -mmin +119 -type f -name 'php*' -delete&lt;br /&gt;
 */5 * * * * find /tmp/ -mmin +5 -type f -name 'magick-*' -size +200M -delete&lt;br /&gt;
&lt;br /&gt;
=== Error in '''Roundcube Webmail during the searching for emails''': '''(Server error)''' ===&lt;br /&gt;
SOLUTION&lt;br /&gt;
&lt;br /&gt;
It's necessary to Install Full-text search.&lt;br /&gt;
&lt;br /&gt;
Proceed to the according section of this manual: '''Fts-xapian'''.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1924</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1924"/>
		<updated>2025-02-18T07:57:37Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 dhcp-option DNS 10.54.100.227&lt;br /&gt;
 dhcp-option DNS 10.54.100.228&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 cd ./easy-rsa&lt;br /&gt;
 ./easyrsa gen-req ${clientName} nopass&lt;br /&gt;
 ./easyrsa sign-req client ${clientName}&lt;br /&gt;
 cd ..&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
=== Статус подключенных клиентов ===&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/openvpn/openvpn-status.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1923</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1923"/>
		<updated>2025-02-17T18:06:49Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 cd ./easy-rsa&lt;br /&gt;
 ./easyrsa gen-req ${clientName} nopass&lt;br /&gt;
 ./easyrsa sign-req client ${clientName}&lt;br /&gt;
 cd ..&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
=== Статус подключенных клиентов ===&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/openvpn/openvpn-status.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1922</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1922"/>
		<updated>2025-02-17T06:38:25Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
=== Статус подключенных клиентов ===&lt;br /&gt;
&amp;lt;code&amp;gt;cat /var/log/openvpn/openvpn-status.log&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1921</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1921"/>
		<updated>2025-02-14T21:19:10Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== Отзыв сертификата клиента ==&lt;br /&gt;
https://server-gu.ru/easy-rsa-revoke-certificate/&lt;br /&gt;
&lt;br /&gt;
=== Создание клиента с сертификатом ===&lt;br /&gt;
Создаем клиента '''test01''' с доступом по сертификату&lt;br /&gt;
&lt;br /&gt;
Проверяем что он подключается к серверу&lt;br /&gt;
&lt;br /&gt;
=== Отзыв сертификата клиента ===&lt;br /&gt;
Переходим в директорию easy-rsa&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отзываем сертификат&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa revoke test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Генерируем БД с отозванными сертификатами, копируем crl.pem в /etc/openvpn, назначаем права чтения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-crl &amp;amp;&amp;amp; cp pki/crl.pem ../ &amp;amp;&amp;amp; chmod ugo+r ../crl.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Добавляем в конфиг&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 ; база отозванных сертификатов&lt;br /&gt;
 crl-verify crl.pem&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Проверяем что '''test01''' НЕ может подключиться к серверу&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1920</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1920"/>
		<updated>2025-02-14T20:12:55Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
 &lt;br /&gt;
 ; Возможность нескольких подключений под одним клиентом с одним сертификатом&lt;br /&gt;
 ; Иначе одному клиенту с одним сертификатом при попытке подключений&lt;br /&gt;
 ; с разных устройств будет выдаватьcя один и тот же IP&lt;br /&gt;
 duplicate-cn&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1919</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1919"/>
		<updated>2025-02-14T19:59:39Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
Шаблон конфигурации клиента&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/client.template&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vim /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 &lt;br /&gt;
 # Default Variable Declarations&lt;br /&gt;
 mkdir=`which mkdir`&lt;br /&gt;
 echo=`which echo`&lt;br /&gt;
 cat=`which cat`&lt;br /&gt;
 printf=`which printf`&lt;br /&gt;
 &lt;br /&gt;
 clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
 templateClientConfFile=&amp;quot;/etc/openvpn/client.template&amp;quot;&lt;br /&gt;
 caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # create conf dir&lt;br /&gt;
 if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
    ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Ask for a new Client name&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
 read clientName&lt;br /&gt;
 &lt;br /&gt;
 # declare client files paths&lt;br /&gt;
 clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
 clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
 clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # template to conf file&lt;br /&gt;
 ${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # ca to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # line break&lt;br /&gt;
 ${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # crt to conf file&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 ${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
 &lt;br /&gt;
 # show info about output conf file&lt;br /&gt;
 ${echo} $'\r'&lt;br /&gt;
 ${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x /etc/openvpn/makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Генерируем конфигурацию клиента (имя клиента такое же как при создании пользователя через easy-rsa - в нашем случае: client1)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./makeClientConf.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Готовая конфигурация клиента будет создана в директории '''/etc/openvpn/clientsConf'''&lt;br /&gt;
&lt;br /&gt;
Передаем её клиенту по зашифрованному каналу (она содержит приватный ключ)&lt;br /&gt;
&lt;br /&gt;
Клиент загружает конфигурацию в '''OpenVPN-Connect''' (на нём тестировалось и работает)&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1918</id>
		<title>OpenVPN. Centos 7. Сервер + клиенты</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=OpenVPN._Centos_7._%D0%A1%D0%B5%D1%80%D0%B2%D0%B5%D1%80_%2B_%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B&amp;diff=1918"/>
		<updated>2025-02-14T18:26:44Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OpenVPN сервер ==&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации сервера ===&lt;br /&gt;
Разрешим пересылку пакетов между интерфейсами&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sysctl.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 net.ipv4.ip_forward = 1&lt;br /&gt;
 ...&lt;br /&gt;
Сохраним изменения и выполним:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sysctl -p&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если OpenVPN сервер находится в локальной сети за маршрутизатором - на маршрутизаторе 192.168.199.1 пробросим внешний порт 11194 на внутренний порт 1194 нашего ovpn-сервера&lt;br /&gt;
&lt;br /&gt;
// 1194 с внешки у ростелеком, например, не работает, возможно блокировка&lt;br /&gt;
&lt;br /&gt;
Этот пункт делаем только если интерфейс Tun, и на локальном интерфейсе openvpn-сервера не настроен NAT&lt;br /&gt;
&lt;br /&gt;
На маршрутизаторе 192.168.199.1 добавим маршрут до сети впн (10.10.10.0/24)через ip-адрес нашего овпн-сервера (centos), чтобы компы из сети 192.168.199.0/24 за маршрутизатором 192.168.199.1, ходя на него (или отвечая на запрос) знали через что идти до сети впн клиентов (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
ЧЕРЕЗ IP-АДРЕС НАШЕГО ОВПН-СЕРВЕРА (CENTOS), ЧТОБЫ КОМПЫ ИЗ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
ХОДЯ НА НЕГО (ИЛИ ОТВЕЧАЯ НА ЗАПРОС) ЗНАЛИ ЧЕРЕЗ ЧТО ИДТИ ДО СЕТИ ВПН КЛИЕНТОВ (10.10.10.0/24)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y epel-release&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y openvpn easy-rsa –y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /etc/openvpn/keys&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p /var/log/openvpn&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -rf /usr/share/easy-rsa/3.0.8/* /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим файл с переменными для создания сертификатов&lt;br /&gt;
&lt;br /&gt;
'''''KEY_NAME''''': Следует указать значение server, иначе придется вносить изменения в конфигурационные файлы, в которых упоминается server.key и server.crt.&lt;br /&gt;
&lt;br /&gt;
'''''KEY_CN''''': здесь надо написать домен или поддомен, который указывает на ваш сервер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/easy-rsa/vars&amp;lt;/code&amp;gt;&lt;br /&gt;
 export KEY_COUNTRY=&amp;quot;RU&amp;quot;&lt;br /&gt;
 export KEY_PROVINCE=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_CITY=&amp;quot;Moscow&amp;quot;&lt;br /&gt;
 export KEY_ORG=&amp;quot;OOO Romashka&amp;quot;&lt;br /&gt;
 export KEY_EMAIL=&amp;quot;ivan@example.com&amp;quot;&lt;br /&gt;
 export KEY_OU=&amp;quot;Community&amp;quot;&lt;br /&gt;
 export KEY_NAME=&amp;quot;server&amp;quot;&lt;br /&gt;
 export KEY_CN=openvpn.example.com&lt;br /&gt;
&amp;lt;code&amp;gt;cp /etc/openvpn/easy-rsa/openssl-easyrsa.cnf /etc/openvpn/easy-rsa/openssl.cnf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cd /etc/openvpn/easy-rsa&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;source ./vars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создадим удостоверяющий центр CA&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa init-pki&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa build-ca&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вводим пароль&lt;br /&gt;
 Enter PEM pass phrase:&lt;br /&gt;
 Verifying - Enter PEM pass phrase:&lt;br /&gt;
Имя сервера&lt;br /&gt;
  Common Name (eg: your user, host, or server name) [Easy-RSA CA]: serveradmin.ru&lt;br /&gt;
Не забудьте указанный при запросе пароль.&lt;br /&gt;
&lt;br /&gt;
Его нужно будет вводить каждый раз при создании нового сертификата openvpn.&lt;br /&gt;
&lt;br /&gt;
Мы получили 2 ключа:&lt;br /&gt;
&lt;br /&gt;
Ключ секретный, его нужно оставить на сервере и никому не отдавать&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/ca.key&lt;br /&gt;
Ключ открытый, его мы будем вместе с пользовательскими сертификатами передавать клиентам.&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/ca.crt&lt;br /&gt;
Создаем запрос сертификата для сервера без пароля с помощью опции nopass, иначе придется вводить пароль с консоли при каждом запуске сервера:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req server nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сгенерированные файлы&lt;br /&gt;
     req: /etc/openvpn/easy-rsa/pki/reqs/server.req&lt;br /&gt;
     key: /etc/openvpn/easy-rsa/pki/private/server.key&lt;br /&gt;
Подписываем запрос на получение сертификата у нашего CA:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa --days=3650 sign-req server server&amp;lt;/code&amp;gt;&lt;br /&gt;
  Request subject, to be signed as a server certificate for 3650 days:&lt;br /&gt;
В процессе работы скрипта вводим пароль от CA, который указывали раньше и отвечаем на вопрос yes.&lt;br /&gt;
&lt;br /&gt;
Мы получили подписанный удостоверяющим центром сертификат для сервера&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/server.crt&lt;br /&gt;
Генерируем ключ Диффи-Хелмана&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-dh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Файл dh сертификата&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/dh.pem&lt;br /&gt;
Копируем в папку /etc/openvpn все необходимые для работы openvpn сервера ключи:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/ca.crt /etc/openvpn/keys/ca.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/dh.pem /etc/openvpn/keys/dh.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/issued/server.crt /etc/openvpn/keys/server.crt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp pki/private/server.key /etc/openvpn/keys/server.key&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конфигурация сервера    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/openvpn/server.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 ; интерфейс, на котором работает ovpn, если не указано - то работает на всех&lt;br /&gt;
 local 192.168.199.225&lt;br /&gt;
 &lt;br /&gt;
 ; настройки сети&lt;br /&gt;
 port 1194&lt;br /&gt;
 proto udp&lt;br /&gt;
 dev tun&lt;br /&gt;
 &lt;br /&gt;
 ; пути до ключей&lt;br /&gt;
 ca /etc/openvpn/keys/ca.crt&lt;br /&gt;
 cert /etc/openvpn/keys/server.crt&lt;br /&gt;
 key /etc/openvpn/keys/server.key&lt;br /&gt;
 dh /etc/openvpn/keys/dh.pem&lt;br /&gt;
 &lt;br /&gt;
 ; настройки для статического адреса сервера в туннелях впн&lt;br /&gt;
 mode server&lt;br /&gt;
 tls-server&lt;br /&gt;
 &lt;br /&gt;
 ; статический адрес туннеля сервера&lt;br /&gt;
 ifconfig 10.10.10.1 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; пул адресов клиентов&lt;br /&gt;
 ifconfig-pool 10.10.10.100 10.10.10.200&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне сервера до сети клиентов&lt;br /&gt;
 route 10.10.10.0 255.255.255.0&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента (клиенту необходимы админские права для создания маршрутов)&lt;br /&gt;
 push &amp;quot;route 10.10.10.1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; маршрут на стороне клиента до хостов в локальной сети сервера&lt;br /&gt;
 push &amp;quot;route 192.168.199.0 255.255.255.0&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; инфо о подключенных клиентах&lt;br /&gt;
 ifconfig-pool-persist /etc/openvpn/ipp.txt&lt;br /&gt;
 &lt;br /&gt;
 ; директория с настройками для каждого клиента&lt;br /&gt;
 ;client-config-dir /etc/openvpn_tun/ccd&lt;br /&gt;
 &lt;br /&gt;
 ; клиенты могут видеть друг друга&lt;br /&gt;
 client-to-client&lt;br /&gt;
 &lt;br /&gt;
 ; каждые 10 секунд посылать ping на удаленный хост, и, если за 120 секунд не было получено ни одного пакета — то перезапускать туннель&lt;br /&gt;
 keepalive 10 120&lt;br /&gt;
 max-clients 100&lt;br /&gt;
 user nobody&lt;br /&gt;
 group nobody&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 &lt;br /&gt;
 ; алгоритм шифрования&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 ; Не писать в логи повторяющиеся сообщения:&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 &lt;br /&gt;
 ; Уровень подробности логов (от 0 до 9)&lt;br /&gt;
 ;verb 3&lt;br /&gt;
 &lt;br /&gt;
 ; логи&lt;br /&gt;
 status /var/log/openvpn/openvpn-status.log&lt;br /&gt;
 log /var/log/openvpn/openvpn.log&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start openvpn@server&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ПРИ ЗАПРОСЕ С ВПН-КЛИЕНТА (НАПРИМЕР) 10.10.10.202, К ХОСТУ ЛОКАЛЬНОЙ СЕТИ 192.168.199.0/24 ЗА МАРШРУТИЗАТОРОМ,&lt;br /&gt;
&lt;br /&gt;
НАПРИМЕР 192.168.199.16, ТРАФИК ИДЕТ ЧЕРЕЗ ВПН СЕРВЕР (Tun0 интерфейс) 10.10.10.1, ПОТОМ К ХОСТУ 192.168.199.16,&lt;br /&gt;
&lt;br /&gt;
НО ХОСТ 192.168.199.16 НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24,&lt;br /&gt;
&lt;br /&gt;
ПОЭТОМУ ОБРАТНЫЙ ТРАФИК ПОЙДЕТ ЧЕРЕЗ ДЕФОЛТНЫЙ ШЛЮЗ, ТО ЕСТЬ МАРШРУТИЗАТОР 192.168.199.1,&lt;br /&gt;
&lt;br /&gt;
НО ОН ТОЖЕ НЕ ЗНАЕТ О СУЩЕСТВОВАНИИ СЕТИ 10.10.10.0/24, ПОЭТОМУ ПИНГА ОТ 10.10.10.202 до 192.168.199.16 НЕ БУДЕТ.&lt;br /&gt;
&lt;br /&gt;
ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ ЕСТЬ 3 ВАРИАНТА:&lt;br /&gt;
&lt;br /&gt;
'''1. На маршрутизаторе 192.168.199.1 прописать маршрут до 10.10.10.0/24 через IP openvpn-сервера (192.168.199.225)'''&lt;br /&gt;
&lt;br /&gt;
Тогда трафик от клиента дойдя по дефолтному шлюзу завернется на 192.168.199.225, а оттуда к клиенту 10.10.10.202&lt;br /&gt;
&lt;br /&gt;
'''2. Прописать NAT-маскарадинг на локальном интерфейсе (ens32)'''&lt;br /&gt;
&lt;br /&gt;
openvpn-сервера (192.168.199.225) от сети 10.10.10.0/24:&lt;br /&gt;
&lt;br /&gt;
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o ens32 -j MASQUERADE&lt;br /&gt;
&lt;br /&gt;
// установим службу чтобы сохранить правило после перезагрузки&lt;br /&gt;
&lt;br /&gt;
systemctl disable firewalld&lt;br /&gt;
&lt;br /&gt;
yum install iptables-services&lt;br /&gt;
&lt;br /&gt;
systemctl enable iptables&lt;br /&gt;
&lt;br /&gt;
service iptables save&lt;br /&gt;
&lt;br /&gt;
В таком случае весь трафик от впн-клиентов сети 10.10.10.0/24&lt;br /&gt;
&lt;br /&gt;
будет натится на локальном интерфейсе openvpn-сервера&lt;br /&gt;
&lt;br /&gt;
'''3. !!! НЕ ТЕСТИРОВАЛ !!!'''&lt;br /&gt;
&lt;br /&gt;
Для этого способа необходимо настраивать openvpn сервер&lt;br /&gt;
&lt;br /&gt;
с использованием интерфейса 2-го (канального) уровня - TAP,&lt;br /&gt;
&lt;br /&gt;
так как TUN это интерфейс 3-го (сетевого) уровня и собираться в бридж не может.&lt;br /&gt;
&lt;br /&gt;
Далее надо объединить физический интерфейс ens32 с интерфейсом Tap0 в бридж.&lt;br /&gt;
&lt;br /&gt;
Бриджу назначаем адрес 192.168.199.225 (какой был у ens32).&lt;br /&gt;
&lt;br /&gt;
Изменения в конфиге openvpn-сервера будут выглядеть примерно так:&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
dev tap0&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.225 255.255.255.0 - адрес и маска бриджа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;;&amp;lt;/nowiki&amp;gt; 192.168.168.100 192.168.168.200 - пул адресов, которые будут выдаваться клиентам&lt;br /&gt;
&lt;br /&gt;
server-bridge 192.168.168.225 255.255.255.0 192.168.168.100 192.168.168.200&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Таким образом впн-клиенты сразу будут оказываться в диапазоне сети за маршрутизатором&lt;br /&gt;
&lt;br /&gt;
и общаться с хостами на уровне коммутации.&lt;br /&gt;
&lt;br /&gt;
=== Настройка конфигурации клиентов ===&lt;br /&gt;
&lt;br /&gt;
==== Вариант 1. Создание конфигураций вручную ====&lt;br /&gt;
Создадим ключ для клиента openvpn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa gen-req client1 nopass&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./easyrsa sign-req client client1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура аналогична созданию сертификата для сервера. Так же вводим пароль, отвечаем yes.&lt;br /&gt;
&lt;br /&gt;
В результате получаем подписанный сертификат клиента:&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/issued/client1.crt&lt;br /&gt;
&lt;br /&gt;
     /etc/openvpn/easy-rsa/pki/private/client1.key&lt;br /&gt;
Клиенту нужно будет передать следующий набор файлов:&lt;br /&gt;
     client.crt&lt;br /&gt;
     client.key&lt;br /&gt;
     ca.crt&lt;br /&gt;
&lt;br /&gt;
==== Вариант 2. Генерируем файл-конфигурацию клиента со встроенными ключами ====&lt;br /&gt;
'''!!! НЕ ТЕСТИРОВАЛ !!! ДОДЕЛАТЬ !!!'''&lt;br /&gt;
&lt;br /&gt;
Скрипт генерации конфигурации&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano ./makeClientConf.sh&amp;lt;/code&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Default Variable Declarations&lt;br /&gt;
mkdir=`which mkdir`&lt;br /&gt;
echo=`which echo`&lt;br /&gt;
cat=`which cat`&lt;br /&gt;
printf=`which printf`&lt;br /&gt;
clientsConfDir=&amp;quot;/etc/openvpn/clientsConf&amp;quot;&lt;br /&gt;
templateClientConfFile=&amp;quot;client.template&amp;quot;&lt;br /&gt;
caFile=&amp;quot;/etc/openvpn/keys/ca.crt&amp;quot;&lt;br /&gt;
# create conf dir&lt;br /&gt;
if ! [ -d &amp;quot;${clientsConfDir}/&amp;quot; ]; then&lt;br /&gt;
   ${mkdir} -p ${clientsConfDir}&lt;br /&gt;
fi&lt;br /&gt;
# Ask for a new Client name&lt;br /&gt;
${echo} $'\r'&lt;br /&gt;
${echo} &amp;quot;Please enter new Client Name:&amp;quot;&lt;br /&gt;
read clientName&lt;br /&gt;
# declare client files paths&lt;br /&gt;
clientConfFile=&amp;quot;${clientName}-config.ovpn&amp;quot;&lt;br /&gt;
clientCrtFile=&amp;quot;/etc/openvpn/easy-rsa/pki/issued/${clientName}.crt&amp;quot;&lt;br /&gt;
clientKeyFile=&amp;quot;/etc/openvpn/easy-rsa/pki/private/${clientName}.key&amp;quot;&lt;br /&gt;
# line break&lt;br /&gt;
${printf} $'\n\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# template to conf file&lt;br /&gt;
${cat} ${templateClientConfFile} &amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# ca to conf file&lt;br /&gt;
${echo} &amp;quot;&amp;lt;ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${cat} ${caFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${echo} &amp;quot;&amp;lt;/ca&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# line break&lt;br /&gt;
${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# crt to conf file&lt;br /&gt;
${echo} &amp;quot;&amp;lt;cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${cat} ${clientCrtFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${echo} &amp;quot;&amp;lt;/cert&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# line break&lt;br /&gt;
${printf} $'\n' &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# crt to conf file&lt;br /&gt;
${echo} &amp;quot;&amp;lt;key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${cat} ${clientKeyFile} &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
${echo} &amp;quot;&amp;lt;/key&amp;gt;&amp;quot; &amp;gt;&amp;gt; ${clientsConfDir}/${clientConfFile}&lt;br /&gt;
# show info about output conf file&lt;br /&gt;
${echo} $'\r'&lt;br /&gt;
${echo} &amp;quot;Client's \&amp;quot;${clientName}\&amp;quot; Configuration: ${clientsConfDir}/${clientConfFile}&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenVPN клиенты ==&lt;br /&gt;
&lt;br /&gt;
=== OpenVPN клиент на Windows ===&lt;br /&gt;
Содержимое файлов client.crt, client.key, ca.crt помещаем в файл client1.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;client1.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 client&lt;br /&gt;
 dev tun&lt;br /&gt;
 proto udp&lt;br /&gt;
 remote 176.192.22.222 11194&lt;br /&gt;
 resolv-retry infinite&lt;br /&gt;
 nobind&lt;br /&gt;
 persist-key&lt;br /&gt;
 persist-tun&lt;br /&gt;
 mute-replay-warnings&lt;br /&gt;
 ;comp-lzo&lt;br /&gt;
 verb 3&lt;br /&gt;
 ;mute 20&lt;br /&gt;
 remote-cert-tls server&lt;br /&gt;
 cipher AES-256-CBC&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;ca&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/ca&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;cert&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/cert&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;key&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 &amp;lt;/key&amp;gt;&lt;br /&gt;
Устанавливаем openvpn-install-2.4.6-I602.exe в режиме службы&lt;br /&gt;
&lt;br /&gt;
Запускаем openvpn client gui&lt;br /&gt;
&lt;br /&gt;
Импортируем созданные на сервере файл client1.conf&lt;br /&gt;
&lt;br /&gt;
Конфигурация после импорта появится в C:\Users\admin\OpenVPN\config\&lt;br /&gt;
&lt;br /&gt;
Подключаемся к серверу&lt;br /&gt;
[[Категория:OpenVPN]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=LVM._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_LV_%D0%B7%D0%B0_%D1%81%D1%87%D0%B5%D1%82_%D1%81%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BC%D0%B5%D1%81%D1%82%D0%B0_%D0%BD%D0%B0_%D1%84%D0%B8%D0%B7%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%B4%D0%B8%D1%81%D0%BA%D0%B5&amp;diff=1917</id>
		<title>LVM. Расширение объема раздела LV за счет свободного места на физическом диске</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=LVM._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_LV_%D0%B7%D0%B0_%D1%81%D1%87%D0%B5%D1%82_%D1%81%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BC%D0%B5%D1%81%D1%82%D0%B0_%D0%BD%D0%B0_%D1%84%D0%B8%D0%B7%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%BC_%D0%B4%D0%B8%D1%81%D0%BA%D0%B5&amp;diff=1917"/>
		<updated>2025-01-07T09:31:52Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Описание=&lt;br /&gt;
В данной инструкции мы увеличиваем '''системный''' раздел '''root''', но она также подойдет и для увеличения '''НЕсистемного''' раздела.&lt;br /&gt;
&lt;br /&gt;
= Расширение =&lt;br /&gt;
&lt;br /&gt;
== '''Вариант 1'''. Простой. Все действия производим онлайн в рабочей системе. БЕЗ удаления раздела '''root'''. ==&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''EXT4''' ===&lt;br /&gt;
Сначала убедимся что на нашем физическом диске есть свободная от разделов область (дополнительный незанятый разделами объем).&lt;br /&gt;
&lt;br /&gt;
Или, если у нас виртуальная машина - сначала увеличиваем объем диска в ВМ.&lt;br /&gt;
&lt;br /&gt;
Далее смотрим информацию о физическом диске и разделах. Должны увидеть что объем физического диска имеет необходимый объем для расширения (или что общий объем диска увеличился, если мы увеличили его в ВМ гипервизора).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fdisk -l&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что изначальный объем раздела '''LV''' '''root''' - '''21'''G, а свободного места '''- 86'''M&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/mapper/almalinux_alma-root   '''21'''G   20G   '''86'''M  99% /&lt;br /&gt;
Если мы посмотрим на '''PV''', то увидим что свободного места для расширения на нем нет, несмотря на то, что физически диск имеет свободную область (или что мы вручную увеличили объем физического диска в ВМ).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvs&amp;lt;/code&amp;gt;&lt;br /&gt;
 PV         VG             Fmt  Attr PSize   PFree&lt;br /&gt;
 /dev/sda2  almalinux_alma lvm2 a--  &amp;lt;21.00g    0&lt;br /&gt;
Так и должно быть, идем далее.&lt;br /&gt;
&lt;br /&gt;
Для начала необходимо расширить логический раздел /dev/sdb'''X''' для '''root''' на физическом диске (например, если на диске было свободное от разделов место или мы прибавили место к виртуальному диску в виртуальной машине (если машина в гипервизоре)). Иначе '''pvs''' и '''vgs''' будут показывать что размер раздела не увеличился и неоткуда брать место для создания '''LV''' большего объема.&lt;br /&gt;
&lt;br /&gt;
==== Если PV создан на партиции /dev/sdaX ====&lt;br /&gt;
&lt;br /&gt;
===== Интерактивное расширение через '''parted''' =====&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sda: '''4295'''MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
  2      1075MB  4295MB  4294MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 2 '''4296'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location '''4296''' is outside of the device /dev/sdb.&lt;br /&gt;
Расширяем объем раздела до полного объема физического диска - '''4295'''MB&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 2 '''4295'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sda: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1075MB  1074MB  primary  ext4         boot&lt;br /&gt;
  2      1075MB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== НЕинтерактивное расширение через '''growpart''' =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''-N -''' Можно предварительно запустить в холостом режиме с данным ключом&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3''' - номер раздела (/dev/sdb'''3''')&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;growpart -v /dev/sda 3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Расширяем PV ====&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sda'''X'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Если PV создан на голом диске /dev/sda =====&lt;br /&gt;
Просто расширяем PV&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sde&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Идем далее.&lt;br /&gt;
&lt;br /&gt;
Смотрим что есть дополнительный незанятый объем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   PV         VG             Fmt  Attr PSize   PFree&lt;br /&gt;
   /dev/sda2  almalinux_alma lvm2 a--  &amp;lt;31.00g '''8.00'''g&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG             #PV #LV #SN Attr   VSize   VFree&lt;br /&gt;
   almalinux_alma   1   2   0 wz--n- &amp;lt;31.00g '''8.00'''g&lt;br /&gt;
Расширяем '''LV''' на весь свободный объем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvresize /dev/almalinux_alma/root /dev/sda2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
Расширяем раздел и одновременно расширяем ФС (только если данный раздел отформатирован в '''XFS'''), используя ключ &amp;quot;'''-r'''&amp;quot; (используется &amp;lt;code&amp;gt;xfs_growfs&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
В данном случае после расширения раздела нет необходимости использовать &amp;lt;code&amp;gt;xfs_growfs&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение на весь объем&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r /dev/almalinux_alma/root /dev/sda2&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение на +определенный объем&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r -L +5G /dev/vg00/root /dev/vda2&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Расширение до итогового объема 20GB&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvresize -r -L 20G /dev/vg00/root /dev/vda2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ'''&lt;br /&gt;
&lt;br /&gt;
Расширяем '''LV''' на конкретное значение в '''GB'''&amp;lt;blockquote&amp;gt;'''-A n''' - Turn off auto-backup of metadata (see man page for details and cautions) which should prevent having to write to /etc/lvm You can then run '''vgcfgbackup''' after you have been successful in resizing. Необходимая опция если на расширяемом разделе осталось 0 свободного места.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;lvextend -A n -L +5G /dev/almalinux_alma/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что объем '''LV''' увеличился&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG             Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   root almalinux_alma -wi-ao---- '''28.59'''g&lt;br /&gt;
   swap almalinux_alma -wi-ao----  2.40g&lt;br /&gt;
Расширяем ФС '''EXT4''' на '''LV''' '''root''' на '''весь доступный объем'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resize2fs /dev/almalinux_alma/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ'''&lt;br /&gt;
&lt;br /&gt;
Если расширяемый раздел LV имеет ФС '''XFS'''&amp;lt;blockquote&amp;gt;Указываем именно директорию с примонтированным расширенным разделом ('''/''' в данном случае, или, например, '''/mnt/d1''', если расширяли не системный диск)&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;xfs_growfs -d /&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим что общий объем раздела '''root''' и объем свободного места увеличился&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
 Filesystem                       Size  Used Avail Use% Mounted on&lt;br /&gt;
 /dev/mapper/almalinux_alma-root   '''29'''G   20G  '''7.7G'''  72% /&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
== '''Вариант 2'''. Сложный. Увеличение раздела через удаление текущего раздела и создание нового увеличенного раздела. (Лучше использовать '''Вариант 1''' как более простой, без удаления раздела.) ==&lt;br /&gt;
Грузимся с загрузочного LIVE дистрибутива Linux. Предпочтительно с '''SystemRescueCD.''' Все действия производим в LIVE системе '''SystemRescueCD'''. В ней имеются необходимые утилиты, например, '''fsarchiver'''.&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''XFS''' ===&lt;br /&gt;
Активируем LVM разделы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vgchange -ay&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG                    Attr       '''LSize'''   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root centos_centos7-test01''' -wi-ao----  '''10.00g'''&lt;br /&gt;
Создаем директорию для монтирования системы root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем директорию для бэкапа файлов раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_backup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем раздел root в директорию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/centos_centos7-test01/root /mnt/root_lv/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем сетевую шару, на которую будем бэкапировать файлы раздела root (для этого подойдет и обычный раздел локального диска, например, подключенного через USB)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -t cifs -o username=admin,password=PassWord#1 //192.168.17.12/img/tmp/root /mnt/root_backup/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Бэкапим файлы раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;xfsdump -l 0 -L &amp;quot;root_backup&amp;quot; -M &amp;quot;root_backup&amp;quot; -f /mnt/root_backup/root_backup.img /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Демонтируем раздел root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удаляем раздел root, чтобы на его месте создать новый root увеличенного размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvremove /dev/centos_centos7-test01/root&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''СКОРЕЕ ВСЕГО ПЕРЕД СОЗДАНИЕМ НОВОГО РАЗДЕЛА LV НЕОБХОДИМО РАСШИРИТЬ ЛОГИЧЕСКИЙ РАЗДЕЛ НА ДИСКЕ'''&lt;br /&gt;
&lt;br /&gt;
'''ВОЗМОЖНО Я НЕ УЧЕЛ ЭТО ПРИ НАПИСАНИИ МАНУАЛА'''&lt;br /&gt;
&lt;br /&gt;
'''ЭТО МОЖНО СДЕЛАТЬ С ИСПОЛЬЗОВАНИЕМ ''parted'''''&lt;br /&gt;
&lt;br /&gt;
'''СМОТРИ НИЖЕ - РАСШИРЕНИЕ РАЗДЕЛА EXT4 ЭТОГО МАНУАЛА'''&lt;br /&gt;
&lt;br /&gt;
'''ДОПОЛНИТЬ ЭТОТ МАНУАЛ КОГДА БУДУ РАСШИРЯТЬ LVM С XFS'''&amp;lt;/blockquote&amp;gt;Создаем новый root увеличенного размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvcreate -Zy -L '''15G''' -n root centos_centos7-test01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG                    Attr       '''LSize'''   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root centos_centos7-test01''' -wi-a-----  '''15.00g'''&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG                    #PV #LV #SN Attr   VSize    '''VFree'''&lt;br /&gt;
   '''centos_centos7-test01'''   1   2   0 wz--n-  &amp;lt;30.00g '''&amp;lt;15.00g'''&lt;br /&gt;
Форматируем новый раздел root&amp;lt;blockquote&amp;gt;В mkfs.xfs (начиная с версии 3.2.4 xfsprogs) недавно стал использоваться по умолчанию суперблок версии 5 с множеством новых улучшений, таких как контрольные суммы метаданных CRC.&lt;br /&gt;
&lt;br /&gt;
Чтобы избежать ошибки, требуется '''&amp;quot;-m reflink=0&amp;quot;''', что отключает несовместимую поддержку копирования при записи reflink.&lt;br /&gt;
&lt;br /&gt;
Иначе при загрузке основной системы '''root''' раздел загрузится в '''RO''' режиме&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;mkfs.xfs -m reflink=0 /dev/centos_centos7-test01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем новый раздел в директорию&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount /dev/centos_centos7-test01/root /mnt/root_lv/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Восстанавливаем файлы root из сохраненного образа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;xfsrestore -f /mnt/root_backup/root_backup.img /mnt/root_lv&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Демонтируем раздел root и директорию для бэкапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;umount /mnt/root_*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отключаем подключенный '''SystemRescueCD'''&lt;br /&gt;
&lt;br /&gt;
Грузимся в основную систему&lt;br /&gt;
&lt;br /&gt;
Система должна загрузиться&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Если расширяемый раздел LV имеет ФС '''EXT4.''' ===&lt;br /&gt;
Активируем LVM разделы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;vgchange -ay&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG   Attr       '''LSize'''  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root''' vg01 -wi-ao---- '''10.00g'''&lt;br /&gt;
Создаем директорию для бэкапа раздела root в образ&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /mnt/root_backup&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Монтируем сетевую шару, на которую будем бэкапировать раздел root (для этого подойдет и обычный раздел локального диска, например, подключенного через USB)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mount -t cifs -o username=admin,password=PassWord#1 //192.168.17.12/img/tmp/root /mnt/root_backup/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем образ раздела '''root'''&amp;lt;blockquote&amp;gt;Будет создан образ '''/mnt/root_backup/root_lv.fsa'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;fsarchiver savefs /mnt/root_backup/root_lv /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
     Statistics for filesystem 0&lt;br /&gt;
     * files successfully processed:....regfiles=27662, directories=5301, symlinks=1186, hardlinks=4250, specials=23&lt;br /&gt;
     * files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0&lt;br /&gt;
Удаляем раздел '''root'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvremove /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь необходимо расширить логический раздел /dev/sdb'''X''' для '''root''' на физическом диске (например, если на диске было свободное от разделов место или мы прибавили место к виртуальному диску в виртуальной машине (если машина в гипервизоре)). Иначе '''pvs''' и '''vgs''' будут показывать что размер раздела не увеличился и неоткуда брать место для создания '''LV''' большего объема.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;parted&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: '''4295'''MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  1074MB  1073MB  primary  ext4&lt;br /&gt;
 ...&lt;br /&gt;
Система не даст расширить  раздел до объема большего, чем объем самого диска, будет ошибка:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 '''4296'''&amp;lt;/code&amp;gt;&lt;br /&gt;
 Error: The location '''4296''' is outside of the device /dev/sdb.&lt;br /&gt;
Расширяем объем раздела&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) resizepart 1 '''4295'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) print&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 Model: VMware Virtual disk (scsi)&lt;br /&gt;
 Disk /dev/sdb: 4295MB&lt;br /&gt;
 Sector size (logical/physical): 512B/512B&lt;br /&gt;
 Partition Table: msdos&lt;br /&gt;
 Disk Flags:&lt;br /&gt;
 Number  Start   End     Size    Type     File system  Flags&lt;br /&gt;
  1      1049kB  4295MB  4294MB  primary  ext4&lt;br /&gt;
                               display the version number and copyright information of GNU Parted&lt;br /&gt;
 ...          &lt;br /&gt;
Выходим из &amp;quot;parted&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;(parted) quit&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем PV&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;pvresize /dev/sdb'''X'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Создаем раздел '''root''' с увеличенным объемом&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lvcreate -Zy -L '''15G''' -n root vg01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Форматируем '''root'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkfs.ext4 /dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Восстанавливаем раздел '''root''' из сохраненного ранее образа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fsarchiver restfs /mnt/root_backup/root_lv.fsa id=0,dest=/dev/vg01/root&amp;lt;/code&amp;gt;&lt;br /&gt;
     Statistics for filesystem 0&lt;br /&gt;
     * files successfully processed:....regfiles=27662, directories=5301, symlinks=1186, hardlinks=4250, specials=23&lt;br /&gt;
     * files with errors:...............regfiles=0, directories=0, symlinks=0, hardlinks=0, specials=0&lt;br /&gt;
&amp;lt;code&amp;gt;vgs&amp;lt;/code&amp;gt;&lt;br /&gt;
   VG   #PV #LV #SN Attr   VSize   VFree&lt;br /&gt;
   vg01   1   2   0 wz--n- &amp;lt;30.00g '''15.00g'''&lt;br /&gt;
&amp;lt;code&amp;gt;lvs&amp;lt;/code&amp;gt;&lt;br /&gt;
   LV   VG   Attr       '''LSize'''  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&lt;br /&gt;
   '''root''' vg01 -wi-ao---- '''15.00g'''&lt;br /&gt;
Отключаем подключенный '''SystemRescueCD'''&lt;br /&gt;
&lt;br /&gt;
Грузимся в основную систему&lt;br /&gt;
&lt;br /&gt;
Система должна загрузиться&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
[[Категория:LVM]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1916</id>
		<title>ZFS. Расширение раздела ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1916"/>
		<updated>2025-01-05T11:06:14Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Вариант 1. Расширение ZFS раздела путем увеличения объема диска (например на виртуальной машине) =&lt;br /&gt;
Изначально имеем диск 16G&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (16G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       15.5G   544K  15.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    16.0G   544K  15.5G&lt;br /&gt;
   ...&lt;br /&gt;
Выключаем машину (обязательно, иначе будет CORRUPT партиция при просмотре через gpart)&lt;br /&gt;
&lt;br /&gt;
Добавляем объема диску до 32G&lt;br /&gt;
&lt;br /&gt;
Включаем машину&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  '''da5'''  GPT  (32G)&lt;br /&gt;
         40      2008       - free -  (1.0M)&lt;br /&gt;
       2048  33550336    '''1'''  freebsd-zfs  (16G)&lt;br /&gt;
   33552384  33556447       - free -  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем диск до максимального объема&amp;lt;blockquote&amp;gt;'''da5''' - имя диска&lt;br /&gt;
&lt;br /&gt;
'''1''' - номер партиции&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''1''' /dev/'''da5'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ''' расширяем до определенного размера:&amp;lt;blockquote&amp;gt;    '''-s size''' - Specifies  the  new  size  of the partition, in logical blocks. An SI unit suffix is allowed.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''2''' '''-s 19G''' da0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если gpart show показывает статус раздела [CORRUPT]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем ФС&amp;lt;blockquote&amp;gt;Можно включить автоматические расширение для пула, тогда не придется расширять руками:&lt;br /&gt;
&lt;br /&gt;
zpool set autoexpand=on zfspoolname&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e d101 da5p1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       31.5G   808K  31.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    32.0G   808K  31.5G        -         -     0%  0.00%      -    ONLINE&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (32G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (32G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   d101           32G    100K     32G     0%    /mnt/d101&lt;br /&gt;
   ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
= Вариант 2. Расширение ZFS раздела на шифрованном разделе GELI путем увеличения объема диска (в данном примере через расширение хард-рейда) =&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
https://genneko.github.io/playing-with-bsd/storage/expanding-zfs-on-geli/&lt;br /&gt;
&lt;br /&gt;
https://www.truenas.com/community/threads/geli-cannot-read-metadata-from-invalid-argument.93142/&lt;br /&gt;
&lt;br /&gt;
== Входные данные ==&lt;br /&gt;
- Имеем хардовый RAID5 (24ТБ) в контроллере HP dl380 G9, собранный из 3 дисков 12ТБ&lt;br /&gt;
&lt;br /&gt;
- В nas4free он определяется как /dev/da4 объемом 24ГБ и пришифрован как /dev/da4.elip1&lt;br /&gt;
&lt;br /&gt;
- На da4.elip1 собран ZFS stripe с использованием GPT - /dev/gpt/raid2&lt;br /&gt;
&lt;br /&gt;
== Задача ==&lt;br /&gt;
- Необходимо расширить хардовый RAID5 на +1 12ТБ диск (в итоге получим устройство объемом 36ТБ)&lt;br /&gt;
&lt;br /&gt;
== Процесс ==&lt;br /&gt;
!!! ОБЯЗАТЕЛЬНО ДЕЛАЕМ БЭКАП МЕТАДАННЫХ ШИФРОВАННОГО ДИСКА '''/dev/da4''' В ФАЙЛ '''da4.eli'''&lt;br /&gt;
&lt;br /&gt;
И СОХРАНЯЕМ ЭТОТ ФАЙЛ ЛОКАЛЬНО&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli backup /dev/da4 /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем хард RAID5 через утилиту в BIOS сервера путем добавления одного диска 12ТБ в массив (расширение может длиться 1-2 дня)&lt;br /&gt;
&lt;br /&gt;
Расширяем логический диск на расширенном массиве&lt;br /&gt;
&lt;br /&gt;
Грузимся в nas4free&lt;br /&gt;
&lt;br /&gt;
Копируем ранее сохраненный файл метаданных на '''nas4free''' в &amp;lt;code&amp;gt;/root/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим размер старого диска - нас интересует &amp;quot;'''provsize: 24000210141184'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli dump /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Metadata on /root/da4.eli:&lt;br /&gt;
   ...&lt;br /&gt;
     provsize: '''24000210141184'''&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем шифрованный раздел&amp;lt;blockquote&amp;gt;'''-s 24000210141184''' - старый объем диска &amp;quot;'''provsize: 24000210141184'''&amp;quot; до расширения, который мы посмотрели в файле метаданных&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;geli resize -v -s 24000210141184 /dev/da4&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Done.&lt;br /&gt;
   ...&lt;br /&gt;
В веб-интерфейсе подключаем шифрованный диск da4 с новым объемом 36ТБ, используя пароль шифрования, с которым создавали старый диск до расширения&lt;br /&gt;
&lt;br /&gt;
!!! НЕ ИСПОЛЬЗУЯ ГАЛКУ &amp;quot;INITIALIZE&amp;quot;, ИНАЧЕ УБЪЕМ РАНЕЕ ШИФРОВАННЫЙ ДИСК&amp;lt;blockquote&amp;gt;Аналог процедуры через консоль:&lt;br /&gt;
&lt;br /&gt;
'''geli attach /dev/da4'''&amp;lt;/blockquote&amp;gt;Импортируем ZFS POOL, который был ранее создан на шифрованном разделе&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool import -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим, ZFS раздел в порядке&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool status&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   pool: raid2&lt;br /&gt;
   state: ONLINE&lt;br /&gt;
   scan: none requested&lt;br /&gt;
   config:&lt;br /&gt;
         NAME         STATE     READ WRITE CKSUM&lt;br /&gt;
         raid2        ONLINE       0     0     0&lt;br /&gt;
           gpt/raid2  ONLINE       0     0     0&lt;br /&gt;
   ...&lt;br /&gt;
Но объем раздела старый, нерасширенный, так и должно быть&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              20T     88K     20T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         21T    1.5T     20T     7%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Также видим статус CORRUPT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  46875410352  da4.eli  GPT  (33T) [CORRUPT]&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240         8152           - free -  (4.0M)&lt;br /&gt;
   ...&lt;br /&gt;
Лечим раздел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.eli recovered&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240  23437713368           - free -  (11T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем партицию до максимального размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart resize -i 1 /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.elip1 resized&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  70313107416        1  freebsd-zfs  (33T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем ZFS-pool raid2&amp;lt;blockquote&amp;gt;'''raid2''' - пул ZFS&lt;br /&gt;
&lt;br /&gt;
'''/dev/gpt/raid2''' - единственный диск, который входит в пул&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e raid2 /dev/gpt/raid2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid3  32.5T  28.9T  3.59T         -    42%    88%  1.00x  ONLINE  -&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              30T     88K     30T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         32T    1.5T     30T     5%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Готово! Раздел расширен.&lt;br /&gt;
[[Категория:ZFS]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1915</id>
		<title>ZFS. Расширение раздела ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1915"/>
		<updated>2025-01-05T08:00:16Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Вариант 1. Расширение ZFS раздела путем увеличения объема диска (например на виртуальной машине) =&lt;br /&gt;
Изначально имеем диск 16G&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (16G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       15.5G   544K  15.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    16.0G   544K  15.5G&lt;br /&gt;
   ...&lt;br /&gt;
Выключаем машину (обязательно, иначе будет CORRUPT партиция при просмотре через gpart)&lt;br /&gt;
&lt;br /&gt;
Добавляем объема диску до 32G&lt;br /&gt;
&lt;br /&gt;
Включаем машину&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  '''da5'''  GPT  (32G)&lt;br /&gt;
         40      2008       - free -  (1.0M)&lt;br /&gt;
       2048  33550336    '''1'''  freebsd-zfs  (16G)&lt;br /&gt;
   33552384  33556447       - free -  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем диск до максимального объема&amp;lt;blockquote&amp;gt;'''da5''' - имя диска&lt;br /&gt;
&lt;br /&gt;
'''1''' - номер партиции&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''1''' /dev/'''da5'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ''' расширяем до определенного размера:&amp;lt;blockquote&amp;gt;    '''-s size''' - Specifies  the  new  size  of the partition, in logical blocks. An SI unit suffix is allowed.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''2''' '''-s 19G''' da0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если gpart show показывает статус раздела [CORRUPT]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем ФС&amp;lt;blockquote&amp;gt;Можно включить автоматические расширение для пула, тогда не придется расширять руками:&lt;br /&gt;
&lt;br /&gt;
zpool set autoexpand=on zfspoolname&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e d101 da5p1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       31.5G   808K  31.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    32.0G   808K  31.5G        -         -     0%  0.00%      -    ONLINE&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (32G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (32G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   d101           32G    100K     32G     0%    /mnt/d101&lt;br /&gt;
   ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
= Вариант 2. Расширение ZFS раздела на шифрованном разделе GELI путем увеличения объема диска (в данном примере через расширение хард-рейда) =&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
https://genneko.github.io/playing-with-bsd/storage/expanding-zfs-on-geli/&lt;br /&gt;
&lt;br /&gt;
https://www.truenas.com/community/threads/geli-cannot-read-metadata-from-invalid-argument.93142/&lt;br /&gt;
&lt;br /&gt;
== Входные данные ==&lt;br /&gt;
- Имеем хардовый RAID5 (24ТБ) в контроллере HP dl380 G9, собранный из 3 дисков 12ТБ&lt;br /&gt;
&lt;br /&gt;
- В nas4free он определяется как /dev/da4 объемом 24ГБ и пришифрован как /dev/da4.elip1&lt;br /&gt;
&lt;br /&gt;
- На da4.elip1 собран ZFS stripe с использованием GPT - /dev/gpt/raid2&lt;br /&gt;
&lt;br /&gt;
== Задача ==&lt;br /&gt;
- Необходимо расширить хардовый RAID5 на +1 12ТБ диск (в итоге получим устройство объемом 36ТБ)&lt;br /&gt;
&lt;br /&gt;
== Процесс ==&lt;br /&gt;
!!! ОБЯЗАТЕЛЬНО ДЕЛАЕМ БЭКАП МЕТАДАННЫХ ШИФРОВАННОГО ДИСКА '''/dev/da4''' В ФАЙЛ '''da4.eli'''&lt;br /&gt;
&lt;br /&gt;
И СОХРАНЯЕМ ЭТОТ ФАЙЛ ЛОКАЛЬНО&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli backup /dev/da4 /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем хард RAID5 через утилиту в BIOS сервера путем добавления одного диска 12ТБ в массив (расширение может длиться 1-2 дня)&lt;br /&gt;
&lt;br /&gt;
Расширяем логический диск на расширенном массиве&lt;br /&gt;
&lt;br /&gt;
Грузимся в nas4free&lt;br /&gt;
&lt;br /&gt;
Копируем ранее сохраненный файл метаданных на '''nas4free''' в &amp;lt;code&amp;gt;/root/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим размер старого диска - нас интересует &amp;quot;'''provsize: 24000210141184'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli dump /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Metadata on /root/da4.eli:&lt;br /&gt;
   ...&lt;br /&gt;
     provsize: '''24000210141184'''&lt;br /&gt;
   ...&lt;br /&gt;
Восстанавливаем файл метаданных на новый расширенный диск&amp;lt;blockquote&amp;gt;'''-s 24000210141184''' - старый объем диска &amp;quot;'''provsize: 24000210141184'''&amp;quot; до расширения, который мы посмотрели в файле метаданных&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;geli resize -v -s 24000210141184 /dev/da4&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Done.&lt;br /&gt;
   ...&lt;br /&gt;
В веб-интерфейсе подключаем шифрованный диск da4 с новым объемом 36ТБ, используя пароль шифрования, с которым создавали старый диск до расширения&lt;br /&gt;
&lt;br /&gt;
!!! НЕ ИСПОЛЬЗУЯ ГАЛКУ &amp;quot;INITIALIZE&amp;quot;, ИНАЧЕ УБЪЕМ РАНЕЕ ШИФРОВАННЫЙ ДИСК&amp;lt;blockquote&amp;gt;Аналог процедуры через консоль:&lt;br /&gt;
&lt;br /&gt;
'''geli attach /dev/da4'''&amp;lt;/blockquote&amp;gt;Импортируем ZFS POOL, который был ранее создан на шифрованном разделе&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool import -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим, ZFS раздел в порядке&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool status&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   pool: raid2&lt;br /&gt;
   state: ONLINE&lt;br /&gt;
   scan: none requested&lt;br /&gt;
   config:&lt;br /&gt;
         NAME         STATE     READ WRITE CKSUM&lt;br /&gt;
         raid2        ONLINE       0     0     0&lt;br /&gt;
           gpt/raid2  ONLINE       0     0     0&lt;br /&gt;
   ...&lt;br /&gt;
Но объем раздела старый, нерасширенный, так и должно быть&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              20T     88K     20T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         21T    1.5T     20T     7%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Также видим статус CORRUPT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  46875410352  da4.eli  GPT  (33T) [CORRUPT]&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240         8152           - free -  (4.0M)&lt;br /&gt;
   ...&lt;br /&gt;
Лечим раздел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.eli recovered&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240  23437713368           - free -  (11T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем партицию до максимального размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart resize -i 1 /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.elip1 resized&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  70313107416        1  freebsd-zfs  (33T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем ZFS-pool raid2&amp;lt;blockquote&amp;gt;'''raid2''' - пул ZFS&lt;br /&gt;
&lt;br /&gt;
'''/dev/gpt/raid2''' - единственный диск, который входит в пул&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e raid2 /dev/gpt/raid2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid3  32.5T  28.9T  3.59T         -    42%    88%  1.00x  ONLINE  -&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              30T     88K     30T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         32T    1.5T     30T     5%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Готово! Раздел расширен.&lt;br /&gt;
[[Категория:ZFS]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1914</id>
		<title>ZFS. Расширение раздела ZFS</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=ZFS._%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B0_ZFS&amp;diff=1914"/>
		<updated>2025-01-05T08:00:01Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Вариант 1. Расширение ZFS раздела путем увеличения объема диска (например на виртуальной машине) =&lt;br /&gt;
Изначально имеем диск 16G&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (16G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       15.5G   544K  15.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    16.0G   544K  15.5G&lt;br /&gt;
   ...&lt;br /&gt;
Выключаем машину (обязательно, иначе будет CORRUPT партиция при просмотре через gpart)&lt;br /&gt;
&lt;br /&gt;
Добавляем объема диску до 32G&lt;br /&gt;
&lt;br /&gt;
Включаем машину&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  '''da5'''  GPT  (32G)&lt;br /&gt;
         40      2008       - free -  (1.0M)&lt;br /&gt;
       2048  33550336    '''1'''  freebsd-zfs  (16G)&lt;br /&gt;
   33552384  33556447       - free -  (16G)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем диск до максимального объема&amp;lt;blockquote&amp;gt;'''da5''' - имя диска&lt;br /&gt;
&lt;br /&gt;
'''1''' - номер партиции&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''1''' /dev/'''da5'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''ИЛИ''' расширяем до определенного размера:&amp;lt;blockquote&amp;gt;    '''-s size''' - Specifies  the  new  size  of the partition, in logical blocks. An SI unit suffix is allowed.&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;gpart resize -i '''2''' '''-s 19G''' da0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если gpart show показывает статус раздела [CORRUPT]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da5&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем ФС&amp;lt;blockquote&amp;gt;Можно включить автоматические расширение для пула, тогда не придется расширять руками:&lt;br /&gt;
&lt;br /&gt;
zpool set autoexpand=on zfspoolname&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e d101 da5p1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list -v d101&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   NAME        SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT&lt;br /&gt;
   d101       31.5G   808K  31.5G        -         -     0%     0%  1.00x    ONLINE  -&lt;br /&gt;
     da5p1    32.0G   808K  31.5G        -         -     0%  0.00%      -    ONLINE&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;      40  67108791  da5  GPT  (32G)&lt;br /&gt;
           40      2008       - free -  (1.0M)&lt;br /&gt;
         2048  67106783    1  freebsd-zfs  (32G)&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   d101           32G    100K     32G     0%    /mnt/d101&lt;br /&gt;
   ...&lt;br /&gt;
Готово!&lt;br /&gt;
&lt;br /&gt;
= Вариант 2. Расширение ZFS раздела на фифрованном разделе GELI путем увеличения объема диска (в данном примере через расширение хард-рейда) =&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
https://genneko.github.io/playing-with-bsd/storage/expanding-zfs-on-geli/&lt;br /&gt;
&lt;br /&gt;
https://www.truenas.com/community/threads/geli-cannot-read-metadata-from-invalid-argument.93142/&lt;br /&gt;
&lt;br /&gt;
== Входные данные ==&lt;br /&gt;
- Имеем хардовый RAID5 (24ТБ) в контроллере HP dl380 G9, собранный из 3 дисков 12ТБ&lt;br /&gt;
&lt;br /&gt;
- В nas4free он определяется как /dev/da4 объемом 24ГБ и пришифрован как /dev/da4.elip1&lt;br /&gt;
&lt;br /&gt;
- На da4.elip1 собран ZFS stripe с использованием GPT - /dev/gpt/raid2&lt;br /&gt;
&lt;br /&gt;
== Задача ==&lt;br /&gt;
- Необходимо расширить хардовый RAID5 на +1 12ТБ диск (в итоге получим устройство объемом 36ТБ)&lt;br /&gt;
&lt;br /&gt;
== Процесс ==&lt;br /&gt;
!!! ОБЯЗАТЕЛЬНО ДЕЛАЕМ БЭКАП МЕТАДАННЫХ ШИФРОВАННОГО ДИСКА '''/dev/da4''' В ФАЙЛ '''da4.eli'''&lt;br /&gt;
&lt;br /&gt;
И СОХРАНЯЕМ ЭТОТ ФАЙЛ ЛОКАЛЬНО&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli backup /dev/da4 /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Расширяем хард RAID5 через утилиту в BIOS сервера путем добавления одного диска 12ТБ в массив (расширение может длиться 1-2 дня)&lt;br /&gt;
&lt;br /&gt;
Расширяем логический диск на расширенном массиве&lt;br /&gt;
&lt;br /&gt;
Грузимся в nas4free&lt;br /&gt;
&lt;br /&gt;
Копируем ранее сохраненный файл метаданных на '''nas4free''' в &amp;lt;code&amp;gt;/root/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим размер старого диска - нас интересует &amp;quot;'''provsize: 24000210141184'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;geli dump /root/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Metadata on /root/da4.eli:&lt;br /&gt;
   ...&lt;br /&gt;
     provsize: '''24000210141184'''&lt;br /&gt;
   ...&lt;br /&gt;
Восстанавливаем файл метаданных на новый расширенный диск&amp;lt;blockquote&amp;gt;'''-s 24000210141184''' - старый объем диска &amp;quot;'''provsize: 24000210141184'''&amp;quot; до расширения, который мы посмотрели в файле метаданных&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;geli resize -v -s 24000210141184 /dev/da4&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   Done.&lt;br /&gt;
   ...&lt;br /&gt;
В веб-интерфейсе подключаем шифрованный диск da4 с новым объемом 36ТБ, используя пароль шифрования, с которым создавали старый диск до расширения&lt;br /&gt;
&lt;br /&gt;
!!! НЕ ИСПОЛЬЗУЯ ГАЛКУ &amp;quot;INITIALIZE&amp;quot;, ИНАЧЕ УБЪЕМ РАНЕЕ ШИФРОВАННЫЙ ДИСК&amp;lt;blockquote&amp;gt;Аналог процедуры через консоль:&lt;br /&gt;
&lt;br /&gt;
'''geli attach /dev/da4'''&amp;lt;/blockquote&amp;gt;Импортируем ZFS POOL, который был ранее создан на шифрованном разделе&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool import -a&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим, ZFS раздел в порядке&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool status&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   pool: raid2&lt;br /&gt;
   state: ONLINE&lt;br /&gt;
   scan: none requested&lt;br /&gt;
   config:&lt;br /&gt;
         NAME         STATE     READ WRITE CKSUM&lt;br /&gt;
         raid2        ONLINE       0     0     0&lt;br /&gt;
           gpt/raid2  ONLINE       0     0     0&lt;br /&gt;
   ...&lt;br /&gt;
Но объем раздела старый, нерасширенный, так и должно быть&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              20T     88K     20T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         21T    1.5T     20T     7%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Также видим статус CORRUPT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  46875410352  da4.eli  GPT  (33T) [CORRUPT]&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240         8152           - free -  (4.0M)&lt;br /&gt;
   ...&lt;br /&gt;
Лечим раздел&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart recover da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.eli recovered&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  46875394048        1  freebsd-zfs  (22T)&lt;br /&gt;
   46875402240  23437713368           - free -  (11T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем партицию до максимального размера&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart resize -i 1 /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   da4.elip1 resized&lt;br /&gt;
   ...&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gpart show /dev/da4.eli&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   =&amp;gt;         40  70313115568  da4.eli  GPT  (33T)&lt;br /&gt;
            40         8152           - free -  (4.0M)&lt;br /&gt;
          8192  70313107416        1  freebsd-zfs  (33T)&lt;br /&gt;
   ...&lt;br /&gt;
Расширяем ZFS-pool raid2&amp;lt;blockquote&amp;gt;'''raid2''' - пул ZFS&lt;br /&gt;
&lt;br /&gt;
'''/dev/gpt/raid2''' - единственный диск, который входит в пул&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;zpool online -e raid2 /dev/gpt/raid2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;zpool list&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid3  32.5T  28.9T  3.59T         -    42%    88%  1.00x  ONLINE  -&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;code&amp;gt;df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
   raid2              30T     88K     30T     0%    /mnt/raid2&lt;br /&gt;
   raid2/bkup         32T    1.5T     30T     5%    /mnt/raid2/bkup&lt;br /&gt;
   ...&lt;br /&gt;
Готово! Раздел расширен.&lt;br /&gt;
[[Категория:ZFS]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1913</id>
		<title>Kubernetes. AlmaLinux 8. Kubernetes Cluster installation with the only one Master-Node and many Worker-Nodes</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1913"/>
		<updated>2024-12-17T06:34:13Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= About =&lt;br /&gt;
Install Kubernetes Master + Node at AlmaLinux 8&lt;br /&gt;
&lt;br /&gt;
= Install =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Firewalld off ===&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl disable --now firewalld.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Selinux OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set hostname ===&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add IP address and hostname resolve to hosts&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
=== Swap OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bridge settings ===&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker install ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes install ===&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Autocompletion kubadm&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker setup ===&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status docker&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Kubernetes init ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
    [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
    sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
    sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;'''''--apiserver-advertise-address=192.168.199.184''''' - LAN interface address, if it is not specified, the default address will be used&lt;br /&gt;
&lt;br /&gt;
'''''--pod-network-cidr=172.16.213.0/24''''' - container virtual network&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm init --apiserver-advertise-address=192.168.199.184 --pod-network-cidr=172.16.213.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;
     To start using your cluster, you need to run the following as a regular user:&lt;br /&gt;
     mkdir -p $HOME/.kube&lt;br /&gt;
     sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;
     sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;
     Alternatively, if you are the root user, you can run:&lt;br /&gt;
     export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;
     You should now deploy a pod network to the cluster.&lt;br /&gt;
     Run &amp;quot;kubectl apply -f [podnetwork].yaml&amp;quot; with one of the options listed at:&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;https://kubernetes.io/docs/concepts/cluster-administration/addons/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     Then you can join any number of worker nodes by running the following on each as root:&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token gn2gva.2h73qvdhk0bg6krn \&lt;br /&gt;
             --discovery-token-ca-cert-hash sha256:418ca3a0003c8945a1cb9c108992c33aedcebbd1a4ba3960b43230a71eb8cda5&lt;br /&gt;
     ...&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p $HOME/.kube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown $(id -u):$(id -g) $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup cluster networking ===&lt;br /&gt;
We need to deploy the pod's internal network so that containers on different nodes can communicate with each other. POD network is the overlay network between the worker nodes.&lt;br /&gt;
&lt;br /&gt;
An overlay network is a virtual network of nodes and logical links, which are built on top of an existing network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f &amp;lt;nowiki&amp;gt;https://docs.projectcalico.org/manifests/calico.yaml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wait about 1 minute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.184&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you somehow miss the output from the kubeadm init command, nothing to worry about as you can always run following command to generate the kubeadm join token again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm token create --print-join-command&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== WORKERS '''kub-node-1 (you can add additional nodes this way, for example &amp;quot;kub-node-2&amp;quot;)''' ==&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl disable --now firewalld.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add host and IP match to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Also you need to add new node host to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; of all k8s nodes and masters in cluster. Or use a DNS server to match IP and hostname.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''--node-ip=192.168.199.186''''' - kub-node-1 IP address&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.186&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
       [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   '''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
       sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
       sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Postinstall and info =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Set node(s) role &amp;quot;node&amp;quot; ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl label node kub-node-1 node-role.kubernetes.io/node=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cluster info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl cluster-info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master or node info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get nodes ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes -o wide&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME&lt;br /&gt;
     master   Ready    control-plane,master   65m     v1.23.1   192.168.199.169   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-348.7.1.el8_5.x86_64    docker://20.10.12&lt;br /&gt;
     node-1   Ready    &amp;lt;none&amp;gt;                 2m28s   v1.23.1   192.168.199.179   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-305.25.1.el8_4.x86_64   docker://20.10.12&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Get pods ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pods --all-namespaces&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAMESPACE     NAME                                       READY   STATUS    RESTARTS      AGE&lt;br /&gt;
     kube-system   calico-kube-controllers-85b5b5888d-lrsq8   1/1     Running   0             58m&lt;br /&gt;
     kube-system   calico-node-gwtl6                          1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   calico-node-lbbbv                          1/1     Running   0             58m&lt;br /&gt;
     kube-system   coredns-64897985d-6jv5w                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   coredns-64897985d-n6c9l                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   etcd-master                                1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-apiserver-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-controller-manager-master             1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-44l8g                           1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-ljfsd                           1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   kube-scheduler-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
Check certs expiration&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs check-expiration&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     [check-expiration] Reading configuration from the cluster...&lt;br /&gt;
     [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'&lt;br /&gt;
     CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED&lt;br /&gt;
     admin.conf                 Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     apiserver                  Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     apiserver-etcd-client      Feb 20, 2023 19:11 UTC   364d            etcd-ca                 no&lt;br /&gt;
     apiserver-kubelet-client   Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     controller-manager.conf    Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     etcd-healthcheck-client    Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-peer                  Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-server                Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     front-proxy-client         Feb 20, 2023 19:10 UTC   364d            front-proxy-ca          no&lt;br /&gt;
     scheduler.conf             Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED&lt;br /&gt;
     ca                      Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     etcd-ca                 Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     front-proxy-ca          Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     ...&lt;br /&gt;
Renew all certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs renew all&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1912</id>
		<title>Kubernetes. AlmaLinux 8. Kubernetes Cluster installation with the only one Master-Node and many Worker-Nodes</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1912"/>
		<updated>2024-12-16T12:42:12Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= About =&lt;br /&gt;
Install Kubernetes Master + Node at AlmaLinux 8&lt;br /&gt;
&lt;br /&gt;
= Install =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Selinux OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set hostname ===&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add IP address and hostname resolve to hosts&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
=== Swap OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bridge settings ===&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker install ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes install ===&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Autocompletion kubadm&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker setup ===&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status docker&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Kubernetes init ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
    [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
    sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
    sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;'''''--apiserver-advertise-address=192.168.199.184''''' - LAN interface address, if it is not specified, the default address will be used&lt;br /&gt;
&lt;br /&gt;
'''''--pod-network-cidr=172.16.213.0/24''''' - container virtual network&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm init --apiserver-advertise-address=192.168.199.184 --pod-network-cidr=172.16.213.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;
     To start using your cluster, you need to run the following as a regular user:&lt;br /&gt;
     mkdir -p $HOME/.kube&lt;br /&gt;
     sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;
     sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;
     Alternatively, if you are the root user, you can run:&lt;br /&gt;
     export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;
     You should now deploy a pod network to the cluster.&lt;br /&gt;
     Run &amp;quot;kubectl apply -f [podnetwork].yaml&amp;quot; with one of the options listed at:&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;https://kubernetes.io/docs/concepts/cluster-administration/addons/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     Then you can join any number of worker nodes by running the following on each as root:&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token gn2gva.2h73qvdhk0bg6krn \&lt;br /&gt;
             --discovery-token-ca-cert-hash sha256:418ca3a0003c8945a1cb9c108992c33aedcebbd1a4ba3960b43230a71eb8cda5&lt;br /&gt;
     ...&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p $HOME/.kube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown $(id -u):$(id -g) $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup cluster networking ===&lt;br /&gt;
We need to deploy the pod's internal network so that containers on different nodes can communicate with each other. POD network is the overlay network between the worker nodes.&lt;br /&gt;
&lt;br /&gt;
An overlay network is a virtual network of nodes and logical links, which are built on top of an existing network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f &amp;lt;nowiki&amp;gt;https://docs.projectcalico.org/manifests/calico.yaml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wait about 1 minute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.184&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you somehow miss the output from the kubeadm init command, nothing to worry about as you can always run following command to generate the kubeadm join token again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm token create --print-join-command&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== WORKERS '''kub-node-1 (you can add additional nodes this way, for example &amp;quot;kub-node-2&amp;quot;)''' ==&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add host and IP match to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Also you need to add new node host to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; of all k8s nodes and masters in cluster. Or use a DNS server to match IP and hostname.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''--node-ip=192.168.199.186''''' - kub-node-1 IP address&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.186&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
       [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   '''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
       sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
       sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Postinstall and info =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Set node(s) role &amp;quot;node&amp;quot; ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl label node kub-node-1 node-role.kubernetes.io/node=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cluster info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl cluster-info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master or node info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get nodes ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes -o wide&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME&lt;br /&gt;
     master   Ready    control-plane,master   65m     v1.23.1   192.168.199.169   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-348.7.1.el8_5.x86_64    docker://20.10.12&lt;br /&gt;
     node-1   Ready    &amp;lt;none&amp;gt;                 2m28s   v1.23.1   192.168.199.179   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-305.25.1.el8_4.x86_64   docker://20.10.12&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Get pods ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pods --all-namespaces&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAMESPACE     NAME                                       READY   STATUS    RESTARTS      AGE&lt;br /&gt;
     kube-system   calico-kube-controllers-85b5b5888d-lrsq8   1/1     Running   0             58m&lt;br /&gt;
     kube-system   calico-node-gwtl6                          1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   calico-node-lbbbv                          1/1     Running   0             58m&lt;br /&gt;
     kube-system   coredns-64897985d-6jv5w                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   coredns-64897985d-n6c9l                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   etcd-master                                1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-apiserver-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-controller-manager-master             1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-44l8g                           1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-ljfsd                           1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   kube-scheduler-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
Check certs expiration&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs check-expiration&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     [check-expiration] Reading configuration from the cluster...&lt;br /&gt;
     [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'&lt;br /&gt;
     CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED&lt;br /&gt;
     admin.conf                 Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     apiserver                  Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     apiserver-etcd-client      Feb 20, 2023 19:11 UTC   364d            etcd-ca                 no&lt;br /&gt;
     apiserver-kubelet-client   Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     controller-manager.conf    Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     etcd-healthcheck-client    Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-peer                  Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-server                Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     front-proxy-client         Feb 20, 2023 19:10 UTC   364d            front-proxy-ca          no&lt;br /&gt;
     scheduler.conf             Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED&lt;br /&gt;
     ca                      Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     etcd-ca                 Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     front-proxy-ca          Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     ...&lt;br /&gt;
Renew all certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs renew all&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1911</id>
		<title>Kubernetes. AlmaLinux 8. Kubernetes Cluster installation with the only one Master-Node and many Worker-Nodes</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1911"/>
		<updated>2024-12-16T12:31:15Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= About =&lt;br /&gt;
Install Kubernetes Master + Node at AlmaLinux 8&lt;br /&gt;
&lt;br /&gt;
= Install =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Selinux OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set hostname ===&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add IP address and hostname resolve to hosts&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
=== Swap OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bridge settings ===&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker install ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes install ===&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Autocompletion kubadm&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker setup ===&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status docker&amp;lt;/code&amp;gt;&lt;br /&gt;
=== Kubernetes init ===&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
    [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
    sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
    sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;'''''--apiserver-advertise-address=192.168.199.184''''' - LAN interface address, if it is not specified, the default address will be used&lt;br /&gt;
&lt;br /&gt;
'''''--pod-network-cidr=172.16.213.0/24''''' - container virtual network&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm init --apiserver-advertise-address=192.168.199.184 --pod-network-cidr=172.16.213.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;
     To start using your cluster, you need to run the following as a regular user:&lt;br /&gt;
     mkdir -p $HOME/.kube&lt;br /&gt;
     sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;
     sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;
     Alternatively, if you are the root user, you can run:&lt;br /&gt;
     export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;
     You should now deploy a pod network to the cluster.&lt;br /&gt;
     Run &amp;quot;kubectl apply -f [podnetwork].yaml&amp;quot; with one of the options listed at:&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;https://kubernetes.io/docs/concepts/cluster-administration/addons/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     Then you can join any number of worker nodes by running the following on each as root:&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token gn2gva.2h73qvdhk0bg6krn \&lt;br /&gt;
             --discovery-token-ca-cert-hash sha256:418ca3a0003c8945a1cb9c108992c33aedcebbd1a4ba3960b43230a71eb8cda5&lt;br /&gt;
     ...&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p $HOME/.kube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown $(id -u):$(id -g) $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup cluster networking ===&lt;br /&gt;
We need to deploy the pod's internal network so that containers on different nodes can communicate with each other. POD network is the overlay network between the worker nodes.&lt;br /&gt;
&lt;br /&gt;
An overlay network is a virtual network of nodes and logical links, which are built on top of an existing network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f &amp;lt;nowiki&amp;gt;https://docs.projectcalico.org/manifests/calico.yaml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wait about 1 minute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.184&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you somehow miss the output from the kubeadm init command, nothing to worry about as you can always run following command to generate the kubeadm join token again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm token create --print-join-command&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== WORKERS '''kub-node-1 (you can add additional nodes this way, for example &amp;quot;kub-node-2&amp;quot;)''' ==&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add host and IP match to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Also you need to add new node host to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; of all k8s nodes and masters in cluster. Or use a DNS server to match IP and hostname.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''--node-ip=192.168.199.186''''' - kub-node-1 IP address&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.186&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
       [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   '''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
       sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
       sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Postinstall and info =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Set node(s) role &amp;quot;node&amp;quot; ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl label node kub-node-1 node-role.kubernetes.io/node=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cluster info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl cluster-info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master or node info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get nodes ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes -o wide&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME&lt;br /&gt;
     master   Ready    control-plane,master   65m     v1.23.1   192.168.199.169   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-348.7.1.el8_5.x86_64    docker://20.10.12&lt;br /&gt;
     node-1   Ready    &amp;lt;none&amp;gt;                 2m28s   v1.23.1   192.168.199.179   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-305.25.1.el8_4.x86_64   docker://20.10.12&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Get pods ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pods --all-namespaces&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAMESPACE     NAME                                       READY   STATUS    RESTARTS      AGE&lt;br /&gt;
     kube-system   calico-kube-controllers-85b5b5888d-lrsq8   1/1     Running   0             58m&lt;br /&gt;
     kube-system   calico-node-gwtl6                          1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   calico-node-lbbbv                          1/1     Running   0             58m&lt;br /&gt;
     kube-system   coredns-64897985d-6jv5w                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   coredns-64897985d-n6c9l                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   etcd-master                                1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-apiserver-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-controller-manager-master             1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-44l8g                           1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-ljfsd                           1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   kube-scheduler-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
Check certs expiration&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs check-expiration&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     [check-expiration] Reading configuration from the cluster...&lt;br /&gt;
     [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'&lt;br /&gt;
     CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED&lt;br /&gt;
     admin.conf                 Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     apiserver                  Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     apiserver-etcd-client      Feb 20, 2023 19:11 UTC   364d            etcd-ca                 no&lt;br /&gt;
     apiserver-kubelet-client   Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     controller-manager.conf    Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     etcd-healthcheck-client    Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-peer                  Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-server                Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     front-proxy-client         Feb 20, 2023 19:10 UTC   364d            front-proxy-ca          no&lt;br /&gt;
     scheduler.conf             Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED&lt;br /&gt;
     ca                      Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     etcd-ca                 Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     front-proxy-ca          Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     ...&lt;br /&gt;
Renew all certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs renew all&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1910</id>
		<title>Kubernetes. AlmaLinux 8. Kubernetes Cluster installation with the only one Master-Node and many Worker-Nodes</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Kubernetes._AlmaLinux_8._Kubernetes_Cluster_installation_with_the_only_one_Master-Node_and_many_Worker-Nodes&amp;diff=1910"/>
		<updated>2024-12-16T12:25:52Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= About =&lt;br /&gt;
Install Kubernetes Master + Node at AlmaLinux 8&lt;br /&gt;
&lt;br /&gt;
= Install =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Selinux OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set hostname ===&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add IP address and hostname resolve to hosts&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&lt;br /&gt;
=== Swap OFF ===&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bridge settings ===&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker install ===&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes install ===&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Autocompletion kubadm&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Docker setup ===&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status docker&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;# init&lt;br /&gt;
&lt;br /&gt;
   '''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
       [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   '''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
       sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
       sudo systemctl restart containerd&lt;br /&gt;
&lt;br /&gt;
       sudo kubeadm init&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubernetes init ===&lt;br /&gt;
'''''--apiserver-advertise-address=192.168.199.184''''' - LAN interface address, if it is not specified, the default address will be used&lt;br /&gt;
&lt;br /&gt;
'''''--pod-network-cidr=172.16.213.0/24''''' - container virtual network&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm init --apiserver-advertise-address=192.168.199.184 --pod-network-cidr=172.16.213.0/24&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;
     To start using your cluster, you need to run the following as a regular user:&lt;br /&gt;
     mkdir -p $HOME/.kube&lt;br /&gt;
     sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;
     sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;
     Alternatively, if you are the root user, you can run:&lt;br /&gt;
     export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;
     You should now deploy a pod network to the cluster.&lt;br /&gt;
     Run &amp;quot;kubectl apply -f [podnetwork].yaml&amp;quot; with one of the options listed at:&lt;br /&gt;
     &amp;lt;nowiki&amp;gt;https://kubernetes.io/docs/concepts/cluster-administration/addons/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     Then you can join any number of worker nodes by running the following on each as root:&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token gn2gva.2h73qvdhk0bg6krn \&lt;br /&gt;
             --discovery-token-ca-cert-hash sha256:418ca3a0003c8945a1cb9c108992c33aedcebbd1a4ba3960b43230a71eb8cda5&lt;br /&gt;
     ...&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir -p $HOME/.kube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chown $(id -u):$(id -g) $HOME/.kube/config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setup cluster networking ===&lt;br /&gt;
We need to deploy the pod's internal network so that containers on different nodes can communicate with each other. POD network is the overlay network between the worker nodes.&lt;br /&gt;
&lt;br /&gt;
An overlay network is a virtual network of nodes and logical links, which are built on top of an existing network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl apply -f &amp;lt;nowiki&amp;gt;https://docs.projectcalico.org/manifests/calico.yaml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wait about 1 minute&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.184&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you somehow miss the output from the kubeadm init command, nothing to worry about as you can always run following command to generate the kubeadm join token again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm token create --print-join-command&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
== WORKERS '''kub-node-1 (you can add additional nodes this way, for example &amp;quot;kub-node-2&amp;quot;)''' ==&lt;br /&gt;
&amp;lt;code&amp;gt;setenforce 0&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sed -i 's/#\?\(SELINUX\=\).*$/\1disabled/' /etc/sysconfig/selinux&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;hostnamectl set-hostname kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add host and IP match to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;Also you need to add new node host to &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; of all k8s nodes and masters in cluster. Or use a DNS server to match IP and hostname.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF&amp;gt;&amp;gt; /etc/hosts&lt;br /&gt;
 192.168.199.184 kub-master-1&lt;br /&gt;
 192.168.199.186 kub-node-1&lt;br /&gt;
 192.168.199.187 kub-node-2&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;swapoff -a &amp;amp;&amp;amp; sed -i '/ swap / s/^/#/' /etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;modprobe br_netfilter&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo '1' &amp;gt; /proc/sys/net/bridge/bridge-nf-call-iptables&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf config-manager --add-repo=&amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y --nobest docker-ce&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl start docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/yum.repos.d/kubernetes.repo&lt;br /&gt;
 [kubernetes]&lt;br /&gt;
 name=Kubernetes&lt;br /&gt;
 baseurl=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 enabled=1&lt;br /&gt;
 gpgcheck=1&lt;br /&gt;
 repo_gpgcheck=1&lt;br /&gt;
 gpgkey=&amp;lt;nowiki&amp;gt;https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 exclude=kubelet kubeadm kubectl&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;yum repolist&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;yum install bash-completion -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl &amp;lt;nowiki&amp;gt;https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker&amp;lt;/nowiki&amp;gt; -o /etc/bash_completion.d/docker.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl completion bash &amp;gt;/etc/bash_completion.d/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'source &amp;lt;(kubeadm completion bash)' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm completion bash &amp;gt;/etc/bash_completion.d/kubeadm&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.bashrc&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;'''Relogin to terminal!'''&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;touch /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''--node-ip=192.168.199.186''''' - kub-node-1 IP address&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;echo &amp;quot;KUBELET_EXTRA_ARGS=--node-ip=192.168.199.186&amp;quot; &amp;gt; /etc/default/kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mkdir /etc/docker&amp;lt;/code&amp;gt;&lt;br /&gt;
 cat &amp;lt;&amp;lt;EOF | sudo tee /etc/docker/daemon.json&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;exec-opts&amp;quot;: [&amp;quot;native.cgroupdriver=systemd&amp;quot;],&lt;br /&gt;
   &amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,&lt;br /&gt;
   &amp;quot;log-opts&amp;quot;: {&lt;br /&gt;
     &amp;quot;max-size&amp;quot;: &amp;quot;100m&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;storage-driver&amp;quot;: &amp;quot;overlay2&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 EOF&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl daemon-reload&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart docker&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm reset&amp;lt;/code&amp;gt;&amp;lt;blockquote&amp;gt;   '''ERROR:'''&lt;br /&gt;
&lt;br /&gt;
       [ERROR CRI]: container runtime is not running: output: time=&amp;quot;2022-05-20T02:06:28Z&amp;quot; level=fatal msg=&amp;quot;getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   '''SOLUTION:'''&lt;br /&gt;
&lt;br /&gt;
       sudo rm /etc/containerd/config.toml&lt;br /&gt;
&lt;br /&gt;
       sudo systemctl restart containerd&amp;lt;/blockquote&amp;gt;&amp;lt;code&amp;gt;kubeadm join 192.168.199.184:6443 --token 2qw1q0.hnmu7eggccf7172y --discovery-token-ca-cert-hash sha256:c7832b18f117af05346cf019aa7a9d3ca0029c65a69320f7cb807147ee975efb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable kubelet&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Postinstall and info =&lt;br /&gt;
&lt;br /&gt;
== MASTER '''kub-master-1''' ==&lt;br /&gt;
&lt;br /&gt;
=== Set node(s) role &amp;quot;node&amp;quot; ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl label node kub-node-1 node-role.kubernetes.io/node=&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cluster info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl cluster-info&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Master or node info ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-master-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl describe node kub-node-1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get nodes ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get nodes -o wide&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME&lt;br /&gt;
     master   Ready    control-plane,master   65m     v1.23.1   192.168.199.169   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-348.7.1.el8_5.x86_64    docker://20.10.12&lt;br /&gt;
     node-1   Ready    &amp;lt;none&amp;gt;                 2m28s   v1.23.1   192.168.199.179   &amp;lt;none&amp;gt;        CentOS Linux 8   4.18.0-305.25.1.el8_4.x86_64   docker://20.10.12&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Get pods ===&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl get pods --all-namespaces&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     NAMESPACE     NAME                                       READY   STATUS    RESTARTS      AGE&lt;br /&gt;
     kube-system   calico-kube-controllers-85b5b5888d-lrsq8   1/1     Running   0             58m&lt;br /&gt;
     kube-system   calico-node-gwtl6                          1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   calico-node-lbbbv                          1/1     Running   0             58m&lt;br /&gt;
     kube-system   coredns-64897985d-6jv5w                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   coredns-64897985d-n6c9l                    1/1     Running   0             65m&lt;br /&gt;
     kube-system   etcd-master                                1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-apiserver-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-controller-manager-master             1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-44l8g                           1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     kube-system   kube-proxy-ljfsd                           1/1     Running   0             2m32s&lt;br /&gt;
     kube-system   kube-scheduler-master                      1/1     Running   1 (64m ago)   65m&lt;br /&gt;
     ...&lt;br /&gt;
&lt;br /&gt;
=== Certificates ===&lt;br /&gt;
Check certs expiration&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs check-expiration&amp;lt;/code&amp;gt;&lt;br /&gt;
     ...&lt;br /&gt;
     [check-expiration] Reading configuration from the cluster...&lt;br /&gt;
     [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'&lt;br /&gt;
     CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED&lt;br /&gt;
     admin.conf                 Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     apiserver                  Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     apiserver-etcd-client      Feb 20, 2023 19:11 UTC   364d            etcd-ca                 no&lt;br /&gt;
     apiserver-kubelet-client   Feb 20, 2023 19:10 UTC   364d            ca                      no&lt;br /&gt;
     controller-manager.conf    Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     etcd-healthcheck-client    Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-peer                  Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     etcd-server                Feb 20, 2023 19:10 UTC   364d            etcd-ca                 no&lt;br /&gt;
     front-proxy-client         Feb 20, 2023 19:10 UTC   364d            front-proxy-ca          no&lt;br /&gt;
     scheduler.conf             Feb 20, 2023 19:11 UTC   364d            ca                      no&lt;br /&gt;
     CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED&lt;br /&gt;
     ca                      Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     etcd-ca                 Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     front-proxy-ca          Feb 18, 2032 19:10 UTC   9y              no&lt;br /&gt;
     ...&lt;br /&gt;
Renew all certs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubeadm certs renew all&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Minikube._Almalinux_8._Installation&amp;diff=1909</id>
		<title>Minikube. Almalinux 8. Installation</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Minikube._Almalinux_8._Installation&amp;diff=1909"/>
		<updated>2024-12-12T16:50:45Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Links =&lt;br /&gt;
https://technixleo.com/run-minikube-kubernetes-on-centos-almalinux-rhel/&lt;br /&gt;
&lt;br /&gt;
= Description =&lt;br /&gt;
Minikube requires your system to be running on a virtual machine environment or a docker container.&lt;br /&gt;
&lt;br /&gt;
= Common installation =&lt;br /&gt;
&amp;lt;code&amp;gt;dnf update -y&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Install KVM and its dependencies with the following command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf install -y qemu-kvm qemu-img libvirt virt-install libvirt-client conntrack&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable and start the libvirtd service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now libvirtd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check for the libvirtd service status&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl status libvirtd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Docker install&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y config-manager --add-repo &amp;lt;nowiki&amp;gt;https://download.docker.com/linux/centos/docker-ce.repo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y remove podman buildah&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;dnf -y install docker-ce docker-ce-cli containerd.io&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now docker.service&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;docker version&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create user libvirt and add one to groups libvirt, docker&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;adduser libvirt -g libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;passwd libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo usermod -a -G libvirt libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo usermod -a -G docker libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;newgrp libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sdoers file edit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/sudoers&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 %libvirt ALL=(ALL) NOPASSWD: ALL&lt;br /&gt;
Edit the main configuration file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/libvirt/libvirtd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the UNIX domain socket group ownership to libvirt by uncommenting the following line. In other words, remove the #.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;unix_sock_group = &amp;quot;libvirt&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the UNIX socket permissions for the R/W socket by uncommenting the following line and setting the correct permissions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;unix_sock_rw_perms = &amp;quot;0770&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save the file and restart the Libvirtd service.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl restart libvirtd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Install minikube =&lt;br /&gt;
Download the latest release of Minikube from the Github Latest releases page and install it.&lt;br /&gt;
&lt;br /&gt;
Alternatively, you can install Minikube using the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl -LO &amp;lt;nowiki&amp;gt;https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;install minikube-linux-amd64 /usr/local/bin/minikube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check for the Minikube version to confirm successful installation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;minikube version&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Configure kubectl =&lt;br /&gt;
Install kubectl Locally&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;curl -LO &amp;lt;nowiki&amp;gt;https://storage.googleapis.com/kubernetes-release/release/`curl&amp;lt;/nowiki&amp;gt; -s &amp;lt;nowiki&amp;gt;https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make the file executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod +x ./kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move it to a directory that is on $PATH.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;mv ./kubectl /usr/local/bin/kubectl&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Confirm successful installation by checking the version.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;kubectl version --client -o json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Start minikube =&lt;br /&gt;
Login to libvirt user&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;su - libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To start using Minikube as a single node cluster, run the following command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;minikube start --addons=ingress&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Run as service =&lt;br /&gt;
EXIT to root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nano /etc/systemd/system/minikube.service&amp;lt;/code&amp;gt;&lt;br /&gt;
 [Unit]&lt;br /&gt;
 Description=Runs minikube on startup&lt;br /&gt;
 After=docker&lt;br /&gt;
 &lt;br /&gt;
 [Service]&lt;br /&gt;
 ExecStart=/usr/local/bin/minikube start&lt;br /&gt;
 ExecStop=/usr/local/bin/minikube stop&lt;br /&gt;
 Type=oneshot&lt;br /&gt;
 RemainAfterExit=yes&lt;br /&gt;
 User=libvirt&lt;br /&gt;
 Group=libvirt&lt;br /&gt;
 &lt;br /&gt;
 [Install]&lt;br /&gt;
 WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;code&amp;gt;systemctl enable --now minikube&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;reboot&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You have to work with minikube as user &amp;quot;libvirt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;su - libvirt&amp;lt;/code&amp;gt;&lt;br /&gt;
[[Категория:AlmaLinux 8]]&lt;br /&gt;
[[Категория:Kubernetes]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Virtual_memory&amp;diff=1908</id>
		<title>Linux. Virtual memory</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Virtual_memory&amp;diff=1908"/>
		<updated>2024-11-26T20:46:24Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Общая информация =&lt;br /&gt;
Любой запущенный процесс получает собственный выделенный участок памяти. Но этот участок не отображается на доступные физические адреса, а использует виртуальное адресное пространство, которое является дополнительным слоем абстракции между процессом и физической памятью. Для сопоставления адресов между виртуальной и физической памятью используются специальные структуры - таблицы страниц.&lt;br /&gt;
&lt;br /&gt;
Что это дает? Во-первых, изоляцию процессов друг от друга, каждый из них работает в собственном виртуальном адресном пространстве и не имеет доступа к памяти других процессов. Во-вторых, позволяет системе гибко управлять физической памятью, например, для неактивного процесса часть страниц может быть перенесено из оперативной памяти в пространства подкачки, но это никак не повлияет на работу самого процесса, его адресное пространство не изменится, поменяется лишь трансляция в таблице страниц. И, наконец, это позволяет экономить физическую память, так если несколько процессов используют одни и те же данные, то система может транслировать адреса виртуальных пространств на один и тот же участок физической памяти.&lt;br /&gt;
&lt;br /&gt;
Таким образом размер виртуальной памяти в системе теоретически ничем не ограничен и общий ее объем может существенно превышать имеющуюся в наличии физическую память. И в этом нет ничего плохого, например, мы запустили несколько графических приложений, для работы которым требуются библиотеки Qt или GTK, но нужно ли каждый раз загружать их в память? Нет, достаточно сделать это один раз, а затем просто транслировать адреса виртуальной памяти процессов на одни и те же участки физической памяти. Но при этом каждый процесс будет думать, что у него загружена собственная копия библиотек.&lt;br /&gt;
&lt;br /&gt;
= Виды кэша =&lt;br /&gt;
'''PageCache''' или '''страничный кэш''' - это место, куда ядро складывает все данные, которые были записаны или считаны из диска.&lt;br /&gt;
&lt;br /&gt;
Кэш '''inode''' и '''dentrie''' - тоже относится к файловой системе. Только в него записываются не сами данные, а структура файловой системы, расположение файлов и папок.&lt;br /&gt;
&lt;br /&gt;
= Работа с памятью =&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|'''cat /proc/meminfo'''&lt;br /&gt;
|Информация об объеме RAM, SWAP и другая информация&lt;br /&gt;
|-&lt;br /&gt;
|'''free -m'''&lt;br /&gt;
|Общий объем памяти (RAM, SWAP), количество использованной, свободной памяти в МБайтах [1]&lt;br /&gt;
|-&lt;br /&gt;
|'''free -m -s 5'''&lt;br /&gt;
|Вывод в других единицах — с ключами:-b байтах; -m мегабайтах; -g гигабайтах, -s запустить с заданным периодом обновления информации&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;lt;nowiki&amp;gt;free -m | awk 'NR==2{printf &amp;quot;Memory Usage: %s/%sMB (%.2f%%)\n&amp;quot;, $3,$2,$3*100/$2}&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
|Расчет использования оперативной памяти&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |'''Очистка кэша памяти'''&lt;br /&gt;
|-&lt;br /&gt;
|'''free -h'''&lt;br /&gt;
|Посмотреть размер страничного кэша можно в последней колонке - cached&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;lt;nowiki&amp;gt;cat /proc/slabinfo | egrep dentry\|inode&amp;lt;/nowiki&amp;gt;'''&lt;br /&gt;
|Просмотр кэша inode и dentrie, относящихся к файловой системе.&lt;br /&gt;
В него записываются не сами данные, а структура файловой системы, расположение файлов и папок.&lt;br /&gt;
|-&lt;br /&gt;
|'''sync; echo 1 &amp;gt; /proc/sys/vm/drop_caches'''&lt;br /&gt;
|Очистка кэша PageCache&lt;br /&gt;
|-&lt;br /&gt;
|'''sync; echo 2 &amp;gt; /proc/sys/vm/drop_caches'''&lt;br /&gt;
|Очистка inode и dentrie&lt;br /&gt;
|-&lt;br /&gt;
|'''sync; echo 3 &amp;gt; /proc/sys/vm/drop_caches'''&lt;br /&gt;
|Очистка inode и dentrie и PageCache&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Описание колонок в выводе команды free =&lt;br /&gt;
 total — общее количество памяти;&lt;br /&gt;
 used — реально использующая в данный момент и зарезервированная системой память;&lt;br /&gt;
 free — свободная память (total минус used);&lt;br /&gt;
 shared — Shared memory или Разделяемая память, можно посмотреть командой ipcs;&lt;br /&gt;
 buffers — буферы в памяти — страницы памяти, зарезервированные системой для выделения их процессам, когда они затребуют этого, так же известна как heap-memory;&lt;br /&gt;
 cached — файлы, которые недавно были использованы системой/процессами и хранящиеся в памяти на случай если вскоре они снова потребуются. '''(Страницы которые изменились в памяти но не изменились на диске помечаются грязными (Dirty). Грязные страницы записываются на диск по расписанию или утилитой sync)'''&lt;br /&gt;
 &lt;br /&gt;
[[Категория:Linux]]&lt;br /&gt;
[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
__БЕЗ_РЕДАКТИРОВАНИЯ_РАЗДЕЛА__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1907</id>
		<title>Linux. Top</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1907"/>
		<updated>2024-11-26T20:37:52Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Linux]]&lt;br /&gt;
[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Shortcuts =&lt;br /&gt;
&lt;br /&gt;
=== Человеческое отображение объема памяти (human readable) ===&lt;br /&gt;
&amp;quot;'''e'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Отсортировать по памяти ===&lt;br /&gt;
&amp;quot;'''M'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Информация о процессе ===&lt;br /&gt;
&amp;lt;code&amp;gt;top -b -n 1 -p 1184&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TOP LEGEND =&lt;br /&gt;
&lt;br /&gt;
== '''%Cpu(s):''' ==&lt;br /&gt;
In &amp;quot;top&amp;quot; what are us, sy, ni, id, wa, hi, si and st (for CPU usage)?&lt;br /&gt;
&lt;br /&gt;
'''us''' - user cpu time (or) % CPU time spent in user space&lt;br /&gt;
&lt;br /&gt;
'''sy''' - system cpu time (or) % CPU time spent in kernel space&lt;br /&gt;
&lt;br /&gt;
'''ni''' - user nice cpu time (or) % CPU time spent on low priority processes&lt;br /&gt;
&lt;br /&gt;
'''id''' - idle cpu time (or) % CPU time spent idle&lt;br /&gt;
&lt;br /&gt;
'''wa''' - io wait cpu time (or) % CPU time spent in wait (on disk)&lt;br /&gt;
&lt;br /&gt;
'''hi''' - hardware irq (or) % CPU time spent servicing/handling hardware interrupts&lt;br /&gt;
&lt;br /&gt;
'''si''' - software irq (or) % CPU time spent servicing/handling software interrupts&lt;br /&gt;
&lt;br /&gt;
'''st''' - steal time % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine&lt;br /&gt;
&lt;br /&gt;
== '''Process table''' ==&lt;br /&gt;
The column headings in the process list are as follows:&lt;br /&gt;
&lt;br /&gt;
'''PID''': Process ID.&lt;br /&gt;
&lt;br /&gt;
'''USER''': The owner of the process.&lt;br /&gt;
&lt;br /&gt;
'''PR''': Process priority.&lt;br /&gt;
&lt;br /&gt;
'''NI''': The nice value of the process.&lt;br /&gt;
&lt;br /&gt;
'''VIRT''': Amount of virtual memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Virtual memory, labelled VIRT: How much memory your process thinks it’s using. Usually much bigger than RES, thanks to the Linux kernel’s clever memory management.&lt;br /&gt;
&lt;br /&gt;
This includes swapped memory, the memory from external libraries, and allocated memory that’s not used.&lt;br /&gt;
&lt;br /&gt;
'''RES''': Amount of resident memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Resident memory, labelled RES: How much physical memory, how much RAM, your process is using. RES is the important number.&lt;br /&gt;
&lt;br /&gt;
This includes memory allocated from shared libraries, given they are still present in memory. Also, it includes all heap and stack memory.&lt;br /&gt;
&lt;br /&gt;
'''SHR''': Amount of shared memory used by the process.&lt;br /&gt;
&lt;br /&gt;
'''S''': Status of the process. (See the list below for the values this field can take).&lt;br /&gt;
&lt;br /&gt;
'''%CPU''': The share of CPU time used by the process since the last update.&lt;br /&gt;
&lt;br /&gt;
'''%MEM''': The share of physical memory used.&lt;br /&gt;
&lt;br /&gt;
'''TIME+''': Total CPU time used by the task in hundredths of a second.&lt;br /&gt;
&lt;br /&gt;
'''COMMAND''': The command name or command line (name + options).&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1906</id>
		<title>Linux. Top</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1906"/>
		<updated>2024-11-26T20:30:48Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Linux]]&lt;br /&gt;
[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Shortcuts =&lt;br /&gt;
&lt;br /&gt;
=== Человеческое отображение объема памяти (human readable) ===&lt;br /&gt;
&amp;quot;'''e'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Отсортировать по памяти ===&lt;br /&gt;
&amp;quot;'''M'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Информация о процессе ===&lt;br /&gt;
&amp;lt;code&amp;gt;top -b -n 1 -p 1184&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TOP LEGEND =&lt;br /&gt;
&lt;br /&gt;
== '''%Cpu(s):''' ==&lt;br /&gt;
In &amp;quot;top&amp;quot; what are us, sy, ni, id, wa, hi, si and st (for CPU usage)?&lt;br /&gt;
&lt;br /&gt;
'''us''' - user cpu time (or) % CPU time spent in user space&lt;br /&gt;
&lt;br /&gt;
'''sy''' - system cpu time (or) % CPU time spent in kernel space&lt;br /&gt;
&lt;br /&gt;
'''ni''' - user nice cpu time (or) % CPU time spent on low priority processes&lt;br /&gt;
&lt;br /&gt;
'''id''' - idle cpu time (or) % CPU time spent idle&lt;br /&gt;
&lt;br /&gt;
'''wa''' - io wait cpu time (or) % CPU time spent in wait (on disk)&lt;br /&gt;
&lt;br /&gt;
'''hi''' - hardware irq (or) % CPU time spent servicing/handling hardware interrupts&lt;br /&gt;
&lt;br /&gt;
'''si''' - software irq (or) % CPU time spent servicing/handling software interrupts&lt;br /&gt;
&lt;br /&gt;
'''st''' - steal time % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine&lt;br /&gt;
&lt;br /&gt;
== '''Process table''' ==&lt;br /&gt;
The column headings in the process list are as follows:&lt;br /&gt;
&lt;br /&gt;
'''PID''': Process ID.&lt;br /&gt;
&lt;br /&gt;
'''USER''': The owner of the process.&lt;br /&gt;
&lt;br /&gt;
'''PR''': Process priority.&lt;br /&gt;
&lt;br /&gt;
'''NI''': The nice value of the process.&lt;br /&gt;
&lt;br /&gt;
'''VIRT''': Amount of virtual memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Virtual memory, labelled VIRT: How much memory your process thinks it’s using. Usually much bigger than RES, thanks to the Linux kernel’s clever memory management.&lt;br /&gt;
&lt;br /&gt;
'''RES''': Amount of resident memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Resident memory, labelled RES: How much physical memory, how much RAM, your process is using. RES is the important number.&lt;br /&gt;
&lt;br /&gt;
'''SHR''': Amount of shared memory used by the process.&lt;br /&gt;
&lt;br /&gt;
'''S''': Status of the process. (See the list below for the values this field can take).&lt;br /&gt;
&lt;br /&gt;
'''%CPU''': The share of CPU time used by the process since the last update.&lt;br /&gt;
&lt;br /&gt;
'''%MEM''': The share of physical memory used.&lt;br /&gt;
&lt;br /&gt;
'''TIME+''': Total CPU time used by the task in hundredths of a second.&lt;br /&gt;
&lt;br /&gt;
'''COMMAND''': The command name or command line (name + options).&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1905</id>
		<title>Linux. Top</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1905"/>
		<updated>2024-11-26T20:29:15Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Linux]]&lt;br /&gt;
[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Shortcuts =&lt;br /&gt;
&lt;br /&gt;
=== Человеческое отображение объема памяти (human readable) ===&lt;br /&gt;
&amp;quot;'''e'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Отсортировать по памяти ===&lt;br /&gt;
&amp;quot;'''M'''&amp;quot; в процессе работы top&lt;br /&gt;
&lt;br /&gt;
=== Информация о процессе ===&lt;br /&gt;
&amp;lt;code&amp;gt;top -b -n 1 -p 1184&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TOP LEGEND =&lt;br /&gt;
&lt;br /&gt;
== '''%Cpu(s):''' ==&lt;br /&gt;
In &amp;quot;top&amp;quot; what are us, sy, ni, id, wa, hi, si and st (for CPU usage)?&lt;br /&gt;
&lt;br /&gt;
'''us''' - user cpu time (or) % CPU time spent in user space&lt;br /&gt;
&lt;br /&gt;
'''sy''' - system cpu time (or) % CPU time spent in kernel space&lt;br /&gt;
&lt;br /&gt;
'''ni''' - user nice cpu time (or) % CPU time spent on low priority processes&lt;br /&gt;
&lt;br /&gt;
'''id''' - idle cpu time (or) % CPU time spent idle&lt;br /&gt;
&lt;br /&gt;
'''wa''' - io wait cpu time (or) % CPU time spent in wait (on disk)&lt;br /&gt;
&lt;br /&gt;
'''hi''' - hardware irq (or) % CPU time spent servicing/handling hardware interrupts&lt;br /&gt;
&lt;br /&gt;
'''si''' - software irq (or) % CPU time spent servicing/handling software interrupts&lt;br /&gt;
&lt;br /&gt;
'''st''' - steal time % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine&lt;br /&gt;
&lt;br /&gt;
== '''Process table''' ==&lt;br /&gt;
The column headings in the process list are as follows:&lt;br /&gt;
&lt;br /&gt;
'''PID''': Process ID.&lt;br /&gt;
&lt;br /&gt;
'''USER''': The owner of the process.&lt;br /&gt;
&lt;br /&gt;
'''PR''': Process priority.&lt;br /&gt;
&lt;br /&gt;
'''NI''': The nice value of the process.&lt;br /&gt;
&lt;br /&gt;
'''VIRT''': Amount of virtual memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Virtual memory, labelled VIRT: How much memory your process thinks it’s using. Usually much bigger than RES, thanks to the Linux kernel’s clever memory management.&lt;br /&gt;
&lt;br /&gt;
'''RES''': Amount of resident memory used by the process.&lt;br /&gt;
&lt;br /&gt;
    Resident memory, labelled RES: How much physical memory, how much RAM, your process is using. RES is the important number.&lt;br /&gt;
&lt;br /&gt;
'''SHR''': Amount of shared memory used by the process.&lt;br /&gt;
&lt;br /&gt;
'''S''': Status of the process. (See the list below for the values this field can take).&lt;br /&gt;
&lt;br /&gt;
'''%CPU''': The share of CPU time used by the process since the last update.&lt;br /&gt;
&lt;br /&gt;
'''%MEM''': The share of physical memory used.&lt;br /&gt;
&lt;br /&gt;
'''TIME+''': Total CPU time used by the task in hundredths of a second.&lt;br /&gt;
&lt;br /&gt;
'''COMMAND''': The command name or command line (name + options).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;--------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1904</id>
		<title>Linux. Top</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Top&amp;diff=1904"/>
		<updated>2024-11-26T20:26:41Z</updated>

		<summary type="html">&lt;p&gt;Cless: Новая страница: «Категория:Linux Категория:Self-education __ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Linux]]&lt;br /&gt;
[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1903</id>
		<title>Linux. Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1903"/>
		<updated>2024-11-26T19:45:42Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
Сигнал в операционных системах семейства Unix — асинхронное уведомление процесса о каком-либо событии, один из основных способов взаимодействия между процессами. Когда сигнал послан процессу, операционная система прерывает выполнение процесса, при этом, если процесс установил собственный ''обработчик сигнала'', операционная система запускает этот обработчик, передав ему информацию о сигнале, если процесс не установил обработчик, то выполняется обработчик по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Названия сигналов «SIG…» являются числовыми константами (макроопределениями Си) со значениями, определяемыми в заголовочном файле &amp;lt;code&amp;gt;signal.h&amp;lt;/code&amp;gt;. Числовые значения сигналов могут меняться от системы к системе, хотя основная их часть имеет в разных системах одни и те же значения. Утилита &amp;lt;code&amp;gt;kill&amp;lt;/code&amp;gt; позволяет задавать сигнал как числом, так и символьным обозначением.&lt;br /&gt;
&lt;br /&gt;
Спецификация сигналов включена в стандарты POSIX.&lt;br /&gt;
&lt;br /&gt;
== Посылка сигналов ==&lt;br /&gt;
&lt;br /&gt;
Сигналы посылаются:&lt;br /&gt;
&lt;br /&gt;
* из терминала, нажатием специальных клавиш или комбинаций (например, нажатие Ctrl-C генерирует SIGINT, Ctrl-\ SIGQUIT, а Ctrl-Z SIGTSTP);&lt;br /&gt;
* ядром системы:&lt;br /&gt;
** при возникновении аппаратных исключений (недопустимых инструкций, нарушениях при обращении в память, системных сбоях и т. п.);&lt;br /&gt;
** ошибочных системных вызовах;&lt;br /&gt;
** для информирования о событиях ввода-вывода;&lt;br /&gt;
* одним процессом другому (или самому себе), с помощью системного вызова &amp;lt;code&amp;gt;kill()&amp;lt;/code&amp;gt;, в том числе:&lt;br /&gt;
** из shell, утилитой &amp;lt;code&amp;gt;/bin/kill&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сигналы не могут быть посланы завершившемуся процессу, находящемуся в состоянии «зомби».&lt;br /&gt;
&lt;br /&gt;
== Обработка сигналов ==&lt;br /&gt;
&lt;br /&gt;
Обработчик по умолчанию для большинства сигналов завершает выполнение процесса. Для альтернативной обработки всех сигналов, за исключением SIGKILL и SIGSTOP, процесс может назначить свой обработчик или игнорировать их возникновение модификацией своей ''сигнальной маски''. Единственное исключение — процесс с pid 1 (init), который имеет право игнорировать или обрабатывать любые сигналы, включая KILL и STOP.&lt;br /&gt;
&lt;br /&gt;
== Безопасность ==&lt;br /&gt;
&lt;br /&gt;
Процесс (или пользователь из оболочки) с эффективным UID, не равным 0 (UID суперпользователя), может посылать сигналы только процессам с тем же UID.&lt;br /&gt;
&lt;br /&gt;
== Классификация сигналов ==&lt;br /&gt;
&lt;br /&gt;
POSIX определяет 28 сигналов, которые можно классифицировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Название&lt;br /&gt;
!Портируемый код&lt;br /&gt;
!Действие по умолчанию&lt;br /&gt;
!Описание&lt;br /&gt;
!Тип&lt;br /&gt;
|-&lt;br /&gt;
|SIGABRT&lt;br /&gt;
|6&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал, посылаемый функцией &amp;lt;code&amp;gt;abort()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGALRM&lt;br /&gt;
|14&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал истечения времени, заданного &amp;lt;code&amp;gt;alarm()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGBUS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильное обращение в физическую память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGCHLD&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|Дочерний процесс завершен или остановлен&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGCONT&lt;br /&gt;
|—&lt;br /&gt;
|Продолжить выполнение&lt;br /&gt;
|Продолжить выполнение ранее остановленного процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGFPE&lt;br /&gt;
|8&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ошибочная арифметическая операция&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGHUP&lt;br /&gt;
|1&lt;br /&gt;
|Завершение&lt;br /&gt;
|Закрытие терминала&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGILL&lt;br /&gt;
|4&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Недопустимая инструкция процессора&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGINT&lt;br /&gt;
|2&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал прерывания (Ctrl-C) с терминала&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|'''SIGKILL'''&lt;br /&gt;
|'''9'''&lt;br /&gt;
|'''Завершение'''&lt;br /&gt;
|'''Безусловное завершение'''&lt;br /&gt;
|'''Управление'''&lt;br /&gt;
|-&lt;br /&gt;
|SIGPIPE&lt;br /&gt;
|13&lt;br /&gt;
|Завершение&lt;br /&gt;
|Запись в разорванное соединение (пайп, сокет)&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGQUIT&lt;br /&gt;
|3&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал «Quit» с терминала (Ctrl-\)&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGSEGV&lt;br /&gt;
|11&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Нарушение при обращении в память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGSTOP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Остановка выполнения процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|'''SIGTERM'''&lt;br /&gt;
|'''15'''&lt;br /&gt;
|'''Завершение'''&lt;br /&gt;
|'''Сигнал завершения (сигнал по умолчанию для утилиты kill)'''&lt;br /&gt;
|'''Управление'''&lt;br /&gt;
|-&lt;br /&gt;
|SIGTSTP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Сигнал остановки с терминала (Ctrl-Z).&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTIN&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка чтения с терминала фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTOU&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка записи на терминал фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR1&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 1&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR2&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 2&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGPOLL&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Событие, отслеживаемое &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGPROF&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение таймера профилирования&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGSYS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильный системный вызов&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGTRAP&lt;br /&gt;
|5&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ловушка трассировки или брейкпоинт&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGURG&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|На сокете получены срочные данные&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGVTALRM&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение «виртуального таймера»&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGXCPU&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил лимит процессорного времени&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGXFSZ&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил допустимый размер файла&lt;br /&gt;
|Исключение&lt;br /&gt;
|+&lt;br /&gt;
|}&lt;br /&gt;
Также есть сигналы, не определённые в POSIX, но присутствующие на некоторых операционных системах.&lt;br /&gt;
&lt;br /&gt;
* SIGEMT&lt;br /&gt;
* [[SIGINFO&amp;amp;action=edit&amp;amp;redlink=1|SIGINFO]]. Посылается процессу, когда запрос статуса (info) получен от управляющего терминала.&lt;br /&gt;
* SIGPWR&lt;br /&gt;
* SIGLOST&lt;br /&gt;
* SIGWINCH&lt;br /&gt;
* SIGSTKFLT&lt;br /&gt;
* SIGUNUSED&lt;br /&gt;
* SIGCLD&lt;br /&gt;
&lt;br /&gt;
При обработке исключений и отладочных сигналов перед завершением процесс может записать в текущий каталог файл с дампом памяти процесса (англ. core image), используя который, отладчик может восстановить условия, при которых возникло данное исключение. Иногда (например, для программ, выполняемых от имени суперпользователя) дамп памяти не создаётся из соображений безопасности.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1902</id>
		<title>Linux. Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1902"/>
		<updated>2024-11-26T19:42:52Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
Сигнал в операционных системах семейства Unix — асинхронное уведомление процесса о каком-либо событии, один из основных способов взаимодействия между процессами. Когда сигнал послан процессу, операционная система прерывает выполнение процесса, при этом, если процесс установил собственный ''обработчик сигнала'', операционная система запускает этот обработчик, передав ему информацию о сигнале, если процесс не установил обработчик, то выполняется обработчик по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Названия сигналов «SIG…» являются числовыми константами (макроопределениями Си) со значениями, определяемыми в заголовочном файле &amp;lt;code&amp;gt;signal.h&amp;lt;/code&amp;gt;. Числовые значения сигналов могут меняться от системы к системе, хотя основная их часть имеет в разных системах одни и те же значения. Утилита &amp;lt;code&amp;gt;kill&amp;lt;/code&amp;gt; позволяет задавать сигнал как числом, так и символьным обозначением.&lt;br /&gt;
&lt;br /&gt;
Спецификация сигналов включена в стандарты POSIX.&lt;br /&gt;
&lt;br /&gt;
== Посылка сигналов ==&lt;br /&gt;
&lt;br /&gt;
Сигналы посылаются:&lt;br /&gt;
&lt;br /&gt;
* из терминала, нажатием специальных клавиш или комбинаций (например, нажатие Ctrl-C генерирует SIGINT, Ctrl-\ SIGQUIT, а Ctrl-Z SIGTSTP);&lt;br /&gt;
* ядром системы:&lt;br /&gt;
** при возникновении аппаратных исключений (недопустимых инструкций, нарушениях при обращении в память, системных сбоях и т. п.);&lt;br /&gt;
** ошибочных системных вызовах;&lt;br /&gt;
** для информирования о событиях ввода-вывода;&lt;br /&gt;
* одним процессом другому (или самому себе), с помощью системного вызова &amp;lt;code&amp;gt;kill()&amp;lt;/code&amp;gt;, в том числе:&lt;br /&gt;
** из shell, утилитой &amp;lt;code&amp;gt;/bin/kill&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сигналы не могут быть посланы завершившемуся процессу, находящемуся в состоянии «зомби».&lt;br /&gt;
&lt;br /&gt;
== Обработка сигналов ==&lt;br /&gt;
&lt;br /&gt;
Обработчик по умолчанию для большинства сигналов завершает выполнение процесса. Для альтернативной обработки всех сигналов, за исключением SIGKILL и SIGSTOP, процесс может назначить свой обработчик или игнорировать их возникновение модификацией своей ''сигнальной маски''. Единственное исключение — процесс с pid 1 (init), который имеет право игнорировать или обрабатывать любые сигналы, включая KILL и STOP.&lt;br /&gt;
&lt;br /&gt;
== Безопасность ==&lt;br /&gt;
&lt;br /&gt;
Процесс (или пользователь из оболочки) с эффективным UID, не равным 0 (UID суперпользователя), может посылать сигналы только процессам с тем же UID.&lt;br /&gt;
&lt;br /&gt;
== Классификация сигналов ==&lt;br /&gt;
&lt;br /&gt;
POSIX определяет 28 сигналов, которые можно классифицировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Название&lt;br /&gt;
!Портируемый код&lt;br /&gt;
!Действие по умолчанию&lt;br /&gt;
!Описание&lt;br /&gt;
!Тип&lt;br /&gt;
|-&lt;br /&gt;
|SIGABRT&lt;br /&gt;
|6&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал, посылаемый функцией &amp;lt;code&amp;gt;abort()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGALRM&lt;br /&gt;
|14&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал истечения времени, заданного &amp;lt;code&amp;gt;alarm()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGBUS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильное обращение в физическую память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGCHLD&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|Дочерний процесс завершен или остановлен&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGCONT&lt;br /&gt;
|—&lt;br /&gt;
|Продолжить выполнение&lt;br /&gt;
|Продолжить выполнение ранее остановленного процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGFPE&lt;br /&gt;
|8&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ошибочная арифметическая операция&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGHUP&lt;br /&gt;
|1&lt;br /&gt;
|Завершение&lt;br /&gt;
|Закрытие терминала&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGILL&lt;br /&gt;
|4&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Недопустимая инструкция процессора&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGINT&lt;br /&gt;
|2&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал прерывания (Ctrl-C) с терминала&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGKILL&lt;br /&gt;
|9&lt;br /&gt;
|Завершение&lt;br /&gt;
|Безусловное завершение&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGPIPE&lt;br /&gt;
|13&lt;br /&gt;
|Завершение&lt;br /&gt;
|Запись в разорванное соединение (пайп, сокет)&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGQUIT&lt;br /&gt;
|3&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал «Quit» с терминала (Ctrl-\)&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGSEGV&lt;br /&gt;
|11&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Нарушение при обращении в память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGSTOP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Остановка выполнения процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTERM&lt;br /&gt;
|15&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал завершения (сигнал по умолчанию для утилиты kill)&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTSTP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Сигнал остановки с терминала (Ctrl-Z).&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTIN&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка чтения с терминала фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTOU&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка записи на терминал фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR1&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 1&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR2&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 2&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGPOLL&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Событие, отслеживаемое &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGPROF&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение таймера профилирования&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGSYS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильный системный вызов&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGTRAP&lt;br /&gt;
|5&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ловушка трассировки или брейкпоинт&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGURG&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|На сокете получены срочные данные&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGVTALRM&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение «виртуального таймера»&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGXCPU&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил лимит процессорного времени&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGXFSZ&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил допустимый размер файла&lt;br /&gt;
|Исключение&lt;br /&gt;
|+&lt;br /&gt;
|}&lt;br /&gt;
Также есть сигналы, не определённые в POSIX, но присутствующие на некоторых операционных системах.&lt;br /&gt;
&lt;br /&gt;
* SIGEMT&lt;br /&gt;
* [[SIGINFO&amp;amp;action=edit&amp;amp;redlink=1|SIGINFO]]. Посылается процессу, когда запрос статуса (info) получен от управляющего терминала.&lt;br /&gt;
* SIGPWR&lt;br /&gt;
* SIGLOST&lt;br /&gt;
* SIGWINCH&lt;br /&gt;
* SIGSTKFLT&lt;br /&gt;
* SIGUNUSED&lt;br /&gt;
* SIGCLD&lt;br /&gt;
&lt;br /&gt;
При обработке исключений и отладочных сигналов перед завершением процесс может записать в текущий каталог файл с дампом памяти процесса (англ. core image), используя который, отладчик может восстановить условия, при которых возникло данное исключение. Иногда (например, для программ, выполняемых от имени суперпользователя) дамп памяти не создаётся из соображений безопасности.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1901</id>
		<title>Linux. Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1901"/>
		<updated>2024-11-26T19:41:58Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
Сигнал в операционных системах семейства Unix — асинхронное уведомление процесса о каком-либо событии, один из основных способов взаимодействия между процессами. Когда сигнал послан процессу, операционная система прерывает выполнение процесса, при этом, если процесс установил собственный ''обработчик сигнала'', операционная система запускает этот обработчик, передав ему информацию о сигнале, если процесс не установил обработчик, то выполняется обработчик по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Названия сигналов «SIG…» являются числовыми константами (макроопределениями Си) со значениями, определяемыми в заголовочном файле &amp;lt;code&amp;gt;signal.h&amp;lt;/code&amp;gt;. Числовые значения сигналов могут меняться от системы к системе, хотя основная их часть имеет в разных системах одни и те же значения. Утилита &amp;lt;code&amp;gt;kill&amp;lt;/code&amp;gt; позволяет задавать сигнал как числом, так и символьным обозначением.&lt;br /&gt;
&lt;br /&gt;
Спецификация сигналов включена в стандарты POSIX.&lt;br /&gt;
&lt;br /&gt;
== Содержание ==&lt;br /&gt;
&lt;br /&gt;
* 1Посылка сигналов&lt;br /&gt;
* 2Обработка сигналов&lt;br /&gt;
* 3Безопасность&lt;br /&gt;
* 4Классификация сигналов&lt;br /&gt;
* 5SA_SIGINFO&lt;br /&gt;
* 6Ссылки&lt;br /&gt;
&lt;br /&gt;
== Посылка сигналов ==&lt;br /&gt;
[&amp;lt;nowiki/&amp;gt;[[Сигнал (Unix)&amp;amp;veaction=edit&amp;amp;section=1|править]] | [[Сигнал (Unix)&amp;amp;action=edit&amp;amp;section=1|править код]]]&lt;br /&gt;
&lt;br /&gt;
Сигналы посылаются:&lt;br /&gt;
&lt;br /&gt;
* из терминала, нажатием специальных клавиш или комбинаций (например, нажатие Ctrl-C генерирует SIGINT, Ctrl-\ SIGQUIT, а Ctrl-Z SIGTSTP);&lt;br /&gt;
* ядром системы:&lt;br /&gt;
** при возникновении аппаратных исключений (недопустимых инструкций, нарушениях при обращении в память, системных сбоях и т. п.);&lt;br /&gt;
** ошибочных системных вызовах;&lt;br /&gt;
** для информирования о событиях ввода-вывода;&lt;br /&gt;
* одним процессом другому (или самому себе), с помощью системного вызова &amp;lt;code&amp;gt;kill()&amp;lt;/code&amp;gt;, в том числе:&lt;br /&gt;
** из shell, утилитой &amp;lt;code&amp;gt;/bin/kill&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сигналы не могут быть посланы завершившемуся процессу, находящемуся в состоянии «зомби».&lt;br /&gt;
&lt;br /&gt;
== Обработка сигналов ==&lt;br /&gt;
[&amp;lt;nowiki/&amp;gt;[[Сигнал (Unix)&amp;amp;veaction=edit&amp;amp;section=2|править]] | [[Сигнал (Unix)&amp;amp;action=edit&amp;amp;section=2|править код]]]&lt;br /&gt;
&lt;br /&gt;
Обработчик по умолчанию для большинства сигналов завершает выполнение процесса. Для альтернативной обработки всех сигналов, за исключением SIGKILL и SIGSTOP, процесс может назначить свой обработчик или игнорировать их возникновение модификацией своей ''сигнальной маски''. Единственное исключение — процесс с pid 1 (init), который имеет право игнорировать или обрабатывать любые сигналы, включая KILL и STOP.&lt;br /&gt;
&lt;br /&gt;
== Безопасность ==&lt;br /&gt;
[&amp;lt;nowiki/&amp;gt;[[Сигнал (Unix)&amp;amp;veaction=edit&amp;amp;section=3|править]] | [[Сигнал (Unix)&amp;amp;action=edit&amp;amp;section=3|править код]]]&lt;br /&gt;
&lt;br /&gt;
Процесс (или пользователь из оболочки) с эффективным UID, не равным 0 (UID суперпользователя), может посылать сигналы только процессам с тем же UID.&lt;br /&gt;
&lt;br /&gt;
== Классификация сигналов ==&lt;br /&gt;
[&amp;lt;nowiki/&amp;gt;[[Сигнал (Unix)&amp;amp;veaction=edit&amp;amp;section=4|править]] | [[Сигнал (Unix)&amp;amp;action=edit&amp;amp;section=4|править код]]]&lt;br /&gt;
&lt;br /&gt;
POSIX определяет 28 сигналов, которые можно классифицировать следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Название&lt;br /&gt;
!Портируемый код&lt;br /&gt;
!Действие по умолчанию&lt;br /&gt;
!Описание&lt;br /&gt;
!Тип&lt;br /&gt;
|-&lt;br /&gt;
|SIGABRT&lt;br /&gt;
|6&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал, посылаемый функцией &amp;lt;code&amp;gt;abort()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGALRM&lt;br /&gt;
|14&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал истечения времени, заданного &amp;lt;code&amp;gt;alarm()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGBUS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильное обращение в физическую память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGCHLD&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|Дочерний процесс завершен или остановлен&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGCONT&lt;br /&gt;
|—&lt;br /&gt;
|Продолжить выполнение&lt;br /&gt;
|Продолжить выполнение ранее остановленного процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGFPE&lt;br /&gt;
|8&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ошибочная арифметическая операция&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGHUP&lt;br /&gt;
|1&lt;br /&gt;
|Завершение&lt;br /&gt;
|Закрытие терминала&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGILL&lt;br /&gt;
|4&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Недопустимая инструкция процессора&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGINT&lt;br /&gt;
|2&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал прерывания (Ctrl-C) с терминала&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGKILL&lt;br /&gt;
|9&lt;br /&gt;
|Завершение&lt;br /&gt;
|Безусловное завершение&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGPIPE&lt;br /&gt;
|13&lt;br /&gt;
|Завершение&lt;br /&gt;
|Запись в разорванное соединение (пайп, сокет)&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGQUIT&lt;br /&gt;
|3&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Сигнал «Quit» с терминала (Ctrl-\)&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGSEGV&lt;br /&gt;
|11&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Нарушение при обращении в память&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGSTOP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Остановка выполнения процесса&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTERM&lt;br /&gt;
|15&lt;br /&gt;
|Завершение&lt;br /&gt;
|Сигнал завершения (сигнал по умолчанию для утилиты kill)&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTSTP&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Сигнал остановки с терминала (Ctrl-Z).&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTIN&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка чтения с терминала фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGTTOU&lt;br /&gt;
|—&lt;br /&gt;
|Остановка процесса&lt;br /&gt;
|Попытка записи на терминал фоновым процессом&lt;br /&gt;
|Управление&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR1&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 1&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGUSR2&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Пользовательский сигнал № 2&lt;br /&gt;
|Пользовательский&lt;br /&gt;
|-&lt;br /&gt;
|SIGPOLL&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Событие, отслеживаемое &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGPROF&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение таймера профилирования&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGSYS&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Неправильный системный вызов&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGTRAP&lt;br /&gt;
|5&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Ловушка трассировки или брейкпоинт&lt;br /&gt;
|Отладка&lt;br /&gt;
|-&lt;br /&gt;
|SIGURG&lt;br /&gt;
|—&lt;br /&gt;
|Игнорируется&lt;br /&gt;
|На сокете получены срочные данные&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGVTALRM&lt;br /&gt;
|—&lt;br /&gt;
|Завершение&lt;br /&gt;
|Истечение «виртуального таймера»&lt;br /&gt;
|Уведомление&lt;br /&gt;
|-&lt;br /&gt;
|SIGXCPU&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил лимит процессорного времени&lt;br /&gt;
|Исключение&lt;br /&gt;
|-&lt;br /&gt;
|SIGXFSZ&lt;br /&gt;
|—&lt;br /&gt;
|Завершение с дампом памяти&lt;br /&gt;
|Процесс превысил допустимый размер файла&lt;br /&gt;
|Исключение&lt;br /&gt;
|+&lt;br /&gt;
|}&lt;br /&gt;
Также есть сигналы, не определённые в POSIX, но присутствующие на некоторых операционных системах.&lt;br /&gt;
&lt;br /&gt;
* SIGEMT&lt;br /&gt;
* [[SIGINFO&amp;amp;action=edit&amp;amp;redlink=1|SIGINFO]]. Посылается процессу, когда запрос статуса (info) получен от управляющего терминала.&lt;br /&gt;
* SIGPWR&lt;br /&gt;
* SIGLOST&lt;br /&gt;
* SIGWINCH&lt;br /&gt;
* SIGSTKFLT&lt;br /&gt;
* SIGUNUSED&lt;br /&gt;
* SIGCLD&lt;br /&gt;
&lt;br /&gt;
При обработке исключений и отладочных сигналов перед завершением процесс может записать в текущий каталог файл с дампом памяти процесса (англ. core image), используя который, отладчик может восстановить условия, при которых возникло данное исключение. Иногда (например, для программ, выполняемых от имени суперпользователя) дамп памяти не создаётся из соображений безопасности.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1900</id>
		<title>Linux. Signals</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Signals&amp;diff=1900"/>
		<updated>2024-11-26T19:41:41Z</updated>

		<summary type="html">&lt;p&gt;Cless: Новая страница: «Категория:Self-education __ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._OOM&amp;diff=1899</id>
		<title>Linux. OOM</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._OOM&amp;diff=1899"/>
		<updated>2024-11-26T19:29:23Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= Что такое OOM Killer и как он работает =&lt;br /&gt;
OOM Killer, пожалуй, одна из немногих технологий в Linux, овеянная мифами и легендами. Часто из уст в уста передаются истории, претендующие на хороший триллер. На самом деле все гораздо проще и прозаичнее, а работа OOM Killer подчиняется строгим правилам. Cегодня мы попробуем разобраться в том, что такое OOM Killer и для чего он предназначен, а также разберемся как он работает и по каким критериям выбирает процессы для завершения. Поэтому, если OOM Killer для вас все еще мифический и непонятный черный ящик, то обязательно прочитайте эту статью.&lt;br /&gt;
&lt;br /&gt;
Начнем с начала, т.е. с выделения памяти в Linux. Любой запущенный процесс получает собственный выделенный участок памяти. Но этот участок не отображается на доступные физические адреса, а использует виртуальное адресное пространство, которое является дополнительным слоем абстракции между процессом и физической памятью. Для сопоставления адресов между виртуальной и физической памятью используются специальные структуры - таблицы страниц.&lt;br /&gt;
&lt;br /&gt;
Что это дает? Во-первых, изоляцию процессов друг от друга, каждый из них работает в собственном виртуальном адресном пространстве и не имеет доступа к памяти других процессов. Во-вторых, позволяет системе гибко управлять физической памятью, например, для неактивного процесса часть страниц может быть перенесено из оперативной памяти в пространства подкачки, но это никак не повлияет на работу самого процесса, его адресное пространство не изменится, поменяется лишь трансляция в таблице страниц. И, наконец, это позволяет экономить физическую память, так если несколько процессов используют одни и те же данные, то система может транслировать адреса виртуальных пространств на один и тот же участок физической памяти.&lt;br /&gt;
&lt;br /&gt;
Таким образом размер виртуальной памяти в системе теоретически ничем не ограничен и общий ее объем может существенно превышать имеющуюся в наличии физическую память. И в этом нет ничего плохого, например, мы запустили несколько графических приложений, для работы которым требуются библиотеки Qt или GTK, но нужно ли каждый раз загружать их в память? Нет, достаточно сделать это один раз, а затем просто транслировать адреса виртуальной памяти процессов на одни и те же участки физической памяти. Но при этом каждый процесс будет думать, что у него загружена собственная копия библиотек.&lt;br /&gt;
&lt;br /&gt;
Поэтому современные Linux-системы выделяют память процессам с превышением имеющейся в наличии физической памяти (RAM + Swap), по умолчанию используя эвристические механизмы. Но случается, что процессы съедают всю доступную физическую память и вот тут системе надо выбрать что-то одно. А выбор, скажем честно, между плохим или очень плохим. Можно убить один из процессов и продолжить работать дальше, а можно вызвать Kernel panic. Понятно, что последнее - это совсем ни в какие ворота, поэтому на сцену выходит OOM Killer, это поведение используется в современных Linux системах по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Но кого же убьет OOM Killer? Бытует ошибочное мнение, что самый &amp;quot;толстый&amp;quot; процесс, занимающий самое большое количество памяти, однако это не так. Хотя заблуждения живучи, и народная молва рисует OOM Killer в виде ковбоя, врывающегося в переполненный салун и открывающий беспорядочную стрельбу по посетителям, преимущественно по толстым. Почему? Да попасть, наверное, проще...&lt;br /&gt;
&lt;br /&gt;
На самом деле OOM Killer использует достаточно сложный анализ и присваивает каждому процессу очки негодности (badness) и при исчерпании памяти будет убит не кто-попало, а самый негодный процесс. Очки негодности могут принимать значения от -1000 до 1000, чем выше значение, тем более высока вероятность что OOM Killer убьет процесс. Процесс с -1000 очков никогда не будет убит OOM Killer.&lt;br /&gt;
&lt;br /&gt;
Как вычисляются очки негодности? За основу берется процент физической памяти используемый процессом и умножается на 10, таким образом получаем базовое значение. Нетрудно заметить, что 1000 очков - это 100% использования памяти. Затем к данному значению начинают применяться различные модификаторы:&lt;br /&gt;
&lt;br /&gt;
Прибавляется половина очков всех дочерних процессов, имеющих собственную виртуальную память.&lt;br /&gt;
&lt;br /&gt;
Если приоритет процесса больше нуля очки умножаются на два. Приоритет может иметь значение от -20 (наивысший приоритет) до 20 (самый низкий).&lt;br /&gt;
&lt;br /&gt;
Очки делятся на коэффициент, связанный с процессорным временем, чем более активен процесс и чем больше процессорного времени он использует, тем больше будет этот коэффициент.&lt;br /&gt;
&lt;br /&gt;
Очки делятся на коэффициент, связанный с временем жизни процесса, чем больше времени прошло с момента запуска, тем выше будет это значение.&lt;br /&gt;
&lt;br /&gt;
Для процессов, запущенных от имени root, обслуживающих систему или процессов ввода-вывода очки делятся на 4.&lt;br /&gt;
&lt;br /&gt;
Для процесса, при выделении памяти которому произошла ошибка out of memory и процессам имеющим с ним общую память, очки делятся на 8.&lt;br /&gt;
&lt;br /&gt;
Очки умножаются на 2^oom_adj, где oom_adj - специальный коэффициент, имеющий значения от -17 до 15, при -17 процесс никогда не будет убить OOM Killer.&lt;br /&gt;
&lt;br /&gt;
Если внимательно изучить эти критерии, то становится ясно, что:&amp;lt;blockquote&amp;gt;  !!!&lt;br /&gt;
&lt;br /&gt;
  OOM Killer убьет '''самый &amp;quot;толстый&amp;quot; процесс''', который '''наименее активен в системе''' и имеет '''самое короткое время жизни'''&lt;br /&gt;
&lt;br /&gt;
  !!!&amp;lt;/blockquote&amp;gt;Согласитесь, это не тоже самое, что убить процесс с самым большим потреблением памяти. Такой подход позволяет достаточно эффективно бороться с утечкой памяти в кривых приложениях, минимизируя их влияние на систему.&lt;br /&gt;
&lt;br /&gt;
Не так давно нам пришлось разбираться с ситуацией: в Linux Mint начал подвисать и падать браузер Chrome. Анализ ситуации выявил, что пользователь поставил стороннее расширение, которое приводило к утечке памяти и зависанию браузера, после чего на сцену выходил OOM Killer и убивал процесс. При этом параллельно были открыты процессы, которые потребляли больше памяти, чем утекало через Chrome, но OOM Killer их не трогал.&lt;br /&gt;
&lt;br /&gt;
В системах виртуализации это будет неактивная виртуалка с наибольшим выделением памяти. Поэтому если у вас регулярно выключается одна из второстепенных машин - проверьте ситуацию с памятью, скорее всего это работа OOM Killer.&lt;br /&gt;
&lt;br /&gt;
Как узнать количество очков, присвоенных процессу? Довольно просто, выполните команду:&lt;br /&gt;
&lt;br /&gt;
    cat /proc/PID/oom_score&lt;br /&gt;
&lt;br /&gt;
Где PID - идентификатор процесса. При необходимости мы можем изменить количество очков используя коэффициент oom_adj:&lt;br /&gt;
&lt;br /&gt;
    echo -17 &amp;gt; /proc/PID/oom_adj&lt;br /&gt;
&lt;br /&gt;
В данном случае мы отправили процессу с указанным PID значение -17, т.е. обеспечили ему полную защиту от OOM Killer.&lt;br /&gt;
&lt;br /&gt;
Все это имеет один большой недостаток: применить коэффициент oom_adj мы можем только к запущенному процессу и по факту это ручная работа. Не следует применять эти методы на практике, кроме, разве что диагностики и отладки.&lt;br /&gt;
&lt;br /&gt;
В современных системах для управления службами используется systemd, который дает нам в руки простые и эффективные инструменты для управления очками негодности. Для этого в секцию [Service] юнита службы добавьте опцию:&lt;br /&gt;
&lt;br /&gt;
  [Service]&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  OOMScoreAdjust=-500&lt;br /&gt;
&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
Значение OOMScoreAdjust показывает насколько следует изменить количество очков процесса относительно рассчитанного количества, в нашем примере мы уменьшили его на 500. Таким образом мы можем защитить важные службы вашей системы от убийства со стороны OOM Killer, но не стоит злоупотреблять этой опцией, в критической ситуации будет лучше, если OOM Killer убьет даже важный процесс, но сохранит вам доступ к системе, нежели вы окажетесь в ситуации с полным исчерпанием физической памяти и недоступности или перезагрузки вашего сервера.&lt;br /&gt;
&lt;br /&gt;
В любом случае, если вы столкнулись с работой OOM Killer, то следует тщательно проанализировать причины нехватки физической памяти и принять необходимые меры.&lt;br /&gt;
&lt;br /&gt;
Надеемся, что после прочтения данной статьи OOM Killer перестанет быть для вас мифическим персонажем и вы будете понимать, что именно он делает, зачем и исходя из каких соображений. После чего он перестанет быть непредсказуемым черным ящиком, а станет вашим другом, помогающим сохранить работоспособность системы в критической ситуации нехватки ресурсов.&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._OOM&amp;diff=1898</id>
		<title>Linux. OOM</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._OOM&amp;diff=1898"/>
		<updated>2024-11-26T19:28:43Z</updated>

		<summary type="html">&lt;p&gt;Cless: Новая страница: «Категория:Self-education __ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1897</id>
		<title>Linux. File descriptor</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1897"/>
		<updated>2024-11-26T19:23:10Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
Когда процесс открывает файл, файлу присваивается ID, по нему процесс обращается к файлу&lt;br /&gt;
&lt;br /&gt;
Находим PID процесса&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[root@ekv01-zb001vvsl ~]# ps ax | grep maria&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    6222 ?        Ssl  2352:03 /usr/sbin/mariadbd&lt;br /&gt;
    ...&lt;br /&gt;
Просмотр файловых дескрипторов процесса mariadb&lt;br /&gt;
&lt;br /&gt;
// это символические ссылки&lt;br /&gt;
&lt;br /&gt;
// список&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls /proc/6222/fd/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// с ссылками на файлы каждого дескриптора&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /proc/6222/fd/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// посмотреть ссылку на файл конкретного дескриптора&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /proc/6222/fd/102&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 lrwx------ 1 mysql mysql 64 Aug 24 14:26 /proc/6222/fd/102 -&amp;gt; /app/data01/mysql/zabbix/hosts_templates.ibd&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;code&amp;gt;readlink /proc/6222/fd/102&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 /app/data01/mysql/zabbix/hosts_templates.ibd&lt;br /&gt;
 ...&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1896</id>
		<title>Linux. File descriptor</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1896"/>
		<updated>2024-11-26T19:21:54Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
Когда процесс открывает файл, файлу присваивается ID, по нему процесс обращается к файлу&lt;br /&gt;
&lt;br /&gt;
Находим PID процесса&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[root@ekv01-zb001vvsl ~]# ps ax | grep maria&amp;lt;/code&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    6222 ?        Ssl  2352:03 /usr/sbin/mariadbd&lt;br /&gt;
    ...&lt;br /&gt;
Просмотр файловых дескрипторов процесса mariadb&lt;br /&gt;
&lt;br /&gt;
// это символические ссылки&lt;br /&gt;
&lt;br /&gt;
// список&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls /proc/6222/fd/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// с ссылками на файлы каждого дескриптора&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /proc/6222/fd/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// посмотреть ссылку на файл конкретного дескриптора&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lh /proc/6222/fd/102&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 lrwx------ 1 mysql mysql 64 Aug 24 14:26 /proc/6222/fd/102 -&amp;gt; /app/data01/mysql/zabbix/hosts_templates.ibd&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;readlink /proc/6222/fd/102&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 /app/data01/mysql/zabbix/hosts_templates.ibd&lt;br /&gt;
 ...&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1895</id>
		<title>Linux. File descriptor</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._File_descriptor&amp;diff=1895"/>
		<updated>2024-11-26T19:20:44Z</updated>

		<summary type="html">&lt;p&gt;Cless: Новая страница: «Категория:Self-education __ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1894</id>
		<title>Linux. Files. Permissions</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1894"/>
		<updated>2024-11-26T19:16:52Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= File permissions =&lt;br /&gt;
&lt;br /&gt;
== What are octal values? ==&lt;br /&gt;
When Linux file permissions are represented by numbers, it's called numeric mode. In numeric mode, a three-digit value represents specific file permissions (for example, 744.) These are called octal values. The first digit is for owner permissions, the second digit is for group permissions, and the third is for other users. Each permission has a numeric value assigned to it:&lt;br /&gt;
&lt;br /&gt;
* r (read): 4&lt;br /&gt;
* w (write): 2&lt;br /&gt;
* x (execute): 1&lt;br /&gt;
&lt;br /&gt;
In the permission value 744, the first digit corresponds to the user, the second digit to the group, and the third digit to others. By adding up the value of each user classification, you can find the file permissions.&lt;br /&gt;
&lt;br /&gt;
For example, a file might have read, write, and execute permissions for its owner, and only read permission for all other users. That looks like this:&lt;br /&gt;
&lt;br /&gt;
* Owner: rwx = 4+2+1 = 7&lt;br /&gt;
* Group: r-- = 4+0+0 = 4&lt;br /&gt;
* Others: r-- = 4+0+0 = 4&lt;br /&gt;
&lt;br /&gt;
The results produce the three-digit value 744.&lt;br /&gt;
&lt;br /&gt;
= File types =&lt;br /&gt;
The file type is one of the following characters:&lt;br /&gt;
&lt;br /&gt;
    -  regular file&lt;br /&gt;
&lt;br /&gt;
    b  block special file&lt;br /&gt;
&lt;br /&gt;
    c  character special file (disk)&lt;br /&gt;
&lt;br /&gt;
    C  high performance (&amp;quot;contiguous data&amp;quot;) file&lt;br /&gt;
&lt;br /&gt;
    d  directory&lt;br /&gt;
&lt;br /&gt;
    D  door (Solaris 2.5 and up)&lt;br /&gt;
&lt;br /&gt;
    l  symbolic link&lt;br /&gt;
&lt;br /&gt;
    M  off-line (&amp;quot;migrated&amp;quot;) file (Cray DMF)&lt;br /&gt;
&lt;br /&gt;
    n  network special file (HP-UX)&lt;br /&gt;
&lt;br /&gt;
    p  FIFO (named pipe)&lt;br /&gt;
&lt;br /&gt;
    P  port (Solaris 10 and up)&lt;br /&gt;
&lt;br /&gt;
    s  socket&lt;br /&gt;
&lt;br /&gt;
    ?  some other file type&lt;br /&gt;
&lt;br /&gt;
= Посмотреть все аттрибуты файла =&lt;br /&gt;
&amp;lt;code&amp;gt;stat ./Тест.part03.rar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  File: «./Тест.part03.rar»&lt;br /&gt;
&lt;br /&gt;
  Size: 5146762   	Blocks: 10056      IO Block: 4096   обычный файл&lt;br /&gt;
&lt;br /&gt;
Device: 871h/2161d	Inode: 8650784     Links: 1&lt;br /&gt;
&lt;br /&gt;
Access: (0760/-rwxrw----)  Uid: ( 3131/tmb_chishko)   Gid: (  513/Domain Users)&lt;br /&gt;
&lt;br /&gt;
Access: 2019-11-08 13:14:28.768582082 +0400&lt;br /&gt;
&lt;br /&gt;
Modify: 2019-11-06 17:03:47.109375000 +0400&lt;br /&gt;
&lt;br /&gt;
Change: 2019-11-08 13:14:29.065585726 +0400&lt;br /&gt;
&lt;br /&gt;
= Timestamps =&lt;br /&gt;
    There are 3 kind of &amp;quot;timestamps&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
        Access - the last time the file was read&lt;br /&gt;
&lt;br /&gt;
        Modify - the last time the file was modified (content has been modified)&lt;br /&gt;
&lt;br /&gt;
        Change - the last time meta data of the file was changed (e.g. permissions)&lt;br /&gt;
&lt;br /&gt;
= Аттрибуты дополнительные =&lt;br /&gt;
Просмотреть аттрибуты&lt;br /&gt;
&lt;br /&gt;
// создадим файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим аттрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// создадим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr +i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// теперь даже root не сможет удалить этот файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;----&amp;lt;/nowiki&amp;gt;i--------e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// удалим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr -i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
= '''SUID, GUID''' =&lt;br /&gt;
&lt;br /&gt;
== Настройка Setuid ==&lt;br /&gt;
Setuid – это бит разрешения, который позволяет пользователю запускать исполняемый файл с правами владельца этого файла. Другими словами, использование этого бита позволяет нам поднять привилегии пользователя в случае, если это необходимо. Классический пример использования этого бита в операционной системе это команда sudo.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# which sudo /usr/bin/sudo&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l /usr/bin/sudo&lt;br /&gt;
 -rwsr-xr-x 1 root root 125308 Feb 20 14:15 /usr/bin/sudo&amp;lt;/code&amp;gt;&lt;br /&gt;
Как мы видим на месте, где обычно установлен классический бит x (на исполнение), у нас выставлен специальный бит s. Это позволяет обычному пользователю системы выполнять команды с повышенными привилегиями без необходимости входа в систему как root.&lt;br /&gt;
&lt;br /&gt;
Установка бита setuid не представляет сложности. Для этого используется команда:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s &amp;lt;filename&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Рассмотрим на примере. Создадим файл с именем ''myfile'', а затем проверим его разрешения с помощью команды ''ls -l''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# touch myfile&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 17:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Как видим, файл не имеет разрешений на выполнение для пользователя, группы и остальных. Добавим бит setuid:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s myfile &lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rwSrw-r-- 1 test test 0 Mar 25 12:00 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Обратим внимание, что вместо ожидаемой буквы «s», видим заглавную «S». Почему? Это случается, если setuid установлен, но сам владелец файла не имеет прав на его выполнение. Добавим это разрешение с помощью команды ''chmod u + x''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod u+x myfile &lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l &lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 12:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Настройка Setgid ==&lt;br /&gt;
Принцип работы Setgid очень похож на setuid с отличием, что файл будет запускаться пользователем от имени группы, которая владеет файлом. Иллюстрирует работу этого бита команда ''crontab'': .&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  which crontab&lt;br /&gt;
 /usr/bin/crontab&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l /usr/bin/crontab&lt;br /&gt;
 -rwxr-sr-x 1 root crontab 34021 Feb 12 2017 /usr/bin/crontab&amp;lt;/code&amp;gt;&lt;br /&gt;
Теперь перейдем к настройке этого бита. Аналогично setuid, бит setgid выставляется с помощью команды chmod g + s .&lt;br /&gt;
&lt;br /&gt;
Рассмотрим на примере создания нового файл с именем ''myfile2''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  touch myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Выполним команду ''chmod g + s'' и посмотрим результаты.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+s myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rwSr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Как разобрались выше, меняем заглавную « S » путем выдачи прав на исполнение группе-владельцу:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+x myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l&lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 19:25 myfile&lt;br /&gt;
 -rw-rwsr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= '''Sticky bit''' =&lt;br /&gt;
// благодаря таким правам удалить файл из TMP может только пользователь, который этот файл создал&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 1777 /tmp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -ld /tmp/&amp;lt;/code&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 drwxrwxrw'''t'''. 15 root root 4096 Sep 22 15:28 /tmp/&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
= Freebsd расширенные атрибуты =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/fs-acl.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// несмотря на полный доступ к файлам, они могут ни удаляться, ни переименовываться&lt;br /&gt;
&lt;br /&gt;
// или не изменяться права доступа даже из под root.&lt;br /&gt;
&lt;br /&gt;
// это значит что на файл установлены дополнительные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
// увидеть это можно через &amp;quot;ls -lao&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// &amp;quot;+&amp;quot; означает что на файле имеются расширенные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lao /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
-rwxrw-rw-+  1 root  wheel  uarch 17301 Jul  9 08:26 ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
// смотрим атрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxpD-aARWcCo-:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
// сбрасываем атрибуты&lt;br /&gt;
&lt;br /&gt;
// Параметр -k удалит все установленные на данный момент ACL из файла или файловой системы.&lt;br /&gt;
&lt;br /&gt;
// Более предпочтительный метод это использование параметра -b, который оставит необходимые для работы ACL поля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setfacl -b /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxp--aARWcCos:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;--------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1893</id>
		<title>Linux. Files. Permissions</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1893"/>
		<updated>2024-11-26T19:10:31Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= File permissions =&lt;br /&gt;
&lt;br /&gt;
== What are octal values? ==&lt;br /&gt;
When Linux file permissions are represented by numbers, it's called numeric mode. In numeric mode, a three-digit value represents specific file permissions (for example, 744.) These are called octal values. The first digit is for owner permissions, the second digit is for group permissions, and the third is for other users. Each permission has a numeric value assigned to it:&lt;br /&gt;
&lt;br /&gt;
* r (read): 4&lt;br /&gt;
* w (write): 2&lt;br /&gt;
* x (execute): 1&lt;br /&gt;
&lt;br /&gt;
In the permission value 744, the first digit corresponds to the user, the second digit to the group, and the third digit to others. By adding up the value of each user classification, you can find the file permissions.&lt;br /&gt;
&lt;br /&gt;
For example, a file might have read, write, and execute permissions for its owner, and only read permission for all other users. That looks like this:&lt;br /&gt;
&lt;br /&gt;
* Owner: rwx = 4+2+1 = 7&lt;br /&gt;
* Group: r-- = 4+0+0 = 4&lt;br /&gt;
* Others: r-- = 4+0+0 = 4&lt;br /&gt;
&lt;br /&gt;
The results produce the three-digit value 744.&lt;br /&gt;
&lt;br /&gt;
= File types =&lt;br /&gt;
The file type is one of the following characters:&lt;br /&gt;
&lt;br /&gt;
    -  regular file&lt;br /&gt;
&lt;br /&gt;
    b  block special file&lt;br /&gt;
&lt;br /&gt;
    c  character special file (disk)&lt;br /&gt;
&lt;br /&gt;
    C  high performance (&amp;quot;contiguous data&amp;quot;) file&lt;br /&gt;
&lt;br /&gt;
    d  directory&lt;br /&gt;
&lt;br /&gt;
    D  door (Solaris 2.5 and up)&lt;br /&gt;
&lt;br /&gt;
    l  symbolic link&lt;br /&gt;
&lt;br /&gt;
    M  off-line (&amp;quot;migrated&amp;quot;) file (Cray DMF)&lt;br /&gt;
&lt;br /&gt;
    n  network special file (HP-UX)&lt;br /&gt;
&lt;br /&gt;
    p  FIFO (named pipe)&lt;br /&gt;
&lt;br /&gt;
    P  port (Solaris 10 and up)&lt;br /&gt;
&lt;br /&gt;
    s  socket&lt;br /&gt;
&lt;br /&gt;
    ?  some other file type&lt;br /&gt;
&lt;br /&gt;
= Посмотреть все аттрибуты файла =&lt;br /&gt;
&amp;lt;code&amp;gt;stat ./Тест.part03.rar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  File: «./Тест.part03.rar»&lt;br /&gt;
&lt;br /&gt;
  Size: 5146762   	Blocks: 10056      IO Block: 4096   обычный файл&lt;br /&gt;
&lt;br /&gt;
Device: 871h/2161d	Inode: 8650784     Links: 1&lt;br /&gt;
&lt;br /&gt;
Access: (0760/-rwxrw----)  Uid: ( 3131/tmb_chishko)   Gid: (  513/Domain Users)&lt;br /&gt;
&lt;br /&gt;
Access: 2019-11-08 13:14:28.768582082 +0400&lt;br /&gt;
&lt;br /&gt;
Modify: 2019-11-06 17:03:47.109375000 +0400&lt;br /&gt;
&lt;br /&gt;
Change: 2019-11-08 13:14:29.065585726 +0400&lt;br /&gt;
&lt;br /&gt;
= Timestamps =&lt;br /&gt;
    There are 3 kind of &amp;quot;timestamps&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
        Access - the last time the file was read&lt;br /&gt;
&lt;br /&gt;
        Modify - the last time the file was modified (content has been modified)&lt;br /&gt;
&lt;br /&gt;
        Change - the last time meta data of the file was changed (e.g. permissions)&lt;br /&gt;
&lt;br /&gt;
= Аттрибуты дополнительные =&lt;br /&gt;
Просмотреть аттрибуты&lt;br /&gt;
&lt;br /&gt;
// создадим файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим аттрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// создадим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr +i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// теперь даже root не сможет удалить этот файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;----&amp;lt;/nowiki&amp;gt;i--------e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// удалим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr -i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
= '''SUID, GUID''' =&lt;br /&gt;
&lt;br /&gt;
== Настройка Setuid ==&lt;br /&gt;
Setuid – это бит разрешения, который позволяет пользователю запускать исполняемый файл с правами владельца этого файла. Другими словами, использование этого бита позволяет нам поднять привилегии пользователя в случае, если это необходимо. Классический пример использования этого бита в операционной системе это команда sudo.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# which sudo /usr/bin/sudo&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l /usr/bin/sudo&lt;br /&gt;
 -rwsr-xr-x 1 root root 125308 Feb 20 14:15 /usr/bin/sudo&amp;lt;/code&amp;gt;&lt;br /&gt;
Как мы видим на месте, где обычно установлен классический бит x (на исполнение), у нас выставлен специальный бит s. Это позволяет обычному пользователю системы выполнять команды с повышенными привилегиями без необходимости входа в систему как root.&lt;br /&gt;
&lt;br /&gt;
Установка бита setuid не представляет сложности. Для этого используется команда:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s &amp;lt;filename&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Рассмотрим на примере. Создадим файл с именем ''myfile'', а затем проверим его разрешения с помощью команды ''ls -l''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# touch myfile&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 17:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Как видим, файл не имеет разрешений на выполнение для пользователя, группы и остальных. Добавим бит setuid:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s myfile &lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rwSrw-r-- 1 test test 0 Mar 25 12:00 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Обратим внимание, что вместо ожидаемой буквы «s», видим заглавную «S». Почему? Это случается, если setuid установлен, но сам владелец файла не имеет прав на его выполнение. Добавим это разрешение с помощью команды ''chmod u + x''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod u+x myfile &lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l &lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 12:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Настройка Setgid ==&lt;br /&gt;
Принцип работы Setgid очень похож на setuid с отличием, что файл будет запускаться пользователем от имени группы, которая владеет файлом. Иллюстрирует работу этого бита команда ''crontab'': .&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  which crontab&lt;br /&gt;
 /usr/bin/crontab&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l /usr/bin/crontab&lt;br /&gt;
 -rwxr-sr-x 1 root crontab 34021 Feb 12 2017 /usr/bin/crontab&amp;lt;/code&amp;gt;&lt;br /&gt;
Теперь перейдем к настройке этого бита. Аналогично setuid, бит setgid выставляется с помощью команды chmod g + s .&lt;br /&gt;
&lt;br /&gt;
Рассмотрим на примере создания нового файл с именем ''myfile2''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  touch myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Выполним команду ''chmod g + s'' и посмотрим результаты.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+s myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rwSr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Как разобрались выше, меняем заглавную « S » путем выдачи прав на исполнение группе-владельцу:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+x myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l&lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 19:25 myfile&lt;br /&gt;
 -rw-rwsr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= '''Sticky bit''' =&lt;br /&gt;
// благодаря таким правам удалить файл из TMP может только пользователь, который этот файл создал&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 1777 /tmp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Freebsd расширенные атрибуты =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/fs-acl.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// несмотря на полный доступ к файлам, они могут ни удаляться, ни переименовываться&lt;br /&gt;
&lt;br /&gt;
// или не изменяться права доступа даже из под root.&lt;br /&gt;
&lt;br /&gt;
// это значит что на файл установлены дополнительные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
// увидеть это можно через &amp;quot;ls -lao&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// &amp;quot;+&amp;quot; означает что на файле имеются расширенные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lao /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
-rwxrw-rw-+  1 root  wheel  uarch 17301 Jul  9 08:26 ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
// смотрим атрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxpD-aARWcCo-:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
// сбрасываем атрибуты&lt;br /&gt;
&lt;br /&gt;
// Параметр -k удалит все установленные на данный момент ACL из файла или файловой системы.&lt;br /&gt;
&lt;br /&gt;
// Более предпочтительный метод это использование параметра -b, который оставит необходимые для работы ACL поля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setfacl -b /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxp--aARWcCos:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;--------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1892</id>
		<title>Linux. Files. Permissions</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1892"/>
		<updated>2024-11-26T19:06:25Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= File types =&lt;br /&gt;
The file type is one of the following characters:&lt;br /&gt;
&lt;br /&gt;
    -  regular file&lt;br /&gt;
&lt;br /&gt;
    b  block special file&lt;br /&gt;
&lt;br /&gt;
    c  character special file (disk)&lt;br /&gt;
&lt;br /&gt;
    C  high performance (&amp;quot;contiguous data&amp;quot;) file&lt;br /&gt;
&lt;br /&gt;
    d  directory&lt;br /&gt;
&lt;br /&gt;
    D  door (Solaris 2.5 and up)&lt;br /&gt;
&lt;br /&gt;
    l  symbolic link&lt;br /&gt;
&lt;br /&gt;
    M  off-line (&amp;quot;migrated&amp;quot;) file (Cray DMF)&lt;br /&gt;
&lt;br /&gt;
    n  network special file (HP-UX)&lt;br /&gt;
&lt;br /&gt;
    p  FIFO (named pipe)&lt;br /&gt;
&lt;br /&gt;
    P  port (Solaris 10 and up)&lt;br /&gt;
&lt;br /&gt;
    s  socket&lt;br /&gt;
&lt;br /&gt;
    ?  some other file type&lt;br /&gt;
&lt;br /&gt;
= Посмотреть все аттрибуты файла =&lt;br /&gt;
&amp;lt;code&amp;gt;stat ./Тест.part03.rar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  File: «./Тест.part03.rar»&lt;br /&gt;
&lt;br /&gt;
  Size: 5146762   	Blocks: 10056      IO Block: 4096   обычный файл&lt;br /&gt;
&lt;br /&gt;
Device: 871h/2161d	Inode: 8650784     Links: 1&lt;br /&gt;
&lt;br /&gt;
Access: (0760/-rwxrw----)  Uid: ( 3131/tmb_chishko)   Gid: (  513/Domain Users)&lt;br /&gt;
&lt;br /&gt;
Access: 2019-11-08 13:14:28.768582082 +0400&lt;br /&gt;
&lt;br /&gt;
Modify: 2019-11-06 17:03:47.109375000 +0400&lt;br /&gt;
&lt;br /&gt;
Change: 2019-11-08 13:14:29.065585726 +0400&lt;br /&gt;
&lt;br /&gt;
= Timestamps =&lt;br /&gt;
    There are 3 kind of &amp;quot;timestamps&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
        Access - the last time the file was read&lt;br /&gt;
&lt;br /&gt;
        Modify - the last time the file was modified (content has been modified)&lt;br /&gt;
&lt;br /&gt;
        Change - the last time meta data of the file was changed (e.g. permissions)&lt;br /&gt;
&lt;br /&gt;
= Аттрибуты дополнительные =&lt;br /&gt;
Просмотреть аттрибуты&lt;br /&gt;
&lt;br /&gt;
// создадим файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим аттрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// создадим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr +i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// теперь даже root не сможет удалить этот файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;----&amp;lt;/nowiki&amp;gt;i--------e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// удалим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr -i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
= '''SUID, GUID''' =&lt;br /&gt;
&lt;br /&gt;
== Настройка Setuid ==&lt;br /&gt;
Setuid – это бит разрешения, который позволяет пользователю запускать исполняемый файл с правами владельца этого файла. Другими словами, использование этого бита позволяет нам поднять привилегии пользователя в случае, если это необходимо. Классический пример использования этого бита в операционной системе это команда sudo.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# which sudo /usr/bin/sudo&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l /usr/bin/sudo&lt;br /&gt;
 -rwsr-xr-x 1 root root 125308 Feb 20 14:15 /usr/bin/sudo&amp;lt;/code&amp;gt;&lt;br /&gt;
Как мы видим на месте, где обычно установлен классический бит x (на исполнение), у нас выставлен специальный бит s. Это позволяет обычному пользователю системы выполнять команды с повышенными привилегиями без необходимости входа в систему как root.&lt;br /&gt;
&lt;br /&gt;
Установка бита setuid не представляет сложности. Для этого используется команда:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s &amp;lt;filename&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Рассмотрим на примере. Создадим файл с именем ''myfile'', а затем проверим его разрешения с помощью команды ''ls -l''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# touch myfile&lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 17:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Как видим, файл не имеет разрешений на выполнение для пользователя, группы и остальных. Добавим бит setuid:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]# chmod u+s myfile &lt;br /&gt;
 root@ruvds-hrc [~]# ls -l myfile&lt;br /&gt;
 -rwSrw-r-- 1 test test 0 Mar 25 12:00 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
Обратим внимание, что вместо ожидаемой буквы «s», видим заглавную «S». Почему? Это случается, если setuid установлен, но сам владелец файла не имеет прав на его выполнение. Добавим это разрешение с помощью команды ''chmod u + x''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod u+x myfile &lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l &lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 12:59 myfile&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Настройка Setgid ==&lt;br /&gt;
Принцип работы Setgid очень похож на setuid с отличием, что файл будет запускаться пользователем от имени группы, которая владеет файлом. Иллюстрирует работу этого бита команда ''crontab'': .&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  which crontab&lt;br /&gt;
 /usr/bin/crontab&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l /usr/bin/crontab&lt;br /&gt;
 -rwxr-sr-x 1 root crontab 34021 Feb 12 2017 /usr/bin/crontab&amp;lt;/code&amp;gt;&lt;br /&gt;
Теперь перейдем к настройке этого бита. Аналогично setuid, бит setgid выставляется с помощью команды chmod g + s .&lt;br /&gt;
&lt;br /&gt;
Рассмотрим на примере создания нового файл с именем ''myfile2''.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  touch myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rw-r-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Выполним команду ''chmod g + s'' и посмотрим результаты.&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+s myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l myfile2&lt;br /&gt;
 -rw-rwSr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
Как разобрались выше, меняем заглавную « S » путем выдачи прав на исполнение группе-владельцу:&lt;br /&gt;
 &amp;lt;code&amp;gt;root@ruvds-hrc [~]#  chmod g+x myfile2&lt;br /&gt;
 root@ruvds-hrc [~]#  ls -l&lt;br /&gt;
 total 0&lt;br /&gt;
 -rwsrw-r-- 1 test test 0 Mar 25 19:25 myfile&lt;br /&gt;
 -rw-rwsr-- 1 test test 0 Mar 25 19:25 myfile2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= '''Sticky bit''' =&lt;br /&gt;
// благодаря таким правам удалить файл из TMP может только пользователь, который этот файл создал&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 1777 /tmp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Freebsd расширенные атрибуты =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/fs-acl.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// несмотря на полный доступ к файлам, они могут ни удаляться, ни переименовываться&lt;br /&gt;
&lt;br /&gt;
// или не изменяться права доступа даже из под root.&lt;br /&gt;
&lt;br /&gt;
// это значит что на файл установлены дополнительные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
// увидеть это можно через &amp;quot;ls -lao&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// &amp;quot;+&amp;quot; означает что на файле имеются расширенные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lao /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
-rwxrw-rw-+  1 root  wheel  uarch 17301 Jul  9 08:26 ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
// смотрим атрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxpD-aARWcCo-:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
// сбрасываем атрибуты&lt;br /&gt;
&lt;br /&gt;
// Параметр -k удалит все установленные на данный момент ACL из файла или файловой системы.&lt;br /&gt;
&lt;br /&gt;
// Более предпочтительный метод это использование параметра -b, который оставит необходимые для работы ACL поля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setfacl -b /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxp--aARWcCos:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;--------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
	<entry>
		<id>https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1891</id>
		<title>Linux. Files. Permissions</title>
		<link rel="alternate" type="text/html" href="https://wiki.cless.pro/index.php?title=Linux._Files._Permissions&amp;diff=1891"/>
		<updated>2024-11-26T19:01:55Z</updated>

		<summary type="html">&lt;p&gt;Cless: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Self-education]]&lt;br /&gt;
__ОБЯЗАТЕЛЬНОЕ_ОГЛАВЛЕНИЕ__&lt;br /&gt;
&lt;br /&gt;
= ls =&lt;br /&gt;
The file type is one of the following characters:&lt;br /&gt;
&lt;br /&gt;
    -  regular file&lt;br /&gt;
&lt;br /&gt;
    b  block special file&lt;br /&gt;
&lt;br /&gt;
    c  character special file (disk)&lt;br /&gt;
&lt;br /&gt;
    C  high performance (&amp;quot;contiguous data&amp;quot;) file&lt;br /&gt;
&lt;br /&gt;
    d  directory&lt;br /&gt;
&lt;br /&gt;
    D  door (Solaris 2.5 and up)&lt;br /&gt;
&lt;br /&gt;
    l  symbolic link&lt;br /&gt;
&lt;br /&gt;
    M  off-line (&amp;quot;migrated&amp;quot;) file (Cray DMF)&lt;br /&gt;
&lt;br /&gt;
    n  network special file (HP-UX)&lt;br /&gt;
&lt;br /&gt;
    p  FIFO (named pipe)&lt;br /&gt;
&lt;br /&gt;
    P  port (Solaris 10 and up)&lt;br /&gt;
&lt;br /&gt;
    s  socket&lt;br /&gt;
&lt;br /&gt;
    ?  some other file type&lt;br /&gt;
&lt;br /&gt;
= Посмотреть все аттрибуты файла =&lt;br /&gt;
&amp;lt;code&amp;gt;stat ./Тест.part03.rar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  File: «./Тест.part03.rar»&lt;br /&gt;
&lt;br /&gt;
  Size: 5146762   	Blocks: 10056      IO Block: 4096   обычный файл&lt;br /&gt;
&lt;br /&gt;
Device: 871h/2161d	Inode: 8650784     Links: 1&lt;br /&gt;
&lt;br /&gt;
Access: (0760/-rwxrw----)  Uid: ( 3131/tmb_chishko)   Gid: (  513/Domain Users)&lt;br /&gt;
&lt;br /&gt;
Access: 2019-11-08 13:14:28.768582082 +0400&lt;br /&gt;
&lt;br /&gt;
Modify: 2019-11-06 17:03:47.109375000 +0400&lt;br /&gt;
&lt;br /&gt;
Change: 2019-11-08 13:14:29.065585726 +0400&lt;br /&gt;
&lt;br /&gt;
= Timestamps =&lt;br /&gt;
    There are 3 kind of &amp;quot;timestamps&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
        Access - the last time the file was read&lt;br /&gt;
&lt;br /&gt;
        Modify - the last time the file was modified (content has been modified)&lt;br /&gt;
&lt;br /&gt;
        Change - the last time meta data of the file was changed (e.g. permissions)&lt;br /&gt;
&lt;br /&gt;
= Аттрибуты дополнительные =&lt;br /&gt;
Просмотреть аттрибуты&lt;br /&gt;
&lt;br /&gt;
// создадим файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;touch keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим аттрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// создадим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr +i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// теперь даже root не сможет удалить этот файл&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;----&amp;lt;/nowiki&amp;gt;i--------e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
// удалим аттрибут &amp;quot;только для чтения&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;sudo chattr -i keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// просмотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;lsattr keep.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;-------------&amp;lt;/nowiki&amp;gt;e-- keep.txt&lt;br /&gt;
&lt;br /&gt;
= '''Sticky bit''' =&lt;br /&gt;
// благодаря таким правам удалить файл из TMP может только пользователь, который этот файл создал&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;chmod 1777 /tmp&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Freebsd расширенные атрибуты =&lt;br /&gt;
&amp;lt;nowiki&amp;gt;https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/fs-acl.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// несмотря на полный доступ к файлам, они могут ни удаляться, ни переименовываться&lt;br /&gt;
&lt;br /&gt;
// или не изменяться права доступа даже из под root.&lt;br /&gt;
&lt;br /&gt;
// это значит что на файл установлены дополнительные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
// увидеть это можно через &amp;quot;ls -lao&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// &amp;quot;+&amp;quot; означает что на файле имеются расширенные атрибуты ACL&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ls -lao /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
-rwxrw-rw-+  1 root  wheel  uarch 17301 Jul  9 08:26 ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
// смотрим атрибуты&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxpD-aARWcCo-:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rw-p--a-R-c---:-------:allow&lt;br /&gt;
&lt;br /&gt;
// сбрасываем атрибуты&lt;br /&gt;
&lt;br /&gt;
// Параметр -k удалит все установленные на данный момент ACL из файла или файловой системы.&lt;br /&gt;
&lt;br /&gt;
// Более предпочтительный метод это использование параметра -b, который оставит необходимые для работы ACL поля.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;setfacl -b /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// смотрим&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;getfacl /mnt/raid1/share/ПТК.xlsx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; file: /mnt/raid1/share/ПТК.xlsx&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; owner: root&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#&amp;lt;/nowiki&amp;gt; group: wheel&lt;br /&gt;
&lt;br /&gt;
            owner@:rwxp--aARWcCos:-------:allow&lt;br /&gt;
&lt;br /&gt;
            group@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
         everyone@:rwxp--a-R-c--s:-------:allow&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;--------------------------------------------------------------------------------&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cless</name></author>
	</entry>
</feed>