# Шпора

# Mount

Настраивал на днях арендованный сервер без прямого доступа к консоли. Ещё и конфигурация была нестандартная, так что техподдержка вручную установила туда ОС и отдала мне с доступом по SSH. Нужно было настроить дополнительные диски и добавить их в fstab. Несмотря на то, что в современных ОС реально монтирует диски systemd, я по старинке предпочитаю добавлять новые точки монтирования в fstab.   
  
В этом деле самое главное – не ошибиться и сразу после изменения файла проверить, что там всё в порядке. Иначе после перезагрузки можно получить проблемы. Без прямого доступа к консоли это может быть фатально.  
  
Я обычно добавляю новые диски в систему следующим образом. Смотрю список дисков через fstab:

```
# fdisk -l | grep /dev/
```

  
  
Сразу видно диски без разметки. Добавлять разделы предпочитаю в cfdisk, а не напрямую в консоли через fstab. В TUI как-то нагляднее, меньше шансов ошибиться.

```
# cfdisk /dev/sdb
```

  
  
Создаю раздел, выбираю тип раздела, сохраняю. После этого можно создавать файловую систему.

```
# mkfs -t ext4 /dev/sdb1
```

  
  
Монтирую в систему:

```
# mkdir /mnt/disk1
```

```
# mount /dev/sdb1 /mnt/disk1
```

  
  
Теперь нам надо добавить эту точку монтирования в fstab. По имени диска категорически нельзя добавлять. Диски могут менять свои имена. Причём это стало актуально в какой-то момент с очередным обновлением железа. Когда я только начинал изучать Linux, спокойно монтировал по именам дисков и проблем не было. В какой-то момент они начались. И сейчас я сам часто наблюдаю, что диски, как и сетевые интерфейсы, могут изменить свои имена после перезагрузки. Если используете LVM, то можно добавлять точки монтирования по имени LV.  
  
Смотрим UUID раздела:

```
# blkid | grep /dev/sdb1
```

  
  
Добавляем его в fstab отдельной строкой:

```
UUID=eaf5c153-08b7-4ea8-8037-e6baad4cac0d /mnt/disk1 ext4 errors=remount-ro 1 0
```

  
  
А теперь проверяем, всё ли мы правильно добавили.

```
# findmnt --verify --verbose
```

  
  
Findmnt проверил все монтирования. В моём случае я получил предупреждение на /media/cdrom0.

```
[W] unreachable source: /dev/sr0: No such file or directory
```

  
  
Судя по всему систему ставили с какого-то диска, локального или сетевого, не знаю, но он остался в fstab. Делать ему там больше нечего, можно закомментировать строку с ним.  
  
Более кратко можно получить информацию только об ошибках:

```
# findmnt -x
```

  
  
☝️Отдельно обращаю внимание на такой момент. До перехода управления к systemd было критически важно оставлять в fstab в конце файла переход на новую строку. Сейчас даже если этого не сделать, то проблем не будет. Всё нормально загрузится. Насколько я понимаю, это тянется из далёкого прошлого и POSIX-совместимой практики, когда файлы конфигурации заканчивались переходом на новую строку. Я лично до сих пор на всякий случай везде этой практики придерживаюсь.  
  
Ещё один способ проверить корректность записей в fstab – использовать **mount**. Можно не монтировать вручную новый диск, а сразу добавить его в fstab. Потом запустить:

```
# mount -a -v
```

  
  
Утилита смонтирует все записи из файла, где не указан параметр noauto. Если вы всё верно добавили, то ошибок не увидите и получите смонтированным новый диск.  
  
Расскажу, что будет, если, к примеру, ошибётесь с диском в fstab или он просто перестанет быть видим в системе. Я лично с этим не раз сталкивался. А однажды это привело к дальней дороге. Добавили наживую новый диск в сервер, я его добавил с ошибкой в fstab и не проверил. Сервер аварийно перезагрузился через полгода из-за обесточивания серверной. Возникли какие-то проблемы с доступом туда, ещё и сервер по неизвестной на тот момент мне причине не стартанул. Приехал туда ножками и увидел примерно то же самое, что вы видите на втором скрине.  
  
Сразу понял, в чём дело, зашёл в режим обслуживания и поправил fstab. Так что внимательно относитесь к его настройке. Этой проблемы можно избежать, если использовать **nofail** в параметрах монтирования. Но с ним могут быть нюансы. Иногда лучше не загрузиться, если с разделом проблемы.  
  
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.  
  
\#linux

# WebRadio

<table border="1" cellpadding="0" cellspacing="0" id="bkmrk-%E3%80%80esp32-3248s035c-%2C-e"><tbody><tr><td colspan="2"> ESP32-3248S035C , ESP32-3248S035R  
 Down LOAD：[WebRadio\_3248S035C\_OpenTape.zip](https://macsbug.wordpress.com/wp-content/uploads/2023/09/webradio_3248s035c_opentape.zip_.pdf)  
 [3.5″ 480×320 ESP32-248S035C](https://macsbug.wordpress.com/2022/10/02/esp32-3248s035/)：Sketch uses 84%  
   
 Down LOAD：2024.09.22 ( Sep 22.2024 )  
 [WebRadio\_S3\_3248S035R.zip](https://macsbug.wordpress.com/wp-content/uploads/2023/09/webradio_s3_3248s035r.zip_.pdf)  
 ESP32-3248S035R を改造。  
 ESP32-WROOM-32 を ESP32-S3-WROOM-1-N16R8 に交換。  
 CH340C UARTは 削除。  
 MAX98357A と iPad 6 Speaker 2pcsを装備し Stereo機能装備。  
 Library： with [ESP32-audioI2S-maste\_3.0.12](https://github.com/schreibfaul1/ESP32-audioI2S/)p\_Sep.16.2024</td></tr><tr><td>![](https://macsbug.wordpress.com/wp-content/uploads/2023/08/3248s035_ot1_280s.jpg?w=240)</td><td>![](https://macsbug.wordpress.com/wp-content/uploads/2023/08/3248s035_ot2_280s.jpg?w=240)</td></tr><tr><td colspan="2"> ESP32-3248S035R 改造： ESP32 S3 + MAX98357A 2pcs + iPad 6 Speaker 2pcs  
 ![](https://macsbug.wordpress.com/wp-content/uploads/2023/09/s035rev_380s.png)</td></tr></tbody></table>

# OpenHASP

[https://nightly.openhasp.com/](https://nightly.openhasp.com/)

# Могу ли я использовать образы дисков из QEMU, VMware или других платформ виртуализации в bhyve?

bhyve does not currently support reading foreign disk image formats directly, so one will have to convert existing VMDK, QCOW, QCOW2, and VDI disk images to a raw image using qemu-img. This can be accomplished by doing the following on a FreeBSD system:<span class="anchor" id="bkmrk-"></span><span class="anchor" id="bkmrk--1"></span>

в настоящее время bhyve не поддерживает прямое чтение внешних форматов образов дисков, поэтому вам придется преобразовать существующие образы дисков VMDK, QCOW, QCOW2 и VDI в необработанный образ с помощью qemu-img. Этого можно добиться, выполнив следующие действия в системе FreeBSD:

<span class="anchor" id="bkmrk--3"></span><span class="anchor" id="bkmrk--4"></span><span class="anchor" id="bkmrk--5"></span>

```
$ pkg install qemu-tools
$ qemu-img convert -f vmdk -O raw vmware_image.vmdk bhyve_raw_image.raw
```

# freebsd мониторинг

Инструкция, freebsd мониторинг.  
Внесу свои пять копеек в инструкцию по мониторингу.  
Моя работа в основном заключается в удаленном администрировании серверов под управлением системы freebsd.  
Иногда полезно держать под рукой уже заготовленный шаблон команд по снятию данных от процессов.

Работа с дисковыми подсистемами.  
На мой взгляд есть еще одна утилита gstat.

```
# gstat
```

Если мы хотим выводить информацию только по активным дискам, то нужно запустить gstat с ключом а:

```
# gstat -a

dT: 1.006s  w: 1.000s
 L(q)  ops/s    r/s   kBps   ms/r    w/s   kBps   ms/w   %busy Name
    0    189     29    923    2.1    160   7285    3.1   14.6| ada0
    0     12     10    445   10.9      2     64    0.2    9.7| ada2
    0    189     29    923    2.1    160   7285    3.1   14.6| ada0s1
    0    189     29    923    2.1    160   7285    3.1   14.6| ada0s1a
    0     12     10    445   10.9      2     64    0.2    9.7| ada2p1
```

Этот вариант более подробный, выведит больше информации по нагрузки дисков.

```
# iostat -w1 -dx
```

Выставим период снятия информации 1 секунду, этим мы выведем информацию по дискам.

```
# iostat -w1 -d
```

Должно получится что то вроде этого.

```
# iostat -w3 -d
            ada0             ada1             ada2             ada3 
  KB/t tps  MB/s   KB/t tps  MB/s   KB/t tps  MB/s   KB/t tps  MB/s 
 44.09  26  1.12  33.38   4  0.12  31.75  31  0.96  113.76   5  0.53 
 32.96  26  0.82   0.00   0  0.00  31.10  21  0.63  128.00   0  0.04 
 37.31 105  3.81   0.00   0  0.00  26.00   7  0.19  128.00   0  0.04 
 45.71   2  0.10   0.00   0  0.00  31.88 110  3.41  40.67   2  0.08
```

Протестируем диск.

```
# diskinfo -t ada0
```

Список открытых файлов в системе.

```
# pstat -f 
```

Так с дисками закончили, теперь перейдем к сетевой подсистеме.

```
# systat -ifstat 1

                    /0   /1   /2   /3   /4   /5   /6   /7   /8   /9   /10
     Load Average   ||||| 

      Interface           Traffic               Peak                Total
            lo0  in      0.000 KB/s          0.050 KB/s          117.844 MB
                 out     0.000 KB/s          0.050 KB/s          117.844 MB

           igb0  in    190.516 KB/s        311.421 KB/s           51.684 GB
                 out     1.897 MB/s          4.343 MB/s          485.240 GB
```

Сетевые активные соединения. Снимаем информацию каждые две секунды.

```
# systat -netstat 2
```

Соединения tcp. Снимаем информацию каждые 2 секунды.

```
# systat -tcp 2
```

В настоящее время сколько пришло пакетов.

```
# netstat -w 1 -h
            input        (Total)           output
   packets  errs idrops      bytes    packets  errs      bytes colls
      1.2K     0     0       232K        542     0       2.0M     0
      1.3K     0     0       218K        565     0       1.8M     0
      1.5K     0     0       323K        797     0       3.0M     0
      2.0K     0     0       340K        961     0       3.5M     0
```

Выводим ошибки.

```
# netstat -i
```

Таблицу маршрутизации.

```
# netstat -nr
```

Хватает ли системе mbuf.

```
# netstat -m
```

Но больше всего я предпочитаю снимать сетевую активность этой утилитой [мониторинг сети с помощью nload](https://www.fryaha.ru/nload/).  
О ней я позже напишу.  
осталось процессор и оперативная память.  
Общая системная статистика.

```
# systat -vmstat 2
```

Прерывание на процессоре.

```
# vmstat -i
```

Сколкьо используется свопа.

```
# systat -swap 1
```

Этим можно увидеть нагрузку на процессор и диски.

```
# systat -iostat 1
```

Просмотр буферов системы.

```
# vmstat -z
```

Смотрим кто перезагружал сервер.

```
# last
```

Выявляем траглодитного процесса.

```
# top -m io -o total
```

Скажу еще пару слов о хорошей утилите top.

```
a - Подробный паказ процессов.
n 10 - Смотрим 10-ть самых больших процессов в системе.
P - Выводим просмотр по ядерно, будит показана нагрузка в процентах на каждое ядро. 
S - Выводим на показ системные процессы.
Утилита top очень обширна в ключах для вытягивания статистики системы. О top я расскажу чуть позже.
```

Дополнительный материал по статьи [Средство проверки сети](https://www.fryaha.ru/freebsd-tools-check-network/).  
Вот такая маленький черновик freebsd мониторинг системы.

https://www.fryaha.ru/freebsd-monitoring-system/

# Настройка IPFW + NAT в FreeBSD 14

Сервер FreeBSD будет выступать в качестве маршрутизатор (роутера) локальной сети, для этого будет использоватся Firewall IPFW и модуль маршрутизации NAT. Необходимо настроить раздачу интернета во внутреннею сеть и открыть порты сервисов которые работают на сервере. Одна сетевая карта сервера смотрит в интернет, вторая в локальную сеть. На сервера FreeBSD работает веб-сервер.

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Архитектура маршрутизатора сети](https://notby.net/nastroyka-ipfw-nat-v-freebsd#1)
2. [2. Включение IPFW + NAT](https://notby.net/nastroyka-ipfw-nat-v-freebsd#2)
3. [3. Синтаксис правил IPFW + NAT](https://notby.net/nastroyka-ipfw-nat-v-freebsd#3)
4. [4. Конфигурация IPFW + NAT](https://notby.net/nastroyka-ipfw-nat-v-freebsd#4)
5. [5. Запуск и перезапуск IPFW + NAT](https://notby.net/nastroyka-ipfw-nat-v-freebsd#5)
6. [6. Команды IPFW + NAT](https://notby.net/nastroyka-ipfw-nat-v-freebsd#6)

</nav>## 1. Архитектура маршрутизатора сети

Настроить можно как угодно и что угодно. Архитектура, которая используется в примере идентична по возможностям для большинства домашних роутеров.

Сервер FreeBSD имеет два сетевых интерфейса. К одной сетевой карте подключен кабель интернет провайдера с внешним IP адресом, к другой подключен кабель до коммутатора внутренний сети. Компьютеры внутренней сеть должно иметь доступ в интернет.

<figure class="image" id="bkmrk-">![Архитектура сети: Интернет — Маршрутизатор FreeBSD (IPFW + NAT) — Коммутатор — Компьютеры локальной сеть](https://notby.net/images/03/arkhitektura-seti-internet-marshrutizator-freebsd-ipfw-nat-kommutator-lokalnaya-set.webp)</figure>На сервере работает веб-сервер и другие сервисы, для это необходимо открыть порты доступа. Также надо настроить возможность проброса портов с внешнего IP адреса на компьютеры локальной сети, для торрент-клиентов, сетевых игр и так далее…

## 2. Включение IPFW + NAT

Открываем файл **/etc/rc.conf**

```
```
nano /etc/rc.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строки

```
```ini
gateway_enable="YES" # Использовать сервер FreeBSD в качестве шлюза
firewall_enable="YES" # Включить IPFW
firewall_nat_enable="YES" # Включить NAT
firewall_script="/etc/ipfw.rules" # Файл с правилами IPFW + NAT
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строку если необходимо логировать какие-то правила. Запись событий будет происходить в файл **/var/log/security** журнала безопасности.

```
```plaintext
firewall_logging="YES"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

В результате фрагмент файла **rc.conf** с параметрами сетевых карт и включённым маршрутизатором должен выглядеть следующим образом

<figure class="image" id="bkmrk--1">![Открыт файл /etc/rc.conf редактором nano в FreeBSD. Настроены параметры сетевых карт, указан параметр для использования FreeBSD в качестве шлюза, включен IPFW + NAT, указан путь до скрипта настройки IPFW.](https://notby.net/images/03/freebsd-nano-etc-rc-conf-vklyuchen-gateway-ipfw-nat.webp)</figure>Дополнительно можно добавить загрузку модулей ядра IPFW + NAT непосредственно в момент загрузки системы.

Открываем файл **/boot/loader.conf**

```
```
nano /boot/loader.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строки

```
```ini
ipfw_load="YES"
ipfw_nat_load="YES"
libalias_load="YES"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

При загрузке FreeBSD сразу будут загружатся: **ipfw** – модуля ядра IPFW, **ipfw\_nat** – модуль базовых функций NAT, **libalias** – модуль полных функций NAT.

По умолчанию в IPFW весь трафик запрещен, поэтому при его запуске или после перезагрузки, без настройки файла правил, будет невозможно подключится через SSH.

Настраиваем файл правил IPFW до его запуска или временно изменяем поведение IPFW на “разрешить все по умолчанию”.

Для этого в файл **/boot/loader.conf** добавляем строку

```
```plaintext
net.inet.ip.fw.default_to_accept="1"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Теперь по умолчанию последнее правило IPFW будет разрешать любой трафик на всех сетевых картах. После завершения настройки рекомендую убрать добавленную строку.

---

IPFW + NAT может быть включен непосредственно в ядре FreeBSD. Для этого включаем в ядро необходимые модули

```
```ini
options		IPFIREWALL # Включить IPFW
options		IPFIREWALL_VERBOSE # Включить возможность логирования трафика
options		IPFIREWALL_VERBOSE_LIMIT=5 # Количество одинаковых пакетов в одну запись лога
#options	IPFIREWALL_DEFAULT_TO_ACCEPT # По умолчанию пропускать все, за исключением запрещенного правилами
options		IPFIREWALL_NAT # Включить базовые возможности NAT
options		LIBALIAS # Включить полные возможности NAT
#options	IPFIREWALL_NAT64 # Включить поддержку NAT64
#options	IPFIREWALL_NPTV6 # Включить поддержку IPv6 NPT
#options	IPFIREWALL_PMOD # Поддержку модулей модификации протоколов
#options	IPDIVERT # Включить NAT через natd(8)
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Читать как собрать ядро FreeBSD: [Конфигурация и сборка ядра FreeBSD 14](https://notby.net/konfiguratsiya-i-sborka-yadra-freebsd)

## 3. Синтаксис правил IPFW + NAT

Правила IPFW имеют примерно следующий синтаксис:

```
```ini
add <номер правила> [allow/deny] [ip/tcp/udp/…] from [any/me/<IP-адрес>] <порт> to [any/me/<IP-адрес>] <порт> {Опции}
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Работу правила лучше объяснить на примере, например открываем 80 порт для веб-сервера

```
```plaintext
add 00400 allow tcp from any to me 80 in via em0 setup keep-state
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляется правило с номером 00400 (необязательный параметр) которое разрешает TCP пакеты с любого IP адреса до IP адреса сервера с **80** портом входящие через сетевую карту **em0** и устанавливаются опции **setup** и **keep-state**. Опция **setup** сопоставляет TCP-пакеты, у которых установлен бит SYN, но отсутствует бит ACK, **keep-state** создает динамическое правило двунаправленного трафика.

Для работы маршрутизации и проброса портов, необходимо создавать экземпляр NAT, он имеет следующий синтаксис:

```
```ini
nat <номер> config [ip <IP-адрес> / if <сетевая карта>] {Опции}
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Например, создаем экземпляр NAT с номером 1, через сетевой интерфейс em0 осуществляется выход в интернет, пробрасываем TCP порт 5530 с внешнего IP на компьютер внутренний сети с адресом 192.168.0.5 на том же порту

```
```plaintext
nat 1 config if em0 same_ports unreg_only deny_in reset redirect_port tcp 192.168.0.5:5530 5530
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Доступные опции для **nat**:

- **same\_ports** – следит за тем, чтобы псевдонимы портов и локальные номера портов были сопоставлены одинаково;
- **unreg\_only** – обрабатывать только частный адресные пространства (192.168.0.0, 10.0.0.0, …);
- **deny\_in** – запретить любое входящие соединение из внешнего мира;
- **reset** – сбрасывать и обновлять таблицу маршрутизации, если изменится внешний IP;
- **redirect\_port** – перенаправление порта;
- **redirect\_addr** – перенаправление IP-адреса.

## 4. Конфигурация IPFW + NAT

Создаем файл конфигурации **/etc/ipfw.rules**

```
```
nano /etc/ipfw.rules
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Чем меньше правил, тем выше производительность IPFW. Объединяй по возможности несколько правил в одно.

Файл конфигурации IPFW + NAT будет выглядеть примерно так:

```
```bash
#!/bin/sh
# Очищаем список правил IPFW
ipfw -q -f flush
# Команда добавления правила, -q — режим без вывода сообщений
cmd="ipfw -q add"
# Сетевые карты заносим в переменные
net="em0" # сетевая карта интернета
lan="em1" # сетевая карта локальной сети

# Разрешить любой трафик внутри loopback интерфейса
$cmd 00010 allow all from any to any via lo0
# Запретить любой трафик извне до локальных адресов
$cmd 00011 deny ip from any to 127.0.0.0/8
$cmd 00012 deny ip from 127.0.0.0/8 to any

# Разрешить любые пакеты внутри локальной сети
$cmd 00050 allow ip from any to any via $lan

# Разрешить доступ к SSH серверу по 22 порту
$cmd 00510 allow tcp from any to me 22 in via $net
# Разрешить доступ к веб-серверу по 80 и 443 портам (HTTP/HTTPS)
$cmd 00520 allow tcp from any to me 80,443 in via $net

# Настройка маршрутизации IPFW + NAT
# Создаем экземпляр NAT с номером 1 и перенаправляем TCP 5530 порт на компьютер локальной сети с адресом 192.168.0.5
ipfw -q nat 1 config if $net same_ports unreg_only deny_in reset redirect_port tcp 192.168.0.5:5530 5530
# Разрешить проходить TCP и UDP пакетам, ping через NAT на сетевую карту интернета
$cmd nat 1 tcp from any to any via ${net}
$cmd nat 1 udp from any to any via ${net}
$cmd nat 1 icmp from any to any via ${net}
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

В таком варианте все исходящие пакеты с сервера и локальный сети проходят через NAT и создается двунаправленное правило для входящих пакетов. Входящие пакеты из интернета запрещены параметром **deny\_in** в экземпляре NAT. Для открытия порта веб-серверу и SSH созданы правила, которые разрешают только входящие пакеты, а для исходящих пакетов будет использоватся правило NAT. В такой конфигурации firewall работает без динамических правил создаваемых опцией keep-state.

Вносим изменения и сохраняем файл с правила IPFW + NAT и можно приступать к запуску IPFW.

## 5. Запуск и перезапуск IPFW + NAT

Будь внимателен. Если есть ошибка или неточность в правилах, можно потерять доступ по SSH.

Запускаем службу IPFW

```
```
service ipfw start
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Когда будут внесены какие-то изменения в файл с правилами межсетевого экрана и маршрутизации, необходимо перезапустить IPFW.

Перезапускаем службу IPFW

```
```
service ipfw restart
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 6. Команды IPFW + NAT

Вывести статистику по работе правил IPFW

```
```
ipfw -a -d -t list
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

- **-a** — количество совпавших пакетов и переданных байт;
- **-d** — вывести динамические правила;
- **-t** — время когда сработало правило последний раз;
- **-e** — динамические правила с истекшим сроком действия.

Удалить правило с указанным номером, например 00500

```
```
ipfw delete 00500
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Вывести список экземпляром NAT и их параметры

```
ipfw nat show config
```

# MPD 5.7 настройка VPN-сервера в FreeBSD

Настраиваем MPD5 в качестве VPN-сервера для подключений Windows-клиентов к офисной сети по протоколу PPTP.

MPD5 также может использоваться в качестве VPN-клиента для доступа к удаленной сети, или подключения к интернет провайдеру.

Для объединения нескольких сетей через интернет обратите внимание на [OpenVPN](https://itadept.ru/freebsd-openvpn/). Ключевые отличия OpenVPN: туннель по UDP или TCP протоколу, TLS-шифрование, возможность задать клиенту маршруты к обслуживаемым сетям.

### Содержание

- [Установка MPD5](https://itadept.ru/freebsd-mpd5-server/#install)
- [Настройка MPD5](https://itadept.ru/freebsd-mpd5-server/#config)
- [Включение маршрутизации](https://itadept.ru/freebsd-mpd5-server/#routing)
- [Настройка брандмауэра](https://itadept.ru/freebsd-mpd5-server/#firewall)
- [Настройка логов MPD5](https://itadept.ru/freebsd-mpd5-server/#logs)
- [Запуск MPD5](https://itadept.ru/freebsd-mpd5-server/#start)
- [Возможные проблемы](https://itadept.ru/freebsd-mpd5-server/#troubleshoot)
- [Анализ логов MPD5](https://itadept.ru/freebsd-mpd5-server/#log-parsers)
- [Ссылки](https://itadept.ru/freebsd-mpd5-server/#links)

<span id="bkmrk--1"></span>

## <a id="bkmrk--2" name="install"></a>Установка MPD5

Устанавливаем пакет:

```
pkg install mpd5
```

Для установки из коллекции портов, обновляем коллекцию:

```
portsnap fetch && portsnap update || portsnap extract
```

Затем, устанавливаем порт:

```
cd /usr/ports/net/mpd5
make install clean
```

## <a id="bkmrk--3" name="config"></a>Настройка MPD5

Переходим в папку с файлами конфигурации:

```
cd /usr/local/etc/mpd5
```

В папке имеются следующие файлы:

- mpd.conf.sample - шаблон файла конфигурации,
- mpd.script.sample - скрипты для модемов,
- mpd.secret.sample - пример списка пользователей и паролей.

Копируем файл конфигурации из шаблона:

```
cp mpd.conf.sample mpd.conf
```

Открываем в редакторе:

```
ee mpd.conf
```

Идентификаторы секций в файле конфигурации задаются с начала строки и заканчиваются двоеточием. Значения параметров в начале строки обязательно отделяются табуляцией, пробелы также допустимы.

Удаляем все секции кроме startup, default и pptp\_server. Для удаления строк в ee используем Ctrl+K. Также конфиг можно создать копипастом приведенного ниже листинга.

Задаем параметры. Строки, требующие корректировки, выделены жирным шрифтом:

```
#Секция startup загружается при запуске MPD5
startup:
   #Протоколировать IP-адреса, с которых выполняются подключения
   <strong>log +PHYS2</strong>
   #Параметры http и telnet доступа для мониторинга и оперативного управления.
   #Задать логин, пароль и роль администратора
   <strong>set user <em>пользователь пароль</em> admin</strong>
   #Задать пользователя, доступны роли operator и user, по умолчанию подразумевается user
   <strong>#set user foo1 bar1</strong>
   #Открыть локальный telnet доступ, порт 5005
   set console self 127.0.0.1 5005
   set console open
   #Открыть веб-админку на всех интерфейсах, порт 5006
   set web self 0.0.0.0 5006
   set web open

#Если в команде запуска MPD не задана конфигурация, обрабатывается секция default.
default:
    #Загрузить секцию pptp_server
    <strong>load pptp_server</strong>

pptp_server:
    #Пул динамических IP-адресов, начальный и конечный адрес
    <strong>set ippool add pool1 192.168.1.50 192.168.1.99</strong>

    #Создать динамический пучок (bundle) с именем B.
    #Сетевые интерфейсы будут создаваться динамически при подключении клиента
    create bundle template B

    #Если IP-адрес клиента принадлежит локальной подсети, присвоить ему MAC-адрес
    set iface enable proxy-arp

    #Отключать клиента при отсутствии трафика в течение заданного количества секунд
    <strong>#set iface idle 1800</strong>

    #Корректировать размер пакета TCP-соединений через туннель,
    #в случае если он превышает заданный MTU (TCP Maximum Segment Size Fix)
    set iface enable tcpmssfix

    #Разрешить сжатие заголовков TCP
    set ipcp yes vjcomp

    #IP-адрес для сервера и клиентов
    #Адрес сервера: 192.168.1.1
    #Для клиентов используем пул: "pool1", объявленный ранее
    <strong>set ipcp ranges 192.168.1.1/32 ippool pool1</strong>

    #Задать DNS-серверы для клиентов
    <strong>set ipcp dns 192.168.1.3 192.168.2.3</strong>
    #Задать WINS-серверы для клиентов
    <strong>#set ipcp nbns 192.168.1.4</strong>

    #Использовать шифрование Microsoft
    #Протокол сжатия Microsoft в базовой поставке не поддерживается, требуется пересборка ядра со сторонним модулем.
    set bundle enable compression
    set ccp yes mppc
    #Разрешить 40-битное и 128-битное шифрование Microsoft
    <strong>#set mppc yes e40</strong>
    set mppc yes e128
    #Разрешить безстатусный (stateless) режим шифрования.
    #Повышает устойчивость к потерям, ценой повышенной загрузки на процессор.
    set mppc yes stateless

    #Создать динамическую PPTP линию
    create link template L pptp

    #Связать с пучком B
    set link action bundle B

    #Использовать фрагментацию, если размер пакета превышает MTU
    set link enable multilink

    #Разрешить сжатие некоторых полей в заголовке, экономит от 1 до 3 байт на пакет
    set link yes acfcomp protocomp

    #Использовать CHAP авторизацию, протоколы: Microsoft CHAP v2, Microsoft CHAP, CHAP MD5.
    set link no pap chap eap
    set link enable chap

    #Отправлять LCP эхо запрос каждые 10 секунд, если ответа не последует в течение 60 секунд, считать соединение разорванным.
    #Не работает вплоть до версии 5.5, LCP-пинг отправляется раз в минуту
    #set link keep-alive 10 60

    #Максимальный размер пакета
    #Стандарт для VPN - 1400
    #Если VPN-соединение разрывается при передаче большого объема данных, следует уменьшить значение параметров, а также убедиться что работает Multilink
<strong>    set link mtu 1402
    set link mru 1400
</strong>
    #Принимать PPTP подключения на всех интерфейсах
    <strong>set pptp self 0.0.0.0</strong>
    set link enable incoming
```

Задаем список пользователей нашего VPN-сервера в файле mpd.secret:

```
ee mpd.secret
```

Задаем имена пользователей, пароли, при необходимости, присваиваем фиксированные IP-адреса. Имя пользователя и пароль чувствительны к регистру.

```
#login    password    ip
user1     pass1      192.168.0.193
user2     pass2  
```

Ограничиваем доступ к файлу:

```
chmod 600 mpd.secret
```

## <a id="bkmrk--4" name="routing"></a>Включение маршрутизации

Проверяем, включена ли маршрутизация, командой:

```
sysctl net.inet.ip.forwarding
```

Если в результате видим: "`net.inet.ip.forwarding: <strong>1</strong>`", значит маршрутизация включена, переходим к следующему разделу.

Если видим: "`net.inet.ip.forwarding: <strong>0</strong>`", значит в /etc/rc.conf необходимо добавить параметр: `gateway_enable="YES"`:

```
printf '\ngateway_enable=\"YES\"\n' >>/etc/rc.conf
```

Перезагружаем систему:

```
reboot
```

Проверяем, включена ли маршрутизация:

```
sysctl net.inet.ip.forwarding
```

В результате получаем:

```
net.inet.ip.forwarding: <strong>1</strong>
```

## <a id="bkmrk--5" name="firewall"></a>Настройка брандмауэра

Для приема PPTP-подключений необходимо открыть входящие TCP-соединения на порт 1723 и разрешить GRE-трафик.  
Для IPFW правила будут примерно следующие:

```
allow tcp from any to me dst-port 1723 setup keep-state
allow gre from any to me
allow gre from me to any
```

Подключенным клиентам также необходимо открыть доступ к локальной сети. В простейшем варианте, для пула 192.168.1.50 - 192.168.1.99, открываем полный доступ для всех локальных подключений, независимо от интерфейсов:

```
allow all from 192.168.1.0/24 to 192.168.1.0/24
```

## <a id="bkmrk--6" name="logs"></a>Настройка логов MPD5

Для записи логов MPD5 использует syslog. Идентификатор источника сообщений задается ключом командной строки "--syslog-ident", значение по умолчанию - "mpd".

Редактируем syslog.conf:

```
ee /etc/syslog.conf
```

Добавляем следующие строки в конец файла:

```
!mpd
*.*                                             /var/log/mpd.log
!*
```

Таким образом, все сообщения от источника "mpd" будут направлены в mpd.log.

Задаем параметры ротации логов:

```
ee /etc/newsyslog.conf
```

Ежедневная ротация в полночь с сохранением 7-ми логов в сжатом формате:

```
/var/log/mpd.log                        600  7     *    @T00  JC
```

Альтернативный вариант, с ежемесячной ротацией и хранением логов за последние три месяца:

```
/var/log/mpd.log                        600  3    *    $M1D0 JC
```

Подробнее о файле конфигурации читаем в справке: [man newsyslog.conf](http://www.freebsd.org/cgi/man.cgi?query=newsyslog.conf&format=html).

Создаем лог-файл:

```
touch /var/log/mpd.log
```

Перезагружаем конфигурацию syslog:

```
service syslogd reload
```

## <a id="bkmrk--7" name="start"></a>Запуск MPD5

Разрешаем запуск MPD, добавляем в /etc/rc.conf параметр: `mpd_enable="YES"`:

```
printf '\nmpd_enable=\"YES\"\n' >>/etc/rc.conf
```

Запускаем службу:

```
service mpd5 start
```

Проверяем, запущена ли служба и параметры запуска:

```
ps -ax | grep mpd5
```

В результате получаем:

```
1274  -  Ss    0:00.00 /usr/local/sbin/mpd5 -p /var/run/mpd5.pid -b
```

Проверяем, слушается ли порт:

```
netstat -an | grep 1723
```

Результат должен быть следующим:

```
tcp4       0      0 *.1723                 *.*                    LISTEN
```

Проверяем сообщения в лог-файле:

```
cat /var/log/mpd.log
```

В случае успешного старта видим следующий текст:

```
Multi-link PPP daemon for FreeBSD                                               
                                                                                
process 1274 started, version 5.7 (root@10i386-default-job-10 21:06 12-Jun-2014)
CONSOLE: listening on 127.0.0.1 5005                                            
web: listening on 0.0.0.0 5006                                                  
PPTP: waiting for connection on 0.0.0.0 1723                                   
```

Заходим браузером в веб-админку: http:/адрес.сервера:5006, проверяем параметры соединений.

Создаем подключение в Windows, либо настраиваем на удаленной стороне MPD-клиент и пробуем подключиться. При настройке клиентского подключения в Windows, чтобы предотвратить туннелирование всего интернет трафика в удаленную сеть, в дополнительных настройках протокола TCP/IP, необходимо отключить флажок "Использовать основной шлюз в удаленной сети". В этом случае будет туннелироваться только трафик удаленной подсети в соответствии с ее классом.

В случае проблем используем tcpdump.

Мониторим физический канал:

```
tcpdump -v -ni <em>интерфейс</em> tcp port 1723 or proto gre
```

Мониторим туннель:

```
tcpdump -ni ng0
```

## <a id="bkmrk--8" name="troubleshoot"></a>Возможные проблемы

Ошибка: "Can't create socket node: No such file or directory. Netgraph initialization failed", может возникнуть после установки новой версии системы. Проблема возникает из-за линковки программы со старыми системными библиотеками. В этом случае необходимо переустановить или пересобрать MPD.

## <a id="bkmrk--9" name="log-parsers"></a>Анализ логов MPD5

Чтобы быть в курсе как используется наш VPN-сервер, организуем ежедневную отправку на почту отчета по сессиям. Для получения административных почтовых уведомлений по протоколу POP3 потребуется установить Dovecot или [Qpopper](https://itadept.ru/freebsd-qpopper/).

Готового решения на все случаи жизни мне найти не удалось. Рассмотрим примеры скриптов, которые можно взять за основу для построения своего анализатора.

### Простейший отчет по сессиям

Сканируем лог за прошедший день командой grep, выбираем сообщения о подключении, отключении клиентов и имена пользователей. Ротация логов должна быть ежедневной.

Результат работы выдает следующий:

```
Jun 14 18:10:20 bsd-10 mpd: pptp0: attached to connection with 92.68.55.2 2539
Jun 14 18:10:23 bsd-10 mpd: [L-1]   MESG: MSRASV5.20
Jun 14 18:10:23 bsd-10 mpd: [L-1]   MESG: MSRAS-0-DESKTOP
Jun 14 18:10:23 bsd-10 mpd: [L-1]   Name: "user1"
Jun 14 18:15:19 bsd-10 mpd: pptp0-0: call cleared by peer
Jun 14 18:15:19 bsd-10 mpd: pptp0-0: killing channel
```

Добавим в /usr/local/etc/periodic/daily скрипт с именем 800.mpd:

```
ee /usr/local/etc/periodic/daily/800.mpd
```

Со следующим содержимым:

```
#!/bin/sh
echo
echo PPTP connections
bzgrep -E '(mpd: pptp)|(MESG:)|(Name)' /var/log/mpd.log.0.bz2
```

Задаем права доступа:

```
chmod 755 /usr/local/etc/periodic/daily/800.mpd
```

### Mpdstat

Единственный готовый скрипт, который мне удалось накопать на просторах интернета.

Сайт проекта: [http://code.google.com/p/mpdstat/](http://code.google.com/p/mpdstat/).

Perl-скрипт интегрируется в periodic, выдает следующий результат:

```
user1
        duration: 0d 00:04:56   link: [L-1]
        from: Jun 14 18:10:23   to: Jun 14 18:15:19

Active Session Report

User Report
       user1: total: 0d 03:53:41           5times
```

Устанавливаем Perl:

```
pkg install perl5
```

Создаем папку для загрузки в пользовательском профиле:

```
mkdir -p ~/src
```

Загружаем Mpdstat:

```
svnlite checkout http://mpdstat.googlecode.com/svn/trunk/ ~/src/mpdstat
```

Переходим в папку с программой:

```
cd ~/src/mpdstat
```

Выполняем установку:

```
make install
```

В случае ошибки установки, переименовываем файл 900.mpdstatus в 900.mpdstat и запускаем установку повторно:

```
mv 900.mpdstatus 900.mpdstat
make install
```

Открываем /etc/periodic.conf, если файл отсутствует в вашей системе, создаем его:

```
ee /etc/periodic.conf
```

Разрешаем исполнения скрипта и задаем путь к лог файлам:

```
daily_status_security_mpdstatus_enable="YES"
daily_status_security_logdir="/var/log"
```

Выполняем тестовый запуск:

```
periodic security
```

Скрипт ищет лог за прошедший день, если он не найден, обрабатывает mpd.log.

## Парсер на PHP

Я использую свой парсер на PHP, генерирующий следующий вывод:

```
L1> Jun 14 18:10:20      92.68.55.2 00:04:59 user1           static.kpn.net MSRASV5.20
L1> Jun 14 18:15:51      92.68.55.2 00:04:01 user1           static.kpn.net MSRASV5.20
L1> Jun 14 18:20:12      92.68.55.2 01:47:45 user1           static.kpn.net MSRASV5.20
L1> Jun 14 21:53:35      92.68.55.2 01:56:10 user1           static.kpn.net MSRASV5.20
L1> Jun 14 23:50:37      92.68.55.2 00:00:55 user1           static.kpn.net MSRASV5.20
```

Скрипт отображает IP-адреса, с которых устанавливаются соединения, и выполняет реверсные DNS-запросы. Параметр "log +PHYS2" должен быть включен в mpd.conf.

Устанавливаем PHP:

```
pkg install php5 php5-bz2
```

Создаем папку программы в профиле пользователя и переходим в нее:

```
mkdir /root/Programs
cd /root/Programs
```

Загружаем архив:

```
fetch <a href="https://itadept.ru/files/freebsd-mpd5-server/MpdLogParser-0.1.tar.bz2">http://itadept.ru//files/freebsd-mpd5-server/MpdLogParser-0.1.tar.bz2</a>
```

Распаковываем:

```
tar -xf MpdLogParser-0.1.tar.bz2
```

Переходим в папку с программой:

```
cd MpdLogParser
```

Создаем файл конфигурации:

```
cp MpdLogParser_Config.php.sample MpdLogParser_Config.php
```

Редактируем конфиг:

```
ee MpdLogParser_Config.php
```

Задаем параметры:

```
/* Часовой пояс из списка: <a href="http://php.net/manual/ru/timezones.php" rel="noopener" target="_blank">http://php.net/manual/ru/timezones.php</a> */

date_default_timezone_set("Europe/Moscow");

/* Путь к лог-файлу */
define('LOG_PATH',"/var/log/mpd.log.0.bz2");

/* IP-адреса, исключаемые из списка */
$IgnoreIP=array(
//    "1.2.3.4",
//    "5.6.7.8",
);
```

Выполняем пробный запуск, лог-файл, заданный в конфиге (mpd.log.0.bz2) должен существовать, автопоиск не предусмотрен:

```
./MpdLogParser.php
```

Добавим в /usr/local/etc/periodic/daily скрипт с именем 800.mpd:

```
ee /usr/local/etc/periodic/daily/800.mpd
```

Со следующим содержимым:

```
#!/bin/sh
echo
echo PPTP connections
/usr/local/bin/php /root/Programs/MpdLogParser/MpdLogParser.php
```

Задаем права доступа:

```
chmod 755 /usr/local/etc/periodic/daily/800.mpd
```

Выполняем тестовый запуск:

```
periodic daily
```

Вывод команды будет отправлен на почту пользователя root.

Настройка завершена.

# Установка VMware Workstation Player в Debian / Ubuntu

На текущей момент самые производительные гипервизоры c большим количеством возможностей выпускает компания VMware. Использование виртуальной машины VMware Workstation Player в Linux удобно тем что в ней есть поддержка DirectX 11+. Это позволяет играть в гостевой системе Windows в производительные игры и использовать приложения для 3D.

После покупки VMware компанией Broadcom, теперь продукты VMware Fusion и Workstation стали бесплатные. Я в статье подправил ссылки, отчасти статья еще актуальная, но надо будет переписать или написать полностью новую статью.

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Установить VMware Workstation Player](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#1)
2. [1.1. Загрузка VMware Player](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#1-1)
3. [1.2. Установка необходимых пакетов](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#1-2)
4. [1.3. Установка VMware Player](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#1-3)
5. [1.4. Запуск VMware Player](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#1-4)
6. [2. Модули ядра vmmon и vmnet](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#2)
7. [2.1. Сборка модулей ядра средствами VMware](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#2-1)
8. [2.2. Ручная сборка и установка модулей ядра](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#2-2)
9. [3. Удалить VMware Workstation Player](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#3)

</nav>## 1. Установить VMware Workstation Player

Установка производится от root пользователя или с привилегиями root через sudo

```
```
su -
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

### 1.1. Загрузка VMware Player

Скачиваем с официального сайта VMware последнею версию [VMware Workstation Player](https://www.vmware.com/products/workstation-player/workstation-player-evaluation.html). Для загрузки необходима регистрировать на сайте Broadcom (*очень редко приходят письма на email*).

<figure class="image" id="bkmrk-">![Раздел Download VMware Workstation 17 Player сайта www.vmware.com](https://notby.net/images/02/website-vmware-com-download-vmware-workstation-17-player.webp)</figure>Ссылка на репозиторий где можно скачать без создания учетной записи: [https://softwareupdate.vmware.com/cds/vmw-desktop/ws/](https://softwareupdate.vmware.com/cds/vmw-desktop/ws/) (с 02.05.2025 не работает, оставил ссылку вдруг заработает.)

### 1.2. Установка необходимых пакетов

VMware Workstation Player во время установки собирает необходимые модули ядра Linux для нормальной работы виртуальной машины. Для сборки модулей ядра в Debian и Ubuntu необходимо чтобы в системы были установлены **build-essential** и **linux-headers-\*\*\*** пакеты. Чтобы не указывать версию ядра системы используем команду **uname -r** в команде на установку.

Устанавливаем необходимые пакеты

```
```
apt install build-essential linux-headers-$(uname -r)
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--1">![В консоли Debian установка пакетов командой "apt install build-essential linux-headers-$(uname -r)". Выведен список того что будет установлено](https://notby.net/images/02/debian-console-apt-install-build-essential-linux-headers-uname-r.webp)</figure>Для **Ubuntu 22.04 LTS** дополнительно еще устанавливаем GCC 12 версии, так как пакет **build-essential** в Ubuntu содержит 11 версию.

```
```
apt install gcc-12
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Дожидаемся окончание установки.

### 1.3. Установка VMware Player

Переходим в каталог куда скачали файл установки VMware Workstation 17 Player (*в моем случае это каталог Downloads в домашней директории*)

```
```
cd /home/user/Downloads/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Смотрим название скаченного файла

```
```
ls | grep VMware-Player
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

*На момент написания статьи файл установки последней версии имеет имя VMware-Player-Full-17.5.0-22583795.x86\_64.bundle*

Выдаем файлу установки VMware-Player права на выполнение

```
```plaintext
chmod +x VMware-Player-Full-17.5.0-22583795.x86_64.bundle
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Устанавливаем VMware Player

```
```plaintext
./VMware-Player-Full-17.5.0-22583795.x86_64.bundle
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--2">![Debian консоль, установка VMware Player 17.5.0 прошла успешно](https://notby.net/images/02/debian-console-install-vmware-player-17-5-0.webp)</figure>### 1.4. Запуск VMware Player

Открываем меню со списком установленных приложений и запускаем **VMware Player**

Если во время запуска VMware Player будет предложено установить модули ядра, значит они не смогли собратся во время установке. Если их установка завершится ошибкой *“Unable to install all modules. See log for details.”*, то читай [следующий раздел](https://notby.net/ustanovka-vmware-workstation-player-v-debian-ubuntu#2) статьи.

<figure class="image" id="bkmrk--3">![VMware Player, окно Welcome to VMware Player, текст лицензии.](https://notby.net/images/02/vmware-player-welcome-to-vmware-player-license.webp)</figure>Читаем лицензионно соглашение и соглашаемся если оно устраивает ⇒ Выбираем проверять на наличии новых версий ⇒ Выбираем использовать бесплатную некоммерческую версию ⇒ Нажимаем **Finish**.

VMware Workstation Player запущена, можно создавать виртуальный машины.

<figure class="image" id="bkmrk--4">![VMware Workstation 17 Player запущена, открыто главное окно](https://notby.net/images/02/vmware-workstation-17-player-main-window.webp)</figure>## 2. Модули ядра vmmon и vmnet

Данный раздел статьи актуален только в том случае если VMware не смогла собрать свои модули ядра для Linux ядра.

VMware Player всегда собирает и устанавливает два своих модуля ядра **vmmon** и **vmnet** для своей работы. Сборка модулей проходит без проблем на стабильных версиях дистрибутивов Linux, так как они используют не самые последние версии ядре Linux.

При запуске VMware Player выводится окно с предложением собрать и загрузить модули ядра

<figure class="image" id="bkmrk--5">![Окно VMware kernel module updater с предложением собрать и загрузить модули ядра](https://notby.net/images/02/vmware-kernel-module-updater-install.webp)</figure>При нажатии **Install**, сборка модулей ядра завершается ошибкой <samp>Unable to install all modules. See log for details. (Exit code 1)</samp>

<figure class="image" id="bkmrk--6">![VMware ошибка: Unable to install all modules. See log for details. (Exit code 1)](https://notby.net/images/02/vmware-unable-to-install-all-modules-see-log-for-details.webp)</figure>Для решения этой проблемы существует проект на GitHub (github.com/mkubecek/vmware-host-modules) с исправленными модулями для сборки на последних ядрах Linux.

Существует два варианта сборки и установки модулей ядра:

1. Замена оригинальных файлов VMware на модифицирование и последующая сборка средствами VMware
2. Полностью ручная сборка модулей ядра и их установка в систему.

Способы сборки и установки будет показыватся на примере версии VMware Workstation Player 17.5.0, которая является последний на момент написания статьи.

### 2.1. Сборка модулей ядра средствами VMware

<mark class="t-green">Данный метод предпочтительный, так как когда обновится ядра LInux, модули под новое ядро будет собраны и установлены средствами VMware при её запуске.</mark>

Скачиваем модифицированные модули для установленной версии VMware Workstation Player

```
```
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-17.5.0.tar.gz
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Вместо <mark class="t-red">17.5.0</mark> указываем установлению в системе версию VMware Workstation Player.

Извлекаем архив

```
```
tar -xzf workstation-17.5.0.tar.gz
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Переходим в извлеченный каталог

```
```
cd vmware-host-modules-workstation-17.5.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Упаковываем в архивы каталоги vmmon-only и vmnet-only

```
```
tar -cf vmmon.tar vmmon-only && tar -cf vmnet.tar vmnet-only
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Копируем архивы в каталог VMware

```
```
cp vmmon.tar vmnet.tar /usr/lib/vmware/modules/source/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем сборку модулей ядра через утилиту vmware-modconfig

```
```
vmware-modconfig --console --install-all
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем VMware Player и проверяем.

Теперь когда будет обновлятся ядро Linux на более новую версию при запуске VMware Player будет происходить сборка и установка модулей ядра.

<figure class="image" id="bkmrk--7">![Окно VMware kernel module updater, происходит процесс сборки и установки модулей ядра vmmon и vmnet](https://notby.net/images/02/vmware-kernel-module-updater-vmmon-vmnet.webp)</figure>### 2.2. Ручная сборка и установка модулей ядра

При этом методе при каждом обновление ядра Linux необходимо будет вручную повторять данный пункт.

Скачиваем модифицированные модули для установленной версии VMware Workstation Player

```
```
wget https://github.com/mkubecek/vmware-host-modules/archive/workstation-17.5.0.tar.gz
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Вместо <mark class="t-red">17.5.0</mark> указываем установлению версию VMware Workstation Player.

Извлекаем архив

```
```
tar -xzf workstation-17.5.0.tar.gz
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

переходим в извлеченный каталог

```
```
cd vmware-host-modules-workstation-17.5.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Собираем и устанавливаем модули в ядро Linux

```
```
make && make install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем VMware Player и проверяем.

## 3. Удалить VMware Workstation Player

Когда необходимо переустановить, заменить версии или полностью удалить VMware, то возникает вопрос: как удалить VMware Workstation Player в Debian или Ubuntu? В списке установленных пакетов VMware Workstation Player нет и её необходимо удалять через утилиту **vmware-installer**.

Выводим список установленных продуктов VMware

```
```
vmware-installer -l
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--8">![Вывод списка установленных продуктов VMware командой "vmware-installer -l" в консоли Debian](https://notby.net/images/02/debian-console-vmware-installer-l-list-products.webp)</figure>Удаляем VMware Player, **vmware-player** - имя удаляемого продукта.

```
```
vmware-installer -u vmware-player
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Сразу будет задан вопрос “All configuration information is about to be removed. Do you wish to keep your configuration files?”, он означает хотим ли сохранить конфигурационные файлы? К конфигурационным файлам относятся настройки VMware и информация о лицензии, но не сами созданные виртуальные машины.

<figure class="image" id="bkmrk--9">![Удаление VMware Player командой "vmware-installer -u vmware-player" в консоли Debian](https://notby.net/images/02/debian-console-vmware-installer-u-vmware-player.webp)</figure>Если был установлен только один продукт, то утилита vmware-installer будет также удалена.

# Выбор режима UEFI или BIOS в VMware Workstation 17 Player

По умолчанию виртуальная машина в VMware создается с режимом загрузки BIOS, если не выбирать Windows 10 или Windows 11. В бесплатной версии VMware Workstation Player в меню нет переключателя выбора режима загрузки (BIOS или UEFI) как в версии VMware Workstation Pro. В статье кратко будет показано как включить UEFI или BIOS режим загрузки в VMware Workstation 17 Player.

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Создаем виртуальную машину](https://notby.net/vybor-rezhima-uefi-ili-bios-v-vmware-workstation-player#1)
2. [2. Редактируем файл виртуальной машины](https://notby.net/vybor-rezhima-uefi-ili-bios-v-vmware-workstation-player#2)
3. [3. Сохраняем файл и запускаем](https://notby.net/vybor-rezhima-uefi-ili-bios-v-vmware-workstation-player#3)

</nav>## 1. Создаем виртуальную машину

Создаем виртуальную машину, но не запускаем её. Можно использовать уже созданную с операционной системой, но тогда ОС не сможет загрузится из-за смены режима загрузки.

<figure class="image" id="bkmrk-">![VMware Workstation 17 Player создание новый виртуальной машины Debian 12. Галочка автоматически запускать снята.](https://notby.net/images/01/vmware-workstation-17-player-create-new-virtual-machine-debian-12.webp)</figure>## 2. Редактируем файл виртуальной машины

Заходим в папку куда создали виртуальную машину и открывает файл с расширением “**.vmx**” (*в моем случае это “Debian 12.vmx” файл*) с именем созданной виртуальной машины в текстовом редакторе.

<figure class="image" id="bkmrk--1">![В текстовом редакторе Geany открыт файл "Debian 12.vmx" и добавлена строка firmware = "efi"](https://notby.net/images/01/geany-opened-debian-12-vmx-file-and-add-firmware-efi.webp)</figure>Находим строку **firmware** в открытом файле и изменяем её значение если необходимо. Если строки **firmware** нет, то VMware работает в режиме BIOS.

Добавляем следующею строку для включения режима UEFI

```
```plaintext
firmware = "efi"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Если нужно использовать режим BIOS изменяем значение на **bios** или полностью удаляем строку.

```
```plaintext
firmware = "bios"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 3. Сохраняем файл и запускаем

Сохраняем файл виртуальной машины и запускаем её для проверки.

Если есть ошибка на некорректный параметр **firmware** при запуске, то это означает что в файле два параметра. Необходимо оставить только один параметр.

<figure class="image" id="bkmrk--2">![VMware Workstation 17 Player, виртуальная машина  запущена в режиме UEFI.](https://notby.net/images/01/vmware-workstation-17-player-running-virtual-machine-uefi-mode.webp)</figure>Виртуальная машина VMware запустилась в режиме UEFI.

# Обновление FreeBSD 14.2 до FreeBSD 14.3

10 июня 2025 года вышла FreeBSD 14.3, и я решил обновиться с FreeBSD 14.2. Обновление в пределах одной ветки FreeBSD проходит проще и быстрее, поскольку нет необходимости переустанавливать приложения и сервисы. Начинаем процесс обновления до FreeBSD 14.3.

Если у тебя FreeBSD 13, то производи обновление как описано в статье: [Обновление FreeBSD 13.2 до FreeBSD 14](https://notby.net/obnovlenie-freebsd-13-2-do-freebsd-14). Только внеси измерение в команду запуска обновления, чтобы получилось: `freebsd-update upgrade -r 14.3-RELEASE`

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Обновление установленных приложений](https://notby.net/obnovlenie-freebsd-14-2-do-freebsd-14-3#1)
2. [2. Запуск обновления до FreeBSD 14.3](https://notby.net/obnovlenie-freebsd-14-2-do-freebsd-14-3#2)
3. [3. Установка обновления FreeBSD 14.3](https://notby.net/obnovlenie-freebsd-14-2-do-freebsd-14-3#3)
4. [4. Установка исправлений безопасности](https://notby.net/obnovlenie-freebsd-14-2-do-freebsd-14-3#4)

</nav>## 1. Обновление установленных приложений

Так как обновление FreeBSD происходит внутри одной ветки FreeBSD 14, то можно обновить все сервисы, библиотеки и приложения заранее.

Обновляем приложения через пакеты

```
```
pkg upgrade
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Или обновляем через порты

```
```
portmaster -a
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Статьи с подробным описанием процесса обновления всех приложений через [порты](https://notby.net/obnovlenie-vsekh-ustanovlennykh-portov-freebsd) или [пакеты](https://notby.net/upravlenie-paketami-v-freebsd) в FreeBSD.

## 2. Запуск обновления до FreeBSD 14.3

До запуска процесса обновления можно сменить текстовый редактор по умолчанию (vi) на другой. Например, сменяем на **ee**.

```
```
setenv EDITOR ee
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Во время обновления, если понадобится ручное редактирование файла, будет вызыватся текстовый редактор **ee**.

Во время обновления может что-то пойти не так и будет утерян доступ к серверу через SSH. Например, если сервер использует не стандартное ядро, то после обновления будет GENERIC ядро. Если FreeBSD без модификаций, то все должно пройти безошибочно.

Запускаем процесс обновления до версии **FreeBSD 14.3**

```
```
freebsd-update upgrade -r 14.3-RELEASE
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Установщик спросит разумно что будут установлены компоненты kernel/generic world/base, а компоненты debug и lib32 не будет установлены, отвечаем **yes**

<figure class="image" id="bkmrk-">![Обновление до версии FreeBSD 14.3 используя команду “freebsd-update upgrade -r 14.3-RELEASE”. На вопрос Does this look reasonable? Ответ yes](https://notby.net/images/06/freebsd-update-upgrade-r-14-3-release-does-this-look-reasonable-yes.webp)</figure>Дожидаемся окончания процесса загрузки обновления.

Во время обновления автоматически могут не обновится конфигурационные файлы и их необходимо будет обновить вручную. Но такое маловероятно произойдет при обновлении внутри одной ветки и с файлами конфигурации по стандарту.

Установщик показывает какие изменения будут внесены в файле /etc/ssh/sshd\_config (замена строки **\#VersionAddendum** которая содержит версию FreeBSD) и если все корректно отвечаем **yes**.

<figure class="image" id="bkmrk--1">![Обновление до версии FreeBSD 14.3. Показаны какие изменения будут в файле /etc/ssh/sshd_config и задается вопрос “разумны такие изменения?“, ответ yes](https://notby.net/images/06/upgrade-to-freebsd-14-3-file-sshd-config-changes-are-reasonable-yes.webp)</figure>Далее будет показан список файлов которые будут добавлены, изменены и удалены во время обновления. Для того чтобы их пролистать нажимаем <kbd>Q</kbd> на клавиатуре, и после списка будет выведено сообщение <samp>To install the downloaded upgrades, run ‘freebsd-update \[options\] install’.</samp> *(Чтобы установить загруженные обновления, выполните команду "freebsd-update \[options\] install".)*.

## 3. Установка обновления FreeBSD 14.3

Устанавливаем обновление FreeBSD 14.3

```
```
freebsd-update install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Процесс установки обновлений запущен, по завершению программа обновлений сообщит <samp>Please reboot and run 'freebsd-update \[options\] install' again to finish installing updates.</samp> *(Пожалуйста, перезагрузитесь и запустите команду "freebsd-update \[options\] install" снова, чтобы завершить установку обновлений.)*.

<figure class="image" id="bkmrk--2">![Обновление до версии FreeBSD 14.3. Написана команда “freebsd-update install“. Выведено сообщение “Please reboot and run 'freebsd-update [options] install' again to finish installing updates.“.](https://notby.net/images/06/upgrade-to-freebsd-14-3-freebsd-update-install-please-reboot.webp)</figure>Перезагружаем сервер

```
```
shutdown -r now
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем команду для завершения установки обновления

```
```
freebsd-update install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--3">![Выполнена команда “freebsd-update install“, обновление до версии FreeBSD 14.3 успешно завершено](https://notby.net/images/06/upgrade-to-freebsd-14-3-freebsd-update-install-done.webp)</figure>Обновление до версии FreeBSD 14.3 успешно произведено.

```
```
uname -v
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

```
```plaintext
FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7 GENERIC
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Проверяем что все программы и сервисы работают корректно, ошибок после установки обновлений не появилось.

## 4. Установка исправлений безопасности

Сразу после обновления FreeBSD до последней версии, нет смысла проверять новые исправления безопасности, так как во время процесса обновления системы были установлены все последнее исправления безопасности.

Спустя какое-то время периодически необходимо проверять и установлять исправления безопасности FreeBSD. Проверку наличия обновлений можно настроить по расписанию через crontab.

Запускаем установку исправлений безопасности FreeBSD 14.3

```
```
freebsd-update fetch install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Дожидаемся окончания процесса установки исправлений безопасности.

Если во время обновления были затронуты файлы ядра FreeBSD, то необходимо будет перезагрузить сервер.

# Настройка VPN сервера WireGuard в FreeBSD

VPN надёжно шифрует трафик, оберегая данные в публичных Wi-Fi, при сомнительных провайдерах или когда хочется больше анонимности и безопасности в сети. Сервер для VPN может быть куплен у провайдера VDS или можно использовать домашний сервер с внешним IP адресом. В статье разберём WireGuard — лёгкий, шустрый, открытый и безопасный VPN-протокол.

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Установка WireGuard в FreeBSD](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#1)
2. [2. Генерация ключей для сервера и клиента WireGuard](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#2)
3. [2.1. Генерация ключей сервера](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#2-1)
4. [2.2. Генерация ключей клиента](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#2-2)
5. [3. Получение имени сетевой карты](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#3)
6. [4. Настройка и конфигурация WireGuard сервера (wg0.conf)](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#4)
7. [5. Автозагрузка и запуск VPN сервера WireGuard](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#5)
8. [6. Создание файла конфигурации WireGuard клиента](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#6)
9. [7. Генерация QR-кода WireGuard туннеля](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#7)
10. [8. Настройка файрвола и маршрутизации в FreeBSD](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#8)
11. [8.1. Настройка IPFW для WireGuard](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#8-1)
12. [8.2. Настройка PF для WireGuard](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#8-2)
13. [9. Подключение к серверу WireGuard](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#9)
14. [9.1. Подключение из Windows к VPN серверу WireGuard ](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#9-1)
15. [9.2. Подключение из Linux к VPN серверу WireGuard ](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#9-2)
16. [9.3. Подключение с телефона Android к VPN серверу WireGuard ](https://notby.net/nastroyka-vpn-servera-wireguard-v-freebsd#9-3)

</nav>## 1. Установка WireGuard в FreeBSD

В FreeBSD уже давно WireGuard встроен в ядро и уже присутствует утилита wg, но для более легкой настройки удобнее использовать **wg-quick**.

Устанавливаем **wireguard-tools** через пакеты

```
```
pkg install wireguard-tools
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk-">![Установка wireguard-tools версии 1.0.20210914_3 через пакеты FreeBSD при помощи команды pkg install wireguard-tools](https://notby.net/images/07/freebsd-pkg-install-wireguard-tools.webp)</figure>Или устанавливаем **wireguard-tools** из портов

```
```
cd /usr/ports/net/wireguard-tools/ && make install clean
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 2. Генерация ключей для сервера и клиента WireGuard

Для шифрования соединения необходимо сгенерировать приватный и публичный ключ для VPN сервера и клиента WireGuard. В официальном руководстве WireGuard показан пример, где ключи генерируются в каталог **/etc/wireguard/** каждый в отдельный файл. Эти файлы нужны только, для того чтобы перенести из них значения ключей в файлы конфигурации VPN сервера и клиента.

### 2.1. Генерация ключей сервера

Я накидал консольную команду которая выведет пару ключей на экран терминала и их можно будет скопировать в блокнот или использовать другое окно терминала. Для генерации приватного ключа используется команда `wg genkey`, для генерации публичного ключа используется команда `wg pubkey` и в качестве параметра для нее передается приватный ключ через временную переменную **WGKEY**.

Генерируем приватный и публичный ключ сервера:

```
```
WGKEY=$(wg genkey); echo "Server Private Key: $WGKEY"; echo $WGKEY | echo "Server Public Key: $(wg pubkey)"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Значение **Server Private Key** необходимо будет вставить в файл конфигурации сервера, а значение **Server Public Key** в файл конфигурации клиента.

<figure class="image" id="bkmrk--1">![Выполнена консольная команда для генерации пары ключей WireGuard сервера в терминале FreeBSD, выведены ключи Server Private Key и Server Public Key](https://notby.net/images/07/freebsd-server-key-pair-wg-genkey-wg-pubkey.webp)</figure>Генерировать ключи можно на любом компьютере где уставлен WireGuard, необязательно на сервере, где будет работать VPN сервер.

### 2.2. Генерация ключей клиента

Консольная команда генерации ключей аналогичен предыдущей, но с добавлением генерации **Pre-Shared Key** через команду `wg genpsk` и заменой слова **Server** на **Client**

Ключ **Pre-Shared Key** используется для дополнительного шифрования внутри основного. Оно необходимо для защиты от расшифровки трафика инопланетными цивилизациями при помощи квантовых компьютеров или в будущем квантовым компьютером созданным человечеством.

Генерируем приватный и публичный ключ клиента:

```
```
WGKEY=$(wg genkey); echo "Client Private Key: $WGKEY"; echo $WGKEY | echo "Client Public Key: $(wg pubkey)"; echo "Client Pre-Shared Key: $(wg genpsk)"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Значения **Client Private Key** и **Client Pre-Shared Key** необходимо будет вставить в файл конфигурации клиента, а значение **Client Public Key** в файл конфигурации сервера.

<figure class="image" id="bkmrk--2">![Выполнена консольная команда для генерации ключей WireGuard клиента в терминале FreeBSD, выведены ключи Server Private Key, Server Public Key и Client Pre-Shared Key](https://notby.net/images/07/freebsd-client-key-pair-wg-genkey-wg-pubkey-wg-genpsk.webp)</figure>Для каждого отдельного пользователя/устройства необходимо генерировать свои ключи.

## 3. Получение имени сетевой карты

Перед настройкой конфигурации сервера необходимо знать имя сетевой карты которая смотрит в интернет.

Выводим список всех сетевых интерфейсов и находим имя нужной сетевой карты

```
```
ifconfig
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Или можно получить имя сетевой карты, которая использует шлюз по умолчанию командой

```
```
route -n get default | grep 'interface:' | awk '{print $2}'
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

```
```plaintext
em0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

В моем случае команда вывела имя **em0** сетевого интерфейса, который получает интернет. Почти во всех случаях команда выведет имя нужной сетевой карты.

## 4. Настройка и конфигурация WireGuard сервера (wg0.conf)

Создаем файл конфигурации **wg0.conf** для VPN сервера WireGuard в каталоге **/usr/local/etc/wireguard/**

```
```
nano /usr/local/etc/wireguard/wg0.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Описание основных параметров конфигурационного файла **wg0.conf** (*строки для работы в сетях IPv6 закомментированы*)

```
```ini
# Файл конфигурации VPN сервера WireGuard 
#
# Раздел "Interface" относится к настройкам сервера
[Interface]
# Приватный ключ сервера из значения "Server Private Key"
PrivateKey = gMtlDa6fcFLfKBRQiBJIaGzvVu9C0tGZrsQRg1DJMHU=
# IP адрес сервера и маска внутренней сети VPN
Address = 192.168.10.1/24
#Address = fd20:20:20::1/64
# Порт сервера
ListenPort = 51820

# Разделы "Peer" относится к настройкам клиентов
[Peer]
# Публичный ключ клиента из значения "Clinet Puplic Key"
PublicKey = MW5v76GNuyMXLyMmH6nDqQ98XdHNbdWluGB42J8SU3Y=
# Ключ PSK из значения "Clinet Pre-Shared Key"
PresharedKey = G1WVZwGj+bDzggvqx9jBTL6NH4dhlW5rCW0PCFHY2oY=
# IP адрес клиента (указание маски 32 обязательно для IPv4)
AllowedIPs = 192.168.10.2/32
#AllowedIPs = fd20:20:20::2/128

# Настройка для второго устройства
#[Peer]
#PublicKey = "Clinet Puplic Key"
#PresharedKey = "Clinet Pre-Shared Key"
#AllowedIPs = 192.168.10.3/32
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

**Компактный файл конфигурации сервера выглядит так:**

```
```ini
[Interface]
PrivateKey = gMtlDa6fcFLfKBRQiBJIaGzvVu9C0tGZrsQRg1DJMHU=
Address = 192.168.10.1/24
ListenPort = 51820

[Peer]
PublicKey = MW5v76GNuyMXLyMmH6nDqQ98XdHNbdWluGB42J8SU3Y=
PresharedKey = G1WVZwGj+bDzggvqx9jBTL6NH4dhlW5rCW0PCFHY2oY=
AllowedIPs = 192.168.10.2/32
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Основные изменения которые необходимо внести в файл конфигурации:

- параметр **PrivateKey** необходимо изменить на свой приватный ключ сервера из **“Server Private Key”**;
- вместо **ens33** необходимо указать имя своей сетевой карты;
- параметр **PublicKey** необходимо изменить на свой публичный ключ клиента из **“Client Private Key”**;
- параметр **PresharedKey** необходимо изменить на свой сгенерированный PSK ключ из **“Client Pre-Shared Key”**.

Вносим необходимые измерения и сохраняем файл.

## 5. Автозагрузка и запуск VPN сервера WireGuard

Добавляем в автозагрузку, где **wg0** — имя файла конфигурации без указания расширения **.conf**

```
```
sysrc wireguard_enable="YES" && sysrc wireguard_interfaces="wg0"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--3">![VPN сервера WireGuard добавлен составной командой sysrc wireguard_enable="YES" && sysrc wireguard_interfaces="wg0" в автозагрузку FreeBSD](https://notby.net/images/07/freebsd-sysrc-wireguard-enable-yes-sysrc-wireguard-interfaces-wg0.webp)</figure>Или вручную открываем файл **/etc/rc.conf**

```
```
nano /etc/rc.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

и добавляем строки:

```
```plaintext
wireguard_enable="YES"
wireguard_interfaces="wg0"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем VPN сервера WireGuard

```
```
wg-quick up wg0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--4">![VPN сервера WireGuard запущен командой “wg-quick up wg0” в операционной системе FreeBSD, выведены сообщения процесса запуска WireGuard](https://notby.net/images/07/freebsd-wg-quick-up-wg0.webp)</figure>Для остановки используем команду

```
```
wg-quick down wg0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 6. Создание файла конфигурации WireGuard клиента

Создаем файл конфигурации WireGuard клиента **wg0-client.conf** в каталоге **/usr/local/etc/wireguard/**

```
```
nano /usr/local/etc/wireguard/wg0-client.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Файл конфигурации клиента создается на сервере для удобства, чтобы была возможность в случае чего скопировать его в WireGuard клиент или передать через QR-код. Необязательно создавать данный файл на сервере, его можно сразу создать в WireGuard клиенте на устройстве пользователя.

Описание основных параметров конфигурационного файла WireGuard клиента

```
```ini
# Файл конфигурации VPN клиента WireGuard 
#
# Раздел "Interface" относится к настройкам клиента
[Interface]
# Приватный ключ клиента из значения "Client Private Key"
PrivateKey = QKlR2932N1k5K4OvQ82DqQQnfJa/kpr3NIHtj+loTk4=
# IP адрес клиента и маска внутренней сети VPN
Address = 192.168.10.2/24
# Публичные DNS сервера или если на сервера VPN запущен DNS,
# то указываем IP адрес WireGuard сервера внутри VPN сети
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001
#DNS = 192.168.10.1

# Раздел "Peer" относится к настройкам подключения к серверу
[Peer]
# Публичный ключ сервера из значения "Server Puplic Key"
PublicKey = Kyhl31NZO9hXhORc3hkpNMWFOF69ZCzlcQ4P70mh4xU=
# Ключ PSK из значения "Clinet Pre-Shared Key"
PresharedKey = G1WVZwGj+bDzggvqx9jBTL6NH4dhlW5rCW0PCFHY2oY=
# Публичный IP адрес сервера и порт, который был указан в файле wg0.conf
Endpoint = 80.95.110.25:51820
# До каких IP адресов пропускать трафик через VPN
# Весь трафик пускать через WireGuard
AllowedIPs = 0.0.0.0/0, ::/0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Используй всегда компактный файл, так как он необходим для генерации QR-кода и не везде поддерживается кириллица.

**Компактный файл конфигурации клиента выглядит так:**

```
```ini
[Interface]
PrivateKey = QKlR2932N1k5K4OvQ82DqQQnfJa/kpr3NIHtj+loTk4=
Address = 192.168.10.2/24
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001

[Peer]
PublicKey = Kyhl31NZO9hXhORc3hkpNMWFOF69ZCzlcQ4P70mh4xU=
PresharedKey = G1WVZwGj+bDzggvqx9jBTL6NH4dhlW5rCW0PCFHY2oY=
Endpoint = 80.95.110.25:51820
AllowedIPs = 0.0.0.0/0, ::/0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Основные изменения которые необходимо внести в файл конфигурации:

- параметр **PrivateKey** необходимо изменить на свой приватный ключ клиента из **“Client Private Key”**;
- параметр **PublicKey** необходимо изменить на свой публичный ключ сервера из **“Server Private Key”**;
- параметр **PresharedKey** необходимо изменить на свой сгенерированный PSK ключ из **“Client Pre-Shared Key”**;
- в параметре **Endpoint** необходимо указать **IP адрес** и **порт** своего WireGuard клиента.

Вносим необходимые измерения и сохраняем файл.

## 7. Генерация QR-кода WireGuard туннеля

С телефона очень удобно получать файл конфигурации через сканирование QR-кода, но для этого файл **wg0-client.conf** необходимо преобразовать в QR-код. Утилита qrencode может создавать QR-коды и выводить их в консоль.

Устанавливаем утилиту **qrencode \[libqrencode\]**

```
```
pkg install libqrencode
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Генерируем **QR-код** в терминале

```
```
qrencode -t ANSIUTF8 -r /usr/local/etc/wireguard/wg0-client.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где /**etc/wireguard/wg0-client.conf** — путь до файла конфигурации клиента.

<figure class="image" id="bkmrk--5">![Сгенерирован QR-код конфигурации WireGuard при помощи команды “qrencode -t ANSIUTF8 -r /usr/local/etc/wireguard/wg0-client.conf” в консольном терминале FreeBSD](https://notby.net/images/07/freebsd-qrencode-t-ansiutf8-r-usr-local-etc-wireguard-wg0-client-conf.webp)</figure>## 8. Настройка файрвола и маршрутизации в FreeBSD

Чтобы была возможность раздавать интернет внутри VPN сети, необходимо настроить маршрутизацию пакетов через один из трех доступных файрволов (**IPFW**, **PF**, **IPF**) в FreeBSD.

Если сервер является удаленным и без возможности получения доступа через дистанционную клавиатуру и монитор, то при настройке файрвола нужно быть очень внимательным. Так как если будет ошибка в настройке может получится так, что будет невозможно подключится через SSH.

*Я использую в качестве файрвола **IPFW**, поэтому покажу минимальные необходимые настройки на основе него, но также покажу еще пример настройки PF.*

### 8.1. Настройка IPFW для WireGuard

Включаем IP-форвардинг

```
```
sysctl net.inet.ip.forwarding=1
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Открываем файл **/etc/rc.conf**

```
```
nano /etc/rc.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строки

```
```ini
gateway_enable="YES" # Включить шлюз (сделает net.inet.ip.forwarding=1)
firewall_enable="YES" # Включить IPFW
firewall_nat_enable="YES" # Включить NAT
firewall_script="/etc/ipfw.rules" # Файл с правилами IPFW
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Строку **gateway\_enable="YES"** можно не добавлять, а вместо этого добавить строку **net.inet.ip.forwarding=1** в файл **/etc/sysctl.conf**

Открываем или создаем файл конфигурации **/etc/ipfw.rules**

```
```
nano /etc/ipfw.rules
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Файл конфигурации IPFW + NAT для WireGuard VPN-сервера будет выглядеть примерно так:

```
```bash
#!/bin/sh
# Очищаем список правил IPFW
ipfw -q -f flush
# Команда добавления правила, -q — режим без вывода сообщений
cmd="ipfw -q add"
# Сетевые интерфейсы заносим в переменные
inet_if="em0" # сетевая карта интернета
wg_if="wg0" # интерфейс WireGuard (если wg0.conf, то указывать wg0)

# Разрешить локальный трафик
$cmd allow all from any to any via lo0

# Разрешить любые пакеты внутри сети WireGuard
$cmd allow ip from any to any via $wg_if

# Разрешить доступ к SSH серверу по 22 порту
$cmd allow tcp from any to me 22 in via $inet_if

# Разрешить доступ к VPN-серверу по протоколу UDP на 51820 порт
$cmd allow udp from any to me 51820 in via $inet_if

# Настройка маршрутизации для WireGuard
ipfw -q nat 1 config if $inet_if same_ports unreg_only deny_in reset
# Разрешить проходить любым пакетам через маршрутизацию
$cmd nat 1 all from any to any via $inet_if
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Этих настроек будет достаточно для раздачи интернета внутрь VPN сети и будет возможность подключится к WireGuard и SSH из интернета. Весь исходящий трафик с сервера в интернет будет идти через правило маршрутизации.

Вносим изменения и сохраняем файл с правилами IPFW.

Будь внимателен. Если есть ошибка или неточность в правилах, можно потерять доступ по SSH.

Запускаем службу IPFW

```
```
service ipfw start
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Можно переходить к проверке VPN-сервера WireGuard.

Более подробно о настройке IPFW читай: [Настройка файрвола IPFW в FreeBSD](https://notby.net/nastroyka-fayrvola-ipfw-v-freebsd) и [Настройка IPFW + NAT в FreeBSD](https://notby.net/nastroyka-ipfw-nat-v-freebsd)

### 8.2. Настройка PF для WireGuard

Включаем IP-форвардинг

```
```
sysctl net.inet.ip.forwarding=1
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Открываем файл **/etc/sysctl.conf**

```
```
nano /etc/sysctl.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

добавляем строку **net.inet.ip.forwarding=1** для постоянного включения IP-форвардинга

```
```plaintext
net.inet.ip.forwarding=1
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Сохраняем файл и закрываем.

Открываем файл **/etc/rc.conf**

```
```
nano /etc/rc.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строки

```
```ini
pf_enable="YES" # Включить PF 
pf_rules="/etc/pf.conf" # Файл с правилами PF
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Открываем или создаем файл конфигурации **/etc/pf.conf**

```
```
nano /etc/pf.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Файл конфигурации PF + NAT для WireGuard VPN-сервера будет выглядеть примерно так:

```
```plaintext
# Определение интерфейсов и параметров
inet_if="em0" # сетевая карта интернета
wg_if="wg0" # интерфейс WireGuard (если wg0.conf, то указывать wg0)
wg_net = "192.168.10.0/24"  # Внутренняя сеть WireGuard (которая указана в wg0.conf)

# Пропускать локальный трафик
set skip on lo0

# Включение NAT для трафика из сети WireGuard
nat on $inet_if from $wg_net to any -> ($inet_if)

# Разрешить любые пакеты внутри сети WireGuard
pass on $wg_if all

# Разрешить доступ к SSH серверу по 22 порту
pass in on $inet_if proto tcp from any to ($inet_if) port 22

# Разрешить доступ к VPN-серверу по протоколу UDP на 51820 порт
pass in on $inet_if proto udp from any to ($inet_if) port 51820

# Разрешить весь исходящий трафик
pass out all
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Этих настроек будет достаточно для раздачи интернета внутрь VPN сети и будет возможность подключится к WireGuard и SSH из интернета.

Вносим изменения и сохраняем файл с правилами PF.

Будь внимателен. Если есть ошибка или неточность в правилах, можно потерять доступ по SSH.

Запускаем службу PF

```
```
service pf start
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Можно переходить к проверке VPN-сервера WireGuard.

## 9. Подключение к серверу WireGuard

Теперь необходимо подключится к VPN сервера WireGuard и проверить его работоспособность с различных устройств. Если что-то не будет работать, необходимо внимательно проверить настройки и корректность внесения ключей.

### 9.1. Подключение из Windows к VPN серверу WireGuard 

Запускаем **PowerShell** и копируем файл **wg0-client.conf** с сервера через утилиту **scp** в любое место на компьютере, например на рабочий стол

```
```
scp root@80.95.110.25:/etc/wireguard/wg0-client.conf 'C:\Users\User\Desktop\'
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Вместо **root@80.95.110.25** указываем свои данные для доступа по SSH, вместо **User** указываем свое имя пользователя Windows.

<figure class="image" id="bkmrk--6">![Запущен PowerShell в Windows 10, выполнена команда “scp root@80.95.110.25:/etc/wireguard/wg0-client.conf 'C:\Users\User\Desktop\'”, файл wg0-client.conf успешно скопирован на рабочий стол](https://notby.net/images/10/windows10-powershell-scp-etc-wireguard-wg0-client-conf.webp)</figure>Скачиваем с официального сайта [wireguard-installer.exe](https://download.wireguard.com/windows-client/wireguard-installer.exe) и запускаем установщик. Произойдет установка WireGuard и он автоматически запустится.

Нажимаем на кнопку **Импорт туннелей из файла** и выбираем файл, скачанный ранее.

<figure class="image" id="bkmrk--7">![Запущен WireGuard в Windows 10, нажата кнопка “Импорт туннелей из файла”, открыто окно с выбором файлов и выбран файл wg0-client.conf](https://notby.net/images/10/windows10-wireguard-import-tunneley-iz-fayla-vybran-fayl-wg0-client-conf.webp)</figure>Подключаемся к WireGuard серверу нажав кнопку **Подключить** и пробуем куда-нибудь зайти.

<figure class="image" id="bkmrk--8">![Запущен WireGuard в Windows 10, подключен wg0-client туннель, выведена статистика успешного VPN подключения, трафик принимается и передается](https://notby.net/images/10/windows10-wireguard-uspeshnoe-podklyuchenie-k-vpn-serveru-trafik-peredaetsya.webp)</figure>Как можно видеть, трафик принимается и передается, VPN WireGuard успешно работает.

Если интернет не работает, то проверяем что пакеты доходят до IP адреса сервера внутри VPN сети и до IP адреса в интернете

```
```
ping 192.168.10.1; ping 1.1.1.1
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где **192.168.10.1** — IP адрес WireGuard сервера указанный в файле **wg0.conf** в параметре Address, а IP адрес **1.1.1.1** — публичный DNS сервер.

### 9.2. Подключение из Linux к VPN серверу WireGuard 

Устанавливаем **WireGuard**

```
```
apt install wireguard
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Копируем файл **wg0-client.conf** с сервера в каталог **/etc/wireguard/** через **scp**

```
```
scp root@80.95.110.25:/etc/wireguard/wg0-client.conf /etc/wireguard/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Подключаемся к WireGuard серверу

```
```
wg-quick up wg0-client
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где **wg0-client** — имя файла конфигурации без указания расширения **.conf**

Проверяем что пакеты доходят до IP адреса сервера внутри VPN сети и до IP адреса в интернете

```
```
ping 192.168.10.1 -c 3; ping 1.1.1.1 -c 3
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где **192.168.10.1** — IP адрес WireGuard сервера указанный в файле **wg0.conf** в параметре Address, а IP адрес **1.1.1.1** — публичный DNS сервер.

<figure class="image" id="bkmrk--9">![Выполнена команда “ping 192.168.10.1 -c 3; ping 1.1.1.1 -c 3” в консоли Debian, успешный пинг до 192.168.10.1 и 1.1.1.1 адресов, потерь нет](https://notby.net/images/10/debian-console-ping-192-168-10-1-c-3-ping-1-1-1-1-c-3.webp)</figure>Как можно видеть, пинг до VPN сервера WireGuard и публичного DNS 1.1.1.1 успешен, можно пользоватся VPN WireGuard.

Чтобы выключить VPN, используем команду

```
```
wg-quick down wg0-client
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Если необходимо, чтобы VPN подключался при запуске компьютера, то добавляем в автозагрузку автоматическое подключение к серверу WireGuard

```
```
systemctl enable wg-quick@wg0-client
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Чтобы убрать из автозагрузки автоматическое подключение WireGuard, используем команду

```
```
systemctl disable wg-quick@wg0-client
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

### 9.3. Подключение с телефона Android к VPN серверу WireGuard 

Устанавливаем приложение **WireGuard** из Google Play.

Запускаем приложение, нажимаем на <kbd>+</kbd> в нижней правой части экрана, выбираем из списка **Сканировать QR-код** и сканируем **QR-код** из консоли. Можно загрузить файл **wg0-client.conf** на телефон, выбрать из списка **Импорт из файла или архива** и указать данный файл.

<figure class="image" id="bkmrk--10">![Приложение WireGuard запущено на Android телефоне, нажата кнопка добавить туннель, выведено меню как можно добавить туннель](https://notby.net/images/10/android-wireguard-menyu-knopki-dobavit-tunnel.webp)</figure>Подключаемся к WireGuard серверу и пробуем куда-нибудь зайти.

<figure class="image" id="bkmrk--11">![Приложение WireGuard запущено на Android телефоне, выведена статистика успешного VPN подключения, трафик принимается и передается](https://notby.net/images/10/android-wireguard-uspeshnoe-podklyuchenie-k-vpn-serveru-trafik-peredaetsya.webp)</figure>Как можно видеть, в статистике трафик принимается и передается, VPN WireGuard успешно работает.

# Сборка и установка AmneziaWG на Debian из исходного кода

AmneziaWG состоит из двух частей: модуля ядра Linux, утилит awg и awg-quick для управления туннелями. В официальном репозитории Debian отсутствует AmneziaWG. Для установки можно использовать сторонний репозиторий ppa, но я покажу в статье полностью ручной процесс сборки. Это даст контроль и безопасность, ведь неизвестно, собран ли в репозитории пакет из исходного кода с github'а или нет.

В статье принято следующее обозначение: если перед командой находится символ **$**, её можно выполнять от имени обычного пользователя; если перед командой находится символ **\#**, её необходимо выполнять от имени пользователя root или с использованием sudo.

```
```
<- выполнять от обычного пользователя
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

```
```
<- выполнять от root-пользователя или с его привилегиями через sudo
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Подготовка к сборке и установке AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#1)
2. [1.1. Установка необходимых утилит](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#1-1)
3. [1.2. Установка заголовков ядра](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#1-2)
4. [2. Модуль ядра AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#2)
5. [2.1. Загрузка исходного кода модуля ядра AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#2-1)
6. [2.2. Сборка и установка модуля ядра через DKMS](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#2-2)
7. [2.3. Сборка и установка модуля ядра вручную](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#2-3)
8. [3. Утилиты awg и awg-quick для управления AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#3)
9. [3.1. Загрузка исходного кода утилит AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#3-1)
10. [3.2. Сборка утилит awg и awg-quick](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#3-2)
11. [3.3. Установка утилит awg и awg-quick](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#3-3)
12. [4. Конфигурация AmneziaWG и перенос файлов WireGuard](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#4)
13. [5. Удаление AmneziaWG](https://notby.net/sborka-i-ustanovka-amneziawg-na-debian-iz-iskhodnogo-koda#5)

</nav>## 1. Подготовка к сборке и установке AmneziaWG

### 1.1. Установка необходимых утилит

Устанавливаем утилиту **git** для клонирования репозиториев с github, компилятор **gcc** и сборщик **make**

```
```
apt install git make gcc
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

### 1.2. Установка заголовков ядра

Для сборки модуля необходимы заголовки ядра Linux установленной системы

```
```
apt install linux-headers-$(uname -r)
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Чтобы заголовки ядра автоматически загружались при обновлении ядра, можно установить мета-пакет с указанием архитектуры компьютера

```
```
apt install linux-headers-amd64
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 2. Модуль ядра AmneziaWG

### 2.1. Загрузка исходного кода модуля ядра AmneziaWG

Создаем для удобства каталог **git** в домашней директории пользователя и переходим в него

```
```
mkdir -p ~/git && cd ~/git
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Клонируем репозиторий **amneziawg-linux-kernel-module**

```
```
git clone https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk-">![Репозиторий amneziawg-linux-kernel-module скопирован с github командой “git clone https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git” в консоли Debian, выведены сообщения процесса клонирования репозитория](https://notby.net/images/06/debian-console-git-clone-https-github-com-amnezia-vpn-amneziawg-linux-kernel-module-git.webp)</figure>### 2.2. Сборка и установка модуля ядра через DKMS

Заходим под root-пользователем или выполняем команды через sudo

```
```
su -
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

#### 2.2.1. Установка DKMS

**Dynamic Kernel Module Support (DKMS)** используется для того чтобы при обновлении ядра Linux до новой версии, происходила автоматическая сборка дополнительных моделей ядра из исходных кодов.

Устанавливаем **DKMS**

```
```
apt install dkms
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Дожидаемся окончания установки.

#### 2.2.2. Подготовка исходного кода для DKMS

Создаем каталог **amneziawg-1.0.0** в каталоге **/usr/src/**

```
```
mkdir -p /usr/src/amneziawg-1.0.0/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Переходим в каталог клонированного репозитория **amneziawg-linux-kernel-module**

```
```
cd amneziawg-linux-kernel-module
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Копируем содержимое каталога **src** в каталог **/usr/src/amneziawg-1.0.0/** который ранее создали

```
```
cp -r src/* /usr/src/amneziawg-1.0.0/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Копируем скрипты загрузки исходных кодов ядра Linux для модуля AmneziaWG в каталог **/usr/src/amneziawg-1.0.0/**

```
```
install -m 755 kernel-tree-scripts/*-sources.sh /usr/src/amneziawg-1.0.0/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

*Копирование через утилиту **install** позволяет сразу установить необходимые права для выполнения скриптов.*

<figure class="image" id="bkmrk--1">![В консоли Debian последовательно выполнены команды: “cd /home/user/git/”, “mkdir -p /usr/src/amneziawg-1.0.0/”, “cd amneziawg-linux-kernel-module”, “cp -r src/* /usr/src/amneziawg-1.0.0/”, “install -m 755 kernel-tree-scripts/*-sources.sh /usr/src/amneziawg-1.0.0/”](https://notby.net/images/06/debian-console-copy-amneziawg-source-to-usr-src-amneziawg-1-0-0.webp)</figure>#### 2.2.3. Сборка и установка модуля ядра

Добавляем модуль ядра **amneziawg** в **DKMS**

```
```
dkms add -m amneziawg -v 1.0.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Собираем модуль ядра **amneziawg** через **DKMS**

```
```
dkms build -m amneziawg -v 1.0.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Устанавливаем модуль ядра **amneziawg** через **DKMS**

```
```
dkms install -m amneziawg -v 1.0.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--2">![Модуль ядра AmneziaWG успешно собран и установлен при помощи DKMS в Debian, использовались следующие команды в терминале: “dkms add -m amneziawg -v 1.0.0”, “dkms build -m amneziawg -v 1.0.0”, “dkms install -m amneziawg -v 1.0.0”](https://notby.net/images/06/debian-console-dkms-add-build-install-m-amneziawg-v-1-0-0.webp)</figure>Модуль ядра amneziawg теперь будет автоматически собиратся при каждом обновлении ядра Linux.

Через встроенный скрипт он будет предварительно скачивать исходный код ядра Linux, а после сборки удалит скачанные и временные файлы.

### 2.3. Сборка и установка модуля ядра вручную

#### 2.3.1. Загрузка исходного кода ядра Linux

Для сборки модуля ядра AmneziaWG необходим исходный код ядра Linux установленной системы.

Загружаем исходный код ядра Linux.

```
```
apt install linux-source
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

**linux-source** — это мета-пакет который включает исходный код ядра Linux текущей системы.

Исходный код будет загружен в каталог **/usr/src/** в формате **tar.xz** архива.

Переходим в каталог **/usr/src/**

```
```
cd /usr/src/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Находим имя архива с исходным кодом ядра (*оно будет иметь имя в зависимости от версии ядра установленной системы*)

```
```
ls | grep linux-source
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Извлекаем содержимое архива (*в моем случае это linux-source-6.1.tar.xz*)

```
```
tar -xJf linux-source-6.1.tar.xz
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

#### 2.3.2. Сборка модуля ядра

Переходим в каталог клонированного репозитория **amneziawg-linux-kernel-module**

```
```
cd amneziawg-linux-kernel-module
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Переходим в каталог **src**

```
```
cd src
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем символьную ссылку на исходный код ядра Linux установленной системы

```
```plaintext
ln -s /usr/src/linux-source-<версия ядра> kernel
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Вместо **&lt;версия ядра&gt;** необходимо указать версию ядра Linux установленной системы.

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

```
```
ln -s /usr/src/linux-source-6.1 kernel
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Собираем модуль ядра **amneziawg**

```
```
make
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Дожидаемся окончания сборки, если все успешно будет выведено **true**.

#### 2.3.3. Установка модуля ядра

Устанавливаем модуль ядра **amneziawg**

```
```
make install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Загружаем модуль ядра **amneziawg**

```
```
modprobe amneziawg
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Проверяем что модуль **amneziawg** загружен

```
```
lsmod | grep amneziawg
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 3. Утилиты awg и awg-quick для управления AmneziaWG

Для управления собранным модулем ядра AmneziaWG необходимы утилиты с той же модификацией протокола WireGuard, что и модуль ядра.

Утилиты имеют имена **awg**, **awg-quick** и они по командам, способом управления аналогичны утилитам **wg**, **wg-quick** из WireGuard.

### 3.1. Загрузка исходного кода утилит AmneziaWG

Создаем для удобства каталог **git** в домашней директории пользователя и переходим в него

```
```
mkdir -p ~/git && cd ~/git
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Клонируем репозиторий **amneziawg-tools**

```
```
git clone https://github.com/amnezia-vpn/amneziawg-tools.git
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--3">![Репозиторий amneziawg-tools скопирован с github командой “git clone https://github.com/amnezia-vpn/amneziawg-tools.git” в консоли Debian, выведены сообщения процесса клонирования репозитория](https://notby.net/images/06/debian-console-git-clone-https-github-com-amnezia-vpn-amneziawg-tools-git.webp)</figure>### 3.2. Сборка утилит awg и awg-quick

Переходим в каталог клонированного репозитория **amneziawg-tools**

```
```
cd amneziawg-tools
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Переходим в каталог **src**

```
```
cd src
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Запускаем процесс сборки утилит **awg** и **awg-quick**

```
```
make
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--4">![В консоли Debian последовательно выполнены команды: “cd amneziawg-tools”, “cd src”, “make”. Показан процесс сборки утилиты из исходного кода.](https://notby.net/images/06/debian-console-cd-amneziawg-tools-cd-src-make.webp)</figure>Дожидаемся окончания сборки.

### 3.3. Установка утилит awg и awg-quick

Заходим под root-пользователем или выполняем команды через sudo

```
```
su -
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Устанавливаем утилиты **awg** и **awg-quick**

```
```
make install
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--5">![Утилиты awg и awg-quick успешно установлены при помощи команды “sudo make install” в терминале операционной системе Debian, выведен список установленных файлов и их пути](https://notby.net/images/06/debian-console-git-amneziawg-tools-src-sudo-make-install.webp)</figure>- в каталог **/usr/bin/** будут скопированы утилиты **awg** и **awg-quick**;
- в каталог **/usr/share/bash-completion/completions/** будут скопированы скрипты для bash-окружения;
- в каталог **/usr/lib/systemd/system/** будут скопированы файлы для работы AmneziaWG в качестве службы systemd.

## 4. Конфигурация AmneziaWG и перенос файлов WireGuard

В AmneziaWG каталог с конфигурационными файлами находится по пути **/etc/amnezia/amneziawg/** и утилита **awg-quick** будет искать там файлы для создания туннеля.

Если необходимо скопировать конфигурационные файлы WireGuard в AmneziaWG используем следующею команду

```
```
cp /etc/wireguard/*.conf /etc/amnezia/amneziawg/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Переходим в каталог конфигурации AmneziaWG

```
```
cd /etc/amnezia/amneziawg/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Создадим, например, файл конфигурации с именем **awg0-client.conf** или откроем любой из перенесенных файлов конфигураций

```
```
nano awg0-client.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Настройка, конфигурация и управление AmneziaWG происходит аналогично Wireguard. Можно использовать статью [Настройка VPN сервера WireGuard в Linux (Debian/Ubuntu)](https://notby.net/nastroyka-vpn-servera-wireguard-v-linux), только вместо команды **wg** использовать **awg**, a вместо **wg-quick** использовать **awg-quick**.

## 5. Удаление AmneziaWG

Если возникнет необходимость удалить AmneziaWG, нужно удалить модуль ядра и утилиты с их файлами.

Удаляем модуль ядра **amneziawg** через **DKMS**

```
```
dkms remove -m amneziawg -v 1.0.0
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Удаляем каталог **/usr/src/amneziawg-1.0.0/**

```
```
rm -rf /usr/src/amneziawg-1.0.0/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Утилиты **awg** и **awg-quick** устанавливались простым копированием, поэтому удаляем их с их файлами по списку

```
rm -v /usr/bin/awg /usr/share/man/man8/awg.8 /usr/share/bash-completion/completions/awg /usr/bin/awg-quick /usr/share/man/man8/awg-quick.8 /usr/share/bash-completion/completions/awg-quick /usr/lib/systemd/system/awg-quick.target /usr/lib/systemd/system/awg-quick@.service
```

# AmneziaWG FreeBSD 14

https://github.com/vgrebenschikov/amneziawg-tools

# FreeBSD port of amneziawg-tools

<div class="Layout-main" data-view-component="true" id="bkmrk-installation-downloa"><div data-target="react-partial.reactRoot"><div class="OverviewContent-module__Box--uNd1J"><div class="OverviewContent-module__Box_11--Tqhu2"><div class="OverviewRepoFiles-module__Box_1--xSt0T"><div class="OverviewRepoFiles-module__Box_2--yIjMp"><div class="Box-sc-g0xbh4-0 js-snippet-clipboard-copy-unpositioned DirectoryRichtextContent-module__SharedMarkdownContent--YORdJ" data-hpc="true"><article class="markdown-body entry-content container-lg">## Installation

Download and build port as:

```
# git clone https://github.com/vgrebenschikov/amneziawg-tools
# cd amneziawg-tools
# make install
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>It will install:

```
$ pkg list amneziawg-tools
/usr/local/bin/awg
/usr/local/bin/awg-quick
/usr/local/etc/rc.d/wireguard-amnezia
/usr/local/share/bash-completion/completions/awg
/usr/local/share/bash-completion/completions/awg-quick
/usr/local/share/licenses/amneziawg-tools-1.0.20241018_2/GPLv2
/usr/local/share/licenses/amneziawg-tools-1.0.20241018_2/LICENSE
/usr/local/share/licenses/amneziawg-tools-1.0.20241018_2/catalog.mk
/usr/local/share/man/man8/awg-quick.8.gz
/usr/local/share/man/man8/awg.8.gz
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>## Using Kernel AmneziaWG module

Install [net/wireguard-amnezia-kmod](https://github.com/vgrebenschikov/wireguard-amnezia-kmod-port)

Unload original if\_wg as and load updated from /boot/modules/if\_wg.ko

```
# kldunload if_wg
# kldload /boot/modules/if_wg.ko
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>To make it automatically load from /boot/modules - add to /boot/loader.conf:

```
if_wg_name="/boot/modules/if_wg.ko"
if_wg_load="YES"
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>## Configuration

Generally - same way as you will configure normal net/wireguard-tools:

```
# cd /usr/local/etc/wireguard
# cat > wg0.conf
[Interface]
PrivateKey = ...our.private.key.here...
ListenPort = 12345
Address = 192.168.1.1/24
Description = Test Wireguard

Jc = 7
Jmin = 150
Jmax = 1000
S1 = 117
S2 = 321
H1 = 2008066467
H2 = 2351746464
H3 = 3053333659
H4 = 1789444460

[Peer]
PublicKey = ...peer.public.key.here...
AllowedIPs = 192.168.1.2/32
^D
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>Then start:

```
# awg-quick up wg0
[#] ifconfig wg create name wg0 description Test Wireguard
[#] awg setconf wg0 /dev/stdin
[#] ifconfig wg0 inet 192.168.1.1/24 alias
[#] ifconfig wg0 mtu 1420
[#] ifconfig wg0 up
[#] route -q -n add -inet 192.168.11.0/24 -interface wg0
[+] Backgrounding route monitor

# awg show
interface: wg0
  public key: CI...
  private key: (hidden)
  listening port: 12345
  jc: 7
  jmin: 150
  jmax: 1000
  s1: 117
  s2: 321
  h1: 2008066467
  h2: 2351746464
  h3: 3053333659
  h4: 1789444460

peer: kue...
  allowed ips: 192.168.1.2/32
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>To setup autostart (wireguard-amnezia rc.d script will load module):

```
# sysrc wireguard_amnezia_enable=YES wireguard_amnezia_interfaces="wg0"
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>## Amnezia Wireguard config options

## Jc

Number of junk packets before handshake.

1–128 (recomended 3–10)

## Jmin

Minimum size of junk packets.

Jmin: &lt; Jmax (recomended ~ 50)

## Jmax

Maximum size of junk packets.

Jmax: ≤ 1280 (recomended ~ 1000)

## S1

Size of handshake initiation packet prepend junk. Should be the same on both ends.

0–1280 (recomended 15–150), S1 != S2

## S2

Size of handshake response packet prepend junk. Should be the same on both ends.

0–1280 (recomended 15–150), S1 != S2

## H1-H4

Custom identifiers for initiation/response/cookie/data packets. Should be the same on both ends.

The unique value in range of 5 - 4,294,967,295 (0x5 - 0xFFFFFFFF), H1 != H2 != H3 != H4

## Additional config options

### Description

```
[Interface]
...
Description = Some Text

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>Will setup interface description visible in ifconfig and SNMP.

### UserLand

Enforce to use amnezia-go instead of kernel driver, you can use port [net/amnezia-wireguard-go](https://github.com/vgrebenschikov/amnezia-wireguard-go) to install it.

```
[Interface]
...
UserLand = true
...

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### Routes

List of routes for the peer to be installed into FIB - that option provides a way to have AllowedIPs list wider then routes installed. Empty list is allowed.

That is useful if routing protocol will work over the link. But remember that internal wireguard routing will happen according to AllowedIPs anyway.

```
...

[Peer]
PublicKey = ...peer.public.key.here...
AllowedIPs = 0.0.0.0/0
Routes = 192.168.1.2/32

```

</article></div></div></div></div></div></div></div>

# Как просматривать видео с камеры Tapo на ПК/NAS/NVR при помощи протоколов RTSP/ONVIF

<div class="suit-for" id="bkmrk-"></div>Камеры Tapo имеют поддержку протоколов ONVIF и RTSP, позволяя им работать с видеорегистраторами и NAS устройствами сторонних производителей, на которых так же реализована поддержка протоколов RTSP/ONVIF. Ниже представлен представлены шаги настройки камеры для просмотра видео с камеры Tapo при помощи сторонних приложений, таких как VLC Player и iSpy.

Примечания:

1\. Имя пользователя и пароль, необходимые для использования RTSP/ONVIF это ни что иное, как данные учетной записи камеры, которую Вы можете создать в приложении Tapo. Если Вы не создавали учетную запись, то можете воспользоваться инструкциями, представленными в первом шаге данной инструкции;

2\. IP-адрес присваивается камере автоматически Вашим Wi-Fi роутером, к которому Вы её подключали. Узнать его можно в списке клиентов DHCP Вашего роутера или в приложении Tapo (для этого необходимо попасть в настройки самой камеры и перейти в раздел “Информация об устройстве”, где будет указан IP-адрес, полученный камерой).

3\. Если Вы хотите просматривать RTSP-поток камеры Tapo удалённо, Вам будет необходимо открыть порт 554 на Вашем роутере, то есть настроить перенаправление (“проброс”) порта.

4\. Вы можете использовать протокол ONVIF с использованием имени пользователя и пароля для управления Вашей камерой Tapo. Пример настройки ONVIF представлен во втором шаге данной инструкции.

5\. Для камеры Tapo C310, разрешение потока stream1 соответствует качеству, заданному в настройках камеры.  
Если Вы хотите просматривать видео с разрешением 3МП при использовании RTSP, необходимо изменить качество видео на “Лучшее качество” в мобильном приложении Tapo и использовать следующий адрес: rtsp://\[IP адрес\]/stream1

6\. Если в камере используется карта памяти microSD и подключена подписка Tapo Care, настроить RTSP не удастся. Вам будет необходимо отключить карту памяти microSD или подписку Tapo Care для получения доступа к RTSP-потоку камеры.

7\. Если Вы обнаружили, что при просмотре видео с камеры через ONVIF/RTSP отсутствует звук, пожалуйста, попробуйте изменить чувствительность микрофона камеры в мобильном приложении.

8\. Перед началом настройки, убедитесь, что устройство, с которого планируется осуществлять просмотр видео с камеры Tapo, находится в той же локальной сети, что и сама камера или что Ваш роутер доступен в сети Интернет (требуется наличие “белого” (публичного) IP-адреса, предоставляемого интернет-провайдером Вашему роутеру. Более подробная информация представлена в конце статьи).

**Шаг 1. Создайте учетную запись камеры в приложении Tapo:**

1\. Во вкладке **“Дом”** нажмите на Вашу камеру для входа в её интерфейс (Вы также можете перейти во вкладку **“Камеры”** и нажать на кнопку **“Управление”** на необходимой камере для входа в её интерфейс).

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/1qpimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/1qpimage.png)

2\. В интерфейсе камеры перейдите в её настройки, нажав на соответствующую иконку справа сверху.

![](https://static.tp-link.com/upload/faq/image-20240717180347-2_20240717150347j.jpeg)

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/ah9image.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/ah9image.png)

3\. Перейдите в раздел **“Дополнительные настройки” &gt; “Учетная запись камеры”** для создания учетной записи (имя пользователя/пароль). С её помощью осуществляется управление камерой при использовании сторонних сервисов.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/IObimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/IObimage.png)

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/O7Kimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/O7Kimage.png)

Здесь Вы увидите информацию о данной функции (**“Об учетной записи камеры”** и **“Прежде чем начать”**). Пожалуйста, ознакомьтесь с информацией, после чего нажмите **“Понятно, согласен”**. После этого Вы сможете создать учетную запись вашей камеры, заполнив соответствующие поля.

Примечание: Имя пользователя и пароль должны содержать от 6 до 32 символов.

![](https://static.tp-link.com/upload/faq/image-20240717180347-5_20240717150347z.jpeg)

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/KT1image.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/KT1image.png)

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/Sgaimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/Sgaimage.png)

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/uk8image.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/uk8image.png)

![](https://static.tp-link.com/upload/faq/image-20240717180347-6_20240717150348x.jpeg)![](https://static.tp-link.com/upload/faq/image-20240717180347-7_20240717150347p.jpeg)

**Шаг 2: Просмотр камеры через iSpy (пример с использованием ONVIF)**

1\. Запустите **iSpy** на Вашем ПК.

2\. Нажмите **“Add”** в левом верхнем углу экрана и выберите **“ONVIF Camera”**.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/riNimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/riNimage.png)

3\. Введите **имя пользователя (Username)** и **пароль (Password)**, которые Вы указывали при создании учетной записи камеры, выберите **адрес сети (Network Address)** и нажмите **“Next”**. Вы можете также изменить дополнительные параметры при необходимости.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/uFzimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/uFzimage.png)

4\. Выберите разрешение видео и нажмите **“OK”**.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/Ixpimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/Ixpimage.png)

5\. При необходимости настройте параметры камеры, включая микрофон, голосовую связь, обнаружение движения, оповещения, запись, изображения, расписания и хранение. Данные параметры можно будет изменить позднее. Нажмите **“Finish”** для завершения добавления камеры в iSpy.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/aXBimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/aXBimage.png)

6\. После добавления камеры Tapo в iSpy Вы сможете просматривать и управлять камерой. Вам доступны просмотр в реальном времени, настройки обнаружения движения, проверка записи при обнаружении движения, установка записи по расписанию, видеозапись и многое другое.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/NQmimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/NQmimage.png)

**Шаг 3: просмотр камеры Tapo через VLC Player (пример с использованием RTSP)**

1\. Запустите **VLC Media Player** на Вашем ПК.

2\. Во вкладке **“Медиа”** выберите **“Открыть URL…”**

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/mjlimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/mjlimage.png)

3\. Введите **URL-адрес RTSP-потока** камеры Tapo.

[![image.png](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/scaled-1680-/bjkimage.png)](https://wiki2.k-11.ru/uploads/images/gallery/2025-07/bjkimage.png)

4\. Нажмите **“Воспроизвести”**.

**URL-адреса RTSP-потока камер Tapo имеют следующий вид:**

— **Поток в высоком качестве:** rtsp://\[IP-адрес камеры\]/stream1

— **Поток в низком качестве:** rtsp://\[IP-адрес камеры\]/stream2

В некоторых случаях также требуется указать порт камеры. По умолчанию, для RTSP используется порт 554 и в таком случае URL-адрес будет иметь следующий вид:

— **Поток в высоком качестве:** rtsp://\[IP-адрес камеры\]:554/stream1

— **Поток в низком качестве:** rtsp://\[IP-адрес камеры\]:554/stream2

Если Вы хотите предоставить доступ к трансляции с Вашей камеры другому лицу, которое находится во внешней сети, изучите информацию, приведенную ниже.

Чтобы трансляцию можно было просматривать из внешней сети, ссылка на нее должна содержать белый (“публичный”) IP-адрес. Это услуга, которую необходимо подключить у Вашего провайдера. Обычно она оказывается за дополнительную абонентскую плату.

Проверить, предоставлен ли Вам белый IP-адрес, достаточно легко. Нужно зайти в настройки роутера и посмотреть, какой IP-адрес приходит на интерфейс WAN. Если Вы используете роутер марки TP-Link, то эту информацию можно увидеть на странице **“Дополнительные настройки” – “Сеть” – “Интернет”** или **“Сеть” – “WAN”** (в зависимости от типа интерфейса Вашего роутера). Если Вы используете роутер другой марки, пожалуйста, свяжитесь с поддержкой производителя Вашего роутера, чтобы узнать эту информацию.

Адрес, который Вы увидите там, НЕ должен принадлежать ни одному из следующих диапазонов:

<div class="content" id="bkmrk-10.0.0.0%C2%A0%E2%80%94-10.255.25">- **10.0.0.0 — 10.255.255.255** (маска подсети 255.0.0.0 или /8);
- **100.64.0.0 — 100.127.255.255** (маска подсети 255.192.0.0 или /10);
- **172.16.0.0 — 172.31.255.255** (маска подсети: 255.240.0.0 или /12);
- **192.168.0.0 — 192.168.255.255** (маска подсети: 255.255.0.0 или /16).

</div>Также нужно настроить проброс порта на этом роутере. Чтобы узнать, как это сделать, обратитесь к этой статье: [https://www.tp-link.com/ru/support/faq/1379/](https://www.tp-link.com/ru/support/faq/1379/)

Внимание: Обычно для камеры выполняется проброс порта 554 для потока RTSP. Для потока ONVIF нужно пробросить порт 2020.

Далее, в ссылке на RTSP-поток должен быть указан адрес на WAN-порту роутера, который мы нашли ранее, и указанный при пробросе внешний порт в формате: <a name="_Hlk172130538" role="button" tabindex="0"></a>rtsp://\[IP-адрес\]:\[Внешний порт\]/stream1 или rtsp://\[IP-адрес\]:\[Внешний порт\]/stream2

К сожалению, просмотр трансляции не будет доступен через браузер, однако для этой цели можно использовать программу iSpy или VLC Player.

# Получение сертификата Let's Encrypt для HTTPS при помощи Certbot в FreeBSD 14.1

Сайт по незащищенному протоколу HTTP ? Любой сайт должен работать через HTTPS, а для этого нужен сертификат которому доверяют веб-браузеры. Существует сервис Let's Encrypt который выдает бесплатно сертификаты для сайта сроком на 3 месяца, а после можно бесплатно их перевыпустить. Для управления и автоматического обновления сертификатов существует утилита Certbot. В статье будет рассмотрена работа Certbot в FreeBSD и настройка nginx для работы с HTTPS протоколом.

<nav class="toc" id="bkmrk-%D0%9E%D0%B3%D0%BB%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%3A-1"><span class="text-big">Оглавление статьи:</span>1. [1. Установка Certbot](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#1)
2. [2. Создание аккаунта Let's Encrypt](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#2)
3. [3. Получение сертификата для сайта](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#3)
4. [4. Настройка nginx для работы с HTTPS](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#4)
5. [5. Проверка HTTPS и перенаправление с HTTP](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#5)
6. [6. Проверка обновлений сертификатов](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#6)
7. [7. Автоматическое обновление сертификатов](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#7)
8. [8. Изменение email адреса аккаунта](https://notby.net/poluchenie-sertifikata-let-s-encrypt-dlya-https-pri-pomoshchi-certbot-v-freebsd#8)

</nav>## 1. Установка Certbot

Устанавливаем через пакеты

```
```
pkg install py311-certbot
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Или устанавливаем из портов

```
```
cd /usr/ports/security/py-certbot/ && make install clean
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

После установки было выведено сообщение: что можно установить плагины для автоматической настройки Apache или Nginx, как включить автоматическое обновление сертификатов.

<figure class="image" id="bkmrk-">![FreeBSD, certbot успешно установлен, выедено сообщение как включить автоматическое обновление сертификатов и что есть плагины для Apache и Nginx](https://notby.net/images/03/freebsd-certbot-messages-after-installation.webp)</figure>В статье будет показан процесс ручной настройки и добавление сертификатов в веб-сервер nginx и включение автоматического обновления сертификатов Let's Encrypt.

## 2. Создание аккаунта Let's Encrypt

Создаем аккаунт командой:

```
```
certbot register
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Указываем свой email адрес

```
```plaintext
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): tommywirser@notby.net
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Соглашаемся с договором по использованию Let's Encrypt

```
```plaintext
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Отказываемся от передачи своего email адреса и получения новостей и рекламы

```
```plaintext
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Аккаунт успешно создан.

## 3. Получение сертификата для сайта

Для получения сертификата используем команду:

```
```
certbot certonly -d notby.net
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где **notby.net** — доменное имя сайта для которого необходимо выпустить сертификат Let's Encrypt.

Будет преложено два варианта как проверить собственность доменного имени сайта:

1. запустить встроенный веб-сервер certbot (не походит, так как уже есть рабочий веб-сервер);
2. использовать рабочий веб-сервер, например nginx.

**Выбираем 2 вариант**

Далее необходимо указать путь до каталога сайта. В каталоге сайте будет создан каталог .well-known/acme-challenge/ с файлами для проверки домена.

**Указываем каталог сайта**

<figure class="image" id="bkmrk--1">![Получение сертификата Let's Encrypt для домена notby.net командой “certbot certonly -d notby.net” в консоли FreeBSD](https://notby.net/images/03/freebsd-certbot-certonly-d-notby-net.webp)</figure>Нажимаем <kbd>Enter</kbd> и дожидаемся завершение процесса получения сертификата.

<figure class="image" id="bkmrk--2">![Консоль FreeBSD, сертификат Let's Encrypt успешно получен для домена notby.net, путь до сертификата и ключа](https://notby.net/images/03/freebsd-certbot-certonly-d-notby-net-successfully-received-certificate.webp)</figure>Сертификат Let's Encrypt успешно выдан сроком на 3 месяца.

Аналогично происходит получение сертификатов для других сайтов, если это необходимо. Можно получить сертификаты для неограненного количества сайтов.

Если во время получения сертификата произошла ошибка, возможны следующие причины:

- Для утилиты certbot недостаточно прав на создание каталога проверки домена внутри каталога сайта;
- Невозможно получить доступ по URL адресу http://&lt;домен&gt;/.well-known/acme-challenge/.

Проверяем что каталог сайта имеет права как минимум 5 (r-x) для пользователя веб-сервера или любых пользователей.

```
```
ls -lh /usr/local/www/
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

```
```shell
drwxr-x---  2 www www  1.0K Feb 21 12:33 notby.net
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем в конфигурацию nginx в раздел настроек сайта следующие строки:

```
```nginx
location /.well-known {
	root /usr/local/www/notby.net/; # Каталог сайта.
}
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 4. Настройка nginx для работы с HTTPS

Настраиваем nginx на обслуживания сайта через HTTPS по 443 порту с указанием путей сертификатов Let's Encrypt и перенаправление всего трафика с HTTP на HTTPS.

Открываем **конфигурационный файл настроек для сайта** или **nginx.conf**, вносим измерения в раздел настроек сайта

```
```nginx
# Вместо домена notby.net указывай свой домен сайта.
# Блок server для домена notby.net по 80 порту (HTTP).
server {
	listen 80; # Порт сервера.
	server_name notby.net; # Домен сайта.
	
	# Настройка location для получения Let's Encrypt сертификата через HTTP, можно перенести в раздел HTTPS.
	# Каталог .well-known будет создан certbot'ом на время получения сертификата Let's Encrypt.
	location /.well-known {
		root /usr/local/www/notby.net/;
	}
	
	#Перенаправление всего трафика с http на https.
	location / {
		return 301 https://$host$request_uri;
	}
}

# Блок server для домена notby.net по 443 порту (HTTPS).
server {
	listen 443 ssl; # 443 порт, поддержка SSL.
	http2 on; # Использовать HTTP/2.
	server_name notby.net; # Домен сайта.

	# Пути к списку сертификатов, на моменте выдачи сертификата они были указаны.
	ssl_certificate /usr/local/etc/letsencrypt/live/notby.net/fullchain.pem;
	ssl_certificate_key  /usr/local/etc/letsencrypt/live/notby.net/privkey.pem;
	# Сертификат для параметра ssl_stapling
	ssl_trusted_certificate /usr/local/etc/letsencrypt/live/notby.net/chain.pem;

	ssl_protocols TLSv1.3; # Разрешенные протоколы (только TLS 1.3).
	ssl_prefer_server_ciphers off; # Использовать клиентские шифры.

	# OCSP stapling, для ssl_stapling обязательный ssl_trusted_certificate параметр.
	ssl_stapling on;
	ssl_stapling_verify on;

	# Настройки location оставляем как было раньше или меняем если что-то нужно поменять. -:)

	location / {
		root	/usr/local/www/notby.net/; # Каталог сайта.
		index	index.html index.php; # Файлы в качестве индекса.
	}

	location ~ \.php$ {
		fastcgi_pass	unix:/var/run/php-fpm.sock;
		fastcgi_param	SCRIPT_FILENAME /usr/local/www/notby.net/$fastcgi_script_name;
		include			fastcgi_params;
	}
}
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Сохраняем файл и перезапускаем веб-сервер nginx

```
```
service nginx restart
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

## 5. Проверка HTTPS и перенаправление с HTTP

Открываем в веб-браузере свой сайт по протоколу **http**://&lt;адрес сайта&gt;/, должно произойти автоматическое перенаправление на **https**://&lt;адрес сайта&gt;/

Нажимаем значок рядом с адресом сайта и видим что сайт работает по защищенному соединению с сертификатом Let's Encrypt.

<figure class="image" id="bkmrk--3">![Кусок браузера Firefox, проверка наличия сертификата сайта notby.net, соединение защищенное с Let's Encrypt сертификатом](https://notby.net/images/03/veb-brauzer-firefox-proverka-nalichiya-sertifikata-sayta.webp)</figure>Теперь все пользователя будет автоматически перенаправлятся на HTTPS протокол, даже не заметив каких-то измерений.

Поисковые системы также со временем изменят протокол сайта или можно зайти в панель управления сайтами в поисковой системе и указать что сайт переехал на HTTPS.

## 6. Проверка обновлений сертификатов

После настройки веб-сервера запускаем проверку получения нового сертификата

```
```
certbot renew --dry-run
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Параметр **--dry-run** указывает что будет происходить симуляция получения нового сертификата.

<figure class="image" id="bkmrk--4">![Симуляция получения нового сертификата командой “certbot renew --dry-run”, тестовое получение сертификата для notby.net успешно завершено](https://notby.net/images/03/freebsd-certbot-renew-dry-run.webp)</figure>Тестовое получение сертификата успешно пройдено.

## 7. Автоматическое обновление сертификатов

Утилиту Certbot необходимо добавить в файл **/etc/periodic.conf** (периодическое выполнение заданий), чтобы она автоматически перевыпустила сертификаты сайтов, срок действия которых заканчивается.

Открываем в текстовом редакторе файл **/etc/periodic.conf** или создаем его

```
```
nano /etc/periodic.conf
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

Добавляем строку

```
```plaintext
weekly_certbot_enable="YES"
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

<figure class="image" id="bkmrk--5">![Открыт файл /etc/periodic.conf в текстовом редакторе nano, добавлена строка weekly_certbot_enable="YES"](https://notby.net/images/03/freebsd-nano-etc-periodic-conf-add-weekly-certbot-enable-yes.webp)</figure>Сохраняем файл. Теперь раз в неделю будет происходить проверка сертификатов сайтов и если сертификату остается меньше двух недель, он будет обновлен автоматически.

## 8. Изменение email адреса аккаунта

Если в дальнейшим потребуется изменить email адрес аккаунта Let's Encrypt, используем команду:

```
```
certbot update_account --email new@email.com
```<button class="copy" title="Скопировать в буфер обмена" type="button"></button>
```

где **new@email.com** — новый email адрес.

Будет предложено подписатся на новости и немного рекламы, отвечаем **N** если неинтересно.

<figure class="image" id="bkmrk--6">![Обновление email адреса аккаунта Let's Encrypt командой “certbot update_account --email new@email.com” в консоли FreeBSD, email успешно обновлен](https://notby.net/images/03/freebsd-certbot-update-account-email-new-email-com.webp)</figure>Email адрес успешно обновлен.

# windows 10 - vpn server штатными средствами.



# Zapret Настройка BSD-подобных систем

- [Поддерживаемые версии](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8)
- [Особенности BSD систем](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BE%D1%81%D0%BE%D0%B1%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8-bsd-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC)
    - [Отсутствие nfqueue](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BE%D1%82%D1%81%D1%83%D1%82%D1%81%D1%82%D0%B2%D0%B8%D0%B5-nfqueue)
    - [Типы Firewall](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D1%82%D0%B8%D0%BF%D1%8B-firewall)
    - [Сборка](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0)
    - [Divert сокеты](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#divert-%D1%81%D0%BE%D0%BA%D0%B5%D1%82%D1%8B)
    - [Lookup Tables](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#lookup-tables)
    - [Загрузка ip таблиц из файла](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-ip-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86-%D0%B8%D0%B7-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0)
    - [Отсутствие splice](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BE%D1%82%D1%81%D1%83%D1%82%D1%81%D1%82%D0%B2%D0%B8%D0%B5-splice)
    - [mdig и ip2net](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#mdig-%D0%B8-ip2net)
- [FreeBSD](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#freebsd)
    - [Подгрузка ipdivert](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D0%BE%D0%B4%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-ipdivert)
    - [Авто-восстановление правил ipfw и работа в фоне](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B0%D0%B2%D1%82%D0%BE-%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB-ipfw-%D0%B8-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D0%B2-%D1%84%D0%BE%D0%BD%D0%B5)
    - [tpws в прозрачном режиме](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#tpws-%D0%B2-%D0%BF%D1%80%D0%BE%D0%B7%D1%80%D0%B0%D1%87%D0%BD%D0%BE%D0%BC-%D1%80%D0%B5%D0%B6%D0%B8%D0%BC%D0%B5)
    - [Запуск dvtws](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-dvtws)
    - [PF в FreeBSD](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#pf-%D0%B2-freebsd)
    - [pfsense](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#pfsense)
- [OpenBSD](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#openbsd)
    - [tpws bind на ipv4](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#tpws-bind-%D0%BD%D0%B0-ipv4)
    - [tpws для проходящего трафика (старые системы)](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#tpws-%D0%B4%D0%BB%D1%8F-%D0%BF%D1%80%D0%BE%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-%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F-%D1%81%D1%85%D0%B5%D0%BC%D0%B0-%D0%BD%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-%D0%B2-%D0%BD%D0%BE%D0%B2%D1%8B%D1%85-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F%D1%85))
    - [tpws для проходящего трафика (новые системы)](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#tpws-%D0%B4%D0%BB%D1%8F-%D0%BF%D1%80%D0%BE%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-%D0%BD%D0%BE%D0%B2%D1%8B%D0%B5-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B))
    - [Запуск dvtws](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-dvtws)
    - [Проблемы с badsum](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D1%8B-%D1%81-badsum)
    - [Особенность отправки fake пакетов](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BE%D1%81%D0%BE%D0%B1%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C-%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-fake-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2)
    - [Перезагрузка PF таблиц](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D0%B5%D1%80%D0%B5%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-pf-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86)
- [MacOS](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#macos)
    - [Введение](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B2%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5)
    - [dvtws бесполезен](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#dvtws-%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%B5%D0%BD)
    - [tpws](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#tpws)
    - [Проблема link-local адреса](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0-link-local-%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D0%B0)
    - [Сборка](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0)
    - [Простая установка](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B0%D1%8F-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)
    - [Вариант Custom](https://github.com/bol-van/zapret/blob/master/docs/bsd.md#%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-custom)

## Поддерживаемые версии

**FreeBSD** 11.x+ , **OpenBSD** 6.x+, частично **MacOS Sierra** +

<svg aria-hidden="true" class="octicon octicon-stop mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Caution

На более старых может собираться, может не собираться, может работать или не работать. На **FreeBSD** 10 собирается и работает `dvtws`. С `tpws` есть проблемы из-за слишком старой версии компилятора clang. Вероятно, будет работать, если обновить компилятор. Возможна прикрутка к последним версиям pfsense без веб интерфейса в ручном режиме через консоль.

## Особенности BSD систем

### Отсутствие nfqueue

В **BSD** нет `nfqueue`. Похожий механизм - divert sockets. Из каталога [`nfq/`](https://github.com/bol-van/zapret/blob/master/nfq) под **BSD** собирается `dvtws` вместо `nfqws`. Он разделяет с `nfqws` большую часть кода и почти совпадает по параметрам командной строки.

### Типы Firewall

**FreeBSD** содержит 3 фаервола : **IPFilter**, **ipfw** и **Packet Filter (PF в дальнейшем)**. **OpenBSD** содержит только **PF**.

### Сборка

Под **FreeBSD** `tpws` и `dvtws` собираются через `make`.

Под **OpenBSD**:

```
make bsd
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk-"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>Под **MacOS**:

```
make mac
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--1"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>**FreeBSD** make распознает BSDmakefile, **OpenBSD** и **MacOS** - нет. Поэтому там используется отдельный target в Makefile. Сборка всех исходников:

```
make -C /opt/zapret
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--2"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### Divert сокеты

Divert сокет это внутренний тип сокета ядра **BSD**. Он не привязывается ни к какому сетевому адресу, не участвует в обмене данными через сеть и идентифицируется по номеру порта `1..65535`. Аналогия с номером очереди `NFQUEUE`. На divert сокеты заворачивается трафик посредством правил ipfw или PF. Если в фаерволе есть правило divert, но на divert порту никто не слушает, то пакеты дропаются. Это поведение аналогично правилам `NFQUEUE` без параметра `--queue-bypass`. На **FreeBSD** divert сокеты могут быть только ipv4, хотя на них принимаются и ipv4, и ipv6 фреймы. На **OpenBSD** divert сокеты создаются отдельно для ipv4 и ipv6 и работают только с одной версией `ip` каждый. На **MacOS** похоже, что divert сокеты из ядра вырезаны. См подробнее раздел про **MacOS**. Отсылка в divert сокет работает аналогично отсылке через raw socket на linux. Передается полностью IP фрейм, начиная с ip загловка. Эти особенности учитываются в `dvtws`.

### Lookup Tables

Скрипты [`ipset/*.sh`](https://github.com/bol-van/zapret/blob/master/ipset) при наличии ipfw работают с ipfw lookup tables. Это прямой аналог ipset. lookup tables не разделены на v4 и v6. Они могут содержать v4 и v6 адреса и подсети одновременно. Если ipfw отсутствует, то действие зависит от переменной `LISTS_RELOAD` в config. Если она задана, то выполняется команда из `LISTS_RELOAD`. В противном случае не делается ничего. Если `LISTS_RELOAD=-`, то заполнение таблиц отключается даже при наличии ipfw.

### Загрузка ip таблиц из файла

PF может загружать ip таблицы из файла. Чтобы использовать эту возможность следует отключить сжатие gzip для листов через параметр файла config: `GZIP_LISTS=0`.

### Отсутствие splice

**BSD** не содержит системного вызова splice. `tpws` работает через переброску данных в user mode в оба конца. Это медленнее, но не критически. Управление асинхронными сокетами в `tpws` основано на linux-specific механизме epoll. В **BSD** для его эмуляции используется epoll-shim - прослойка для эмуляции epoll на базе kqueue.

### mdig и ip2net

mdig и ip2net полностью работоспособны в **BSD**. В них нет ничего системо-зависимого.

## FreeBSD

### Подгрузка ipdivert

Divert сокеты требуют специального модуля ядра - `ipdivert`.

- Поместите следующие строки в `/boot/loader.conf` (создать, если отсутствует):

```
ipdivert_load="YES"
net.inet.ip.fw.default_to_accept=1

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--3"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>`/etc/rc.conf`:

```
firewall_enable="YES"
firewall_script="/etc/rc.firewall.my"

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--4"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>`/etc/rc.firewall.my`:

```
$ ipfw -q -f flush
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--5"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### Авто-восстановление правил ipfw и работа в фоне

В `/etc/rc.firewall.my` можно дописывать правила ipfw, чтобы они восстанавливались после перезагрузки. Оттуда же можно запускать и демоны zapret, добавив в параметры `--daemon`. Например так:

```
$ pkill ^dvtws$
$ /opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--6"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>Для перезапуска фаервола и демонов достаточно будет сделать:

```
$ /etc/rc.d/ipfw restart
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--7"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### tpws в прозрачном режиме

Краткая инструкция по запуску `tpws` в прозрачном режиме.

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Предполагается, что интерфейс LAN называется `em1`, WAN - `em0`.

#### Весь трафик

```
$ ipfw delete 100
$ ipfw add 100 fwd 127.0.0.1,988 tcp from me to any 80,443 proto ip4 xmit em0 not uid daemon
$ ipfw add 100 fwd ::1,988 tcp from me to any 80,443 proto ip6 xmit em0 not uid daemon
$ ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
$ ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
$ /opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--8"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>#### Трафик только на таблицу zapret, за исключением таблицы nozapret

```
$ ipfw delete 100
$ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
$ ipfw add 100 fwd 127.0.0.1,988 tcp from me to table\(zapret\) 80,443 proto ip4 xmit em0 not uid daemon
$ ipfw add 100 fwd ::1,988 tcp from me to table\(zapret\) 80,443 proto ip6 xmit em0 not uid daemon
$ ipfw add 100 allow tcp from any to table\(nozapret\) 80,443 recv em1
$ ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
$ ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
$ /opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--9"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Таблицы zapret, nozapret, ipban создаются скриптами из ipset по аналогии с Linux. Обновление скриптов можно забить в cron под root:

```
$ crontab -e
```

<div class="markdown-alert markdown-alert-note" dir="auto" id="bkmrk--10"><div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><div class="snippet-clipboard-content notranslate position-relative overflow-auto">  
</div></div>```
<...>
0 12 */2 * * /opt/zapret/ipset/get_config.sh

```

<div class="markdown-alert markdown-alert-note" dir="auto" id="bkmrk--11"><div class="snippet-clipboard-content notranslate position-relative overflow-auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div></div><svg aria-hidden="true" class="octicon octicon-stop mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Caution

При использовании ipfw `tpws` не требует повышенных привилегий для реализации прозрачного режима. Однако, без рута невозможен bind на порты `< 1024` и смена UID/GID. Без смены UID будет рекурсия, поэтому правила ipfw нужно создавать с учетом UID, под которым работает `tpws`. Переадресация на порты `>= 1024` может создать угрозу перехвата трафика непривилегированным процессом, если вдруг `tpws` не запущен.

### Запуск dvtws

#### Весь трафик

```
$ ipfw delete 100
$ ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
# required for autottl mode only
$ ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted recv em0
$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--12"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>#### Трафик только на таблицу zapret, за исключением таблицы nozapret

```
$ ipfw delete 100
$ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
$ ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
# required for autottl mode only
$ ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--13"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### PF в FreeBSD

Настройка аналогична **OpenBSD**, но есть важные нюансы.

- В **FreeBSD** поддержка PF в `tpws` отключена по умолчанию. Чтобы ее включить, нужно использовать параметр `--enable-pf`.
- Нельзя сделать ipv6 rdr на `::1`. Нужно делать на link-local адрес входящего интерфейса. Смотрите через `ifconfig` адрес `fe80:...` и добавляете в правило.
- Синтаксис `pf.conf` немного отличается. Более новая версия PF.
- Лимит на количество элементов таблиц задается так:
    
    ```
    $ sysctl net.pf.request_maxcount=2000000
    ```
    
    <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
    </div></div>
- Сломан divert-to. Он работает, но не работает механизм предотвращения зацикливаний. Кто-то уже написал патч, но в `14-RELEASE` проблема все еще есть. Следовательно, на данный момент работа `dvtws` через PF невозможна.
    
    `/etc/pf.conf`:
    
    ```
    rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::31c:29ff:dee2:1c4d port 988
    rdr pass on em1 inet  proto tcp to port {80,443} -> 127.0.0.1 port 988
    
    ```
    
    <div class="snippet-clipboard-content notranslate position-relative overflow-auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
    </div></div>```
    $ /opt/zapret/tpws/tpws --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force
    ```
    
    <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
    </div></div>

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

В PF не выходит делать rdr-to с той же системы, где работает proxy. Вариант с route-to не сохраняет мета информацию. Адрес назначения теряется. Поэтому этот вариант годится для squid, берущего адрес из протокола прикладного уровня, но не годится для tpws, полагающегося на метаданные ОС. Поддержка rdr-to реализована через `/dev/pf`, поэтому прозрачный режим **требует root**.

### pfsense

#### Описание

pfsense основан на **FreeBSD** и использует фаервол PF, имеющий проблемы с divert. К счастью, модули ipfw и ipdivert присутствуют в поставке последних версий pfsense. Их можно подгрузить через `kldload`.

В некоторых более старых версиях pfsense требуется изменить порядок фаерволов через `sysctl`, сделав ipfw первым. В более новых эти параметры `sysctl` отсутствуют, но система работает как надо и без них. В некоторых случаях фаервол PF может ограничивать возможности `dvtws`, в частности в области фрагментации ip.

Присутствуют по умолчанию правила scrub для реассемблинга фрагментов.

Бинарики из [`binaries/freebsd-x64`](https://github.com/bol-van/zapret/blob/master/binaries/freebsd-x64) собраны под **FreeBSD 11**. Они должны работать и на последующих версиях **FreeBSD**, включая pfsense. Можно пользоваться `install_bin.sh`.

#### Автозапуск

Пример скрипта автозапуска лежит в [`init.d/pfsense`](https://github.com/bol-van/zapret/blob/master/init.d/pfsense). Его следует поместить в `/usr/local/etc/rc.d` и отредактировать на предмет правил ipfw и запуска демонов. Есть встроенный редактор `edit` как более приемлемая альтернатива `vi`.

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Поскольку `git` отсутствует, копировать файлы удобнее всего через `ssh`. `curl` присутствует по умолчанию. Можно скопировать zip с файлами zapret и распаковать в `/opt`, как это делается на других системах. Тогда `dvtws` нужно запускать как `/opt/zapret/nfq/dvtws`. Либо скопировать только `dvtws` в `/usr/local/sbin`. Как вам больше нравится.

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Скрипты ipset работают, крон есть. Можно сделать автообновление листов.

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Если вас напрягает бедность имеющегося репозитория, можно включить репозиторий от **FreeBSD**, который по умолчанию выключен.

Поменяйте `no` на `yes` в `/usr/local/etc/pkg/repos/FreeBSD.conf`

Можно установить весь привычный софт, включая `git`, чтобы напрямую скачивать zapret с github.

`/usr/local/etc/rc.d/zapret.sh` (chmod `755`):

```
#!/bin/sh

kldload ipfw
kldload ipdivert

# for older pfsense versions. newer do not have these sysctls
sysctl net.inet.ip.pfil.outbound=ipfw,pf
sysctl net.inet.ip.pfil.inbound=ipfw,pf
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf

ipfw delete 100
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
pkill ^dvtws$
dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2

# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
pfctl -d ; pfctl -e
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--14"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>#### Проблемы tpws

Что касается `tpws`, то видимо имеется некоторый конфликт двух фаерволов, и правила fwd в ipfw не работают. Работает перенаправление средствами PF как описано в разделе по **FreeBSD**. В PF можно изменять правила только целыми блоками - якорями (anchors). Нельзя просто так добавить или удалить что-то. Но чтобы какой-то anchor был обработан, на него должна быть ссылка из основного набора правил. Его трогать нельзя, иначе порушится весь фаервол. Поэтому придется править код скриптов pfsense.

1. Поправьте `/etc/inc/filter.inc` следующим образом:

```
	<...>
	/* MOD */
	$natrules .= "# ZAPRET redirection\n";
	$natrules .= "rdr-anchor \"zapret\"\n";

	$natrules .= "# TFTP proxy\n";
	$natrules .= "rdr-anchor \"tftp-proxy/*\"\n";
	<...>

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--15"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>2. Напишите файл с содержимым anchor-а (например, `/etc/zapret.anchor`):

```
rdr pass on em1 inet  proto tcp to port {80,443} -> 127.0.0.1 port 988
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 port 988

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--16"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>`fe80::20c:29ff:5ae3:4821` замените на ваш link local адрес LAN интерфейса, либо уберите строчку, если ipv6 не нужен.

3. Добавьте в автозапуск `/usr/local/etc/rc.d/zapret.sh`:

```
$ pfctl -a zapret -f /etc/zapret.anchor
$ pkill ^tpws$
$ tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--17"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>4. После перезагрузки проверьте, что правила создались:

```
$ pfctl -s nat
no nat proto carp all
nat-anchor "natearly/*" all
nat-anchor "natrules/*" all
<...>
no rdr proto carp all
rdr-anchor "zapret" all
rdr-anchor "tftp-proxy/*" all
rdr-anchor "miniupnpd" all

$ pfctl -s nat -a zapret
rdr pass on em1 inet proto tcp from any to any port = http -> 127.0.0.1 port 988
rdr pass on em1 inet proto tcp from any to any port = https -> 127.0.0.1 port 988
rdr pass on em1 inet6 proto tcp from any to any port = http -> fe80::20c:29ff:5ae3:4821 port 988
rdr pass on em1 inet6 proto tcp from any to any port = https -> fe80::20c:29ff:5ae3:4821 port 988
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--18"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Так же есть более элегантный способ запуска `tpws` через @reboot в cron и правило перенаправления в UI. Это позволит не редактировать код pfsense.

## OpenBSD

### tpws bind на ipv4

В `tpws` bind по умолчанию только на ipv6. Для bind на ipv4 нужно указать `--bind-addr=0.0.0.0`. Используйте `--bind-addr=0.0.0.0 --bind-addr=::` для достижения того же результата, как в других ОС по умолчанию. Но лучше все же так не делать, а сажать на определенные внутренние адреса или интерфейсы.

### tpws для проходящего трафика (старая схема не работает в новых версиях)

В этом варианте tpws обращается явно к редиректору pf и пытается от него получить оригинальный адрес назначения. Как показывает практика, это не работает на новых версиях OpenBSD. Возвращается ошибка ioctl. Последняя проверенная версия, где это работает, - 6.8 . Между 6.8 и 7.4 разработчики сломали этот механизм.

`/etc/pf.conf`:

```
pass in quick on em1 inet  proto tcp to port {80,443} rdr-to 127.0.0.1 port 988
pass in quick on em1 inet6 proto tcp to port {80,443} rdr-to ::1 port 988

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--19"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>```
$ pfctl -f /etc/pf.conf
$ tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1 --enable-pf
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--20"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

В PF не выходит делать rdr-to с той же системы, где работает proxy. Вариант с route-to не сохраняет мета информацию. Адрес назначения теряется. Поэтому этот вариант годится для squid, берущего адрес из протокола прикладного уровня, но не годится для tpws, полагающегося на метаданные ОС. Поддержка rdr-to реализована через `/dev/pf`, поэтому прозрачный режим **требует root**.

### tpws для проходящего трафика (новые системы)

В новых версиях предлагается использовать divert-to вместо rdr-to. Минимально проверенная версия, где это работает, 7.4. Может работать или не работать на более старых - исследование не проводилось.

`/etc/pf.conf`:

```
pass on em1 inet proto tcp to port {80,443} divert-to 127.0.0.1 port 989
pass on em1 inet6 proto tcp to port {80,443} divert-to ::1 port 989

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--21"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>tpws должен иметь бинд на точно такой адрес, который указан в правилах pf. `0.0.0.0` или `::` не работает.

```
$ pfctl -f /etc/pf.conf
$ tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--22"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

Так же не понятно как делать divert с самой системы, где работает tpws.

### Запуск dvtws

#### Весь трафик

`/etc/pf.conf`:

```
pass in  quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state
pass in  quick on em0 proto tcp from port {80,443} no state
pass out quick on em0 proto tcp to   port {80,443} divert-packet port 989 no state

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--23"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>```
$ pfctl -f /etc/pf.conf
$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--24"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>#### Трафик только на таблицу zapret, за исключением таблицы nozapret

`/etc/pf.conf`:

```
set limit table-entries 2000000
table <zapret> file "/opt/zapret/ipset/zapret-ip.txt"
table <zapret-user> file "/opt/zapret/ipset/zapret-ip-user.txt"
table <nozapret> file "/opt/zapret/ipset/zapret-ip-exclude.txt"
pass out quick on em0 inet  proto tcp to   <nozapret> port {80,443}
pass in  quick on em0 inet  proto tcp from <zapret>  port {80,443} flags SA/SA divert-packet port 989 no state
pass in  quick on em0 inet  proto tcp from <zapret>  port {80,443} no state
pass out quick on em0 inet  proto tcp to   <zapret>  port {80,443} divert-packet port 989 no state
pass in  quick on em0 inet  proto tcp from <zapret-user>  port {80,443} flags SA/SA divert-packet port 989 no state
pass in  quick on em0 inet  proto tcp from <zapret-user>  port {80,443} no state
pass out quick on em0 inet  proto tcp to   <zapret-user>  port {80,443} divert-packet port 989 no state
table <zapret6> file "/opt/zapret/ipset/zapret-ip6.txt"
table <zapret6-user> file "/opt/zapret/ipset/zapret-ip-user6.txt"
table <nozapret6> file "/opt/zapret/ipset/zapret-ip-exclude6.txt"
pass out quick on em0 inet6 proto tcp to   <nozapret6> port {80,443}
pass in  quick on em0 inet6 proto tcp from <zapret6> port {80,443} flags SA/SA divert-packet port 989 no state
pass in  quick on em0 inet6 proto tcp from <zapret6> port {80,443} no state
pass out quick on em0 inet6 proto tcp to   <zapret6> port {80,443} divert-packet port 989 no state
pass in  quick on em0 inet6 proto tcp from <zapret6-user>  port {80,443} flags SA/SA divert-packet port 989 no state
pass in  quick on em0 inet6 proto tcp from <zapret6-user>  port {80,443} no state
pass out quick on em0 inet6 proto tcp to   <zapret6-user> port {80,443} divert-packet port 989 no state

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--25"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>```
$ pfctl -f /etc/pf.conf
$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--26"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>### Проблемы с badsum

**OpenBSD** принудительно пересчитывает tcp checksum после divert, поэтому скорее всего `dpi-desync-fooling=badsum` у вас не заработает. При использовании этого параметра `dvtws` предупредит о возможной проблеме.

### Особенность отправки fake пакетов

В **OpenBSD** `dvtws` все фейки отсылает через divert socket, поскольку эта возможность через raw sockets заблокирована. Видимо PF автоматически предотвращает повторный заворот diverted фреймов, поэтому проблемы зацикливания нет.

divert-packet автоматически вносит обратное правило для перенаправления. Трюк с no state и in правилом позволяет обойти эту проблему, чтобы напрасно не гнать массивный трафик через `dvtws`.

### Перезагрузка PF таблиц

Скрипты из ipset не перезагружают таблицы в PF по умолчанию.

Чтобы они это делали, добавьте параметр в `/opt/zapret/config`:

```
LISTS_RELOAD="pfctl -f /etc/pf.conf"

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--27"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div>Более новые версии `pfctl` понимают команду перезагрузить только таблицы. Но это не относится к **OpenBSD**. В новых **FreeBSD** есть.

```
$ pfctl -Tl -f /etc/pf.conf
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--28"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><svg aria-hidden="true" class="octicon octicon-report mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Important

Не забудьте выключить сжатие gzip: `GZIP_LISTS=0`

<svg aria-hidden="true" class="octicon octicon-report mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Important

Если в вашей конфигурации какого-то файла листа нет, то его необходимо исключить из правил PF. Если вдруг листа нет, и он задан в pf.conf, будет ошибка перезагрузки фаервола.

<svg aria-hidden="true" class="octicon octicon-info mr-2" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>Note

После настройки обновление листов можно поместить в cron:

```
$ crontab -e
```

<div class="markdown-alert markdown-alert-note" dir="auto" id="bkmrk--29"><div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto"><div class="zeroclipboard-container"><svg aria-hidden="true" class="octicon octicon-copy js-clipboard-copy-icon" data-view-component="true" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>  
</div></div><div class="snippet-clipboard-content notranslate position-relative overflow-auto">  
</div></div>```
<...>
0 12 */2 * * /opt/zapret/ipset/get_config.sh
```

https://forum.lissyara.su/freebsd-f8/obhod-dpi-na-shlyuze-t46842.html

# FreeBSD 13.1: GPU passthrough with bhyve | Windows 10 ???

https://rutube.ru/video/37bc4749554c4f88a1873d02e1500090/?ysclid=mgqoo0p8q2243477801

# Sendmail FreeBSD 14*

<div class="bbCodeBlock-title" id="bkmrk-code%3A">Code:</div>```
/etc/mail # make all
/usr/bin/m4 -D_CF_DIR_=/usr/share/sendmail/cf/   /usr/share/sendmail/cf/m4/cf.m4 xxx.xxx.net.mc > xxx.xxx.net.cf
/usr/bin/m4 -D_CF_DIR_=/usr/share/sendmail/cf/   /usr/share/sendmail/cf/m4/cf.m4 xxx.xxx.net.submit.mc > xxx.xxx.net.submit.cf
/usr/sbin/sendmail -bi -OAliasFile=/etc/mail/aliases
sendmail: no recipients
*** Error code 66

Stop.
make: stopped in /etc/mail
/etc/mail #
```

To continue using Sendmail:

> <div class="bbCodeBlock-content"><div class="bbCodeBlock-expandContent js-expandContent ">cd /etc/mail  
> cp /usr/share/examples/sendmail/mailer.conf /etc/mail/mailer.conf  
> make  
> cp HOSTNAME.cf sendmail.cf  
> service sendmail restart</div></div>

# Установите Home Assistant на FreeBSD внутри виртуальной машины bhyve

Для этого на FreeBSD 13.1-p1 vm vm-bhyve 1.5.0 в качестве менеджера виртуальных машин bhyve и qemu-tools 7.0.0\_1 требуется преобразовать образ из qcow2 в raw, как я полагаю.

## Требования

### Требуемые pkgs

- вм-бхиве
- qemu-инструменты

Для этого вам нужно настроить vm-bhyve, о чём я не буду рассказывать.

### Шаблон операционной системы Centos8

Создайте файл с именем centos8.conf. Поместите этот файл в папку vm\_dir в разделе «.templates».

```
loader="uefi"
cpu=1
memory=512M
network0_type="virtio-net"
network0_switch="public"
disk0_name="disk0"
disk0_dev="sparse-zvol"
disk0_type="virtio-blk"
```

## Установка

При запуске vm img url образ будет загружен, распакован и помещён в нужную папку. Папка vm\_dir определена в /etc/rc.conf в подкаталоге ".img". На тот момент последней версией образа была 8.4. Однако после установки мне сразу же предложили обновиться до версии ОС 8.5.

### Загрузить изображение

```
vm img <a href="https://github.com/home-assistant/operating-system/releases/download/8.4/haos_ova-8.4.qcow2.xz">https://github.com/home-assistant/operating-system/releases/download/8.4/haos_ova-8.4.qcow2.xz</a>
```

### Создание виртуальной машины

Теперь мы создаём виртуальную машину с помощью команды vm create. Параметр **-t centos8** определяет шаблон, созданный ранее. Параметр -c 2 указывает, сколько ядер вы хотите назначить виртуальной машине. Параметр -m 8G указывает объём оперативной памяти, 4 ГБ должно быть достаточно. Ознакомьтесь с требованиями на веб-странице Home Assistant. Параметр -s 100G указывает объём дискового пространства, которое вы хотите назначить виртуальной машине. Когда я впервые настраивал это, я выделил только 50 ГБ, чего должно быть более чем достаточно. Однако я использую разреженный ZFS, так как он не будет использовать все 100 ГБ сразу, поэтому я могу выделить больше.

```
vm create -t centos8 -c 2 -m 8G -s 100G -i haos_ova-8.4.qcow2 haos
```

### Боковое примечание

По какой-то причине при первом запуске этой команды иногда возникает ошибка «Диск занят».

```
qemu-img: /dev/zvol/tank/bhyve/haos/disk0: error while creating output image: Protocol driver 'host_device' does not support image creation, and opening the image failed: Could not open '/dev/zvol/tank/bhyve/haos/disk0': Device busy
/usr/local/sbin/vm: ERROR: failed to write img file with qemu-img

```

Если удалить виртуальную машину и создать её заново, она появится.

```
vm destroy haos
```

Затем снова выполните команду vm create, и она создаст виртуальную машину. Если проблема не исчезнет, вы можете изменить шаблон, чтобы он использовал образы дисков, а не zfs. С образами дисков такой ошибки никогда не возникало. Также можно указать открытый ключ для аутентификации с помощью -C -k your\_key.pub. Но на текущей странице руководства нет информации об этом. И я не уверен, как это работает. По крайней мере, я не могу найти это на странице руководства. С помощью флага -n вы можете задать статический IP-адрес. Кроме того, я смог найти в исходном коде vm-core на GitHub.

```
Example netconfig param: "ip=10.0.0.2/24;gateway=10.0.0.1;nameservers=1.1.1.1,8.8.8.8"
```

Я бы хотел, чтобы у вас была возможность задать параметры для выбора сетевого коммутатора, который вы хотите использовать. Но, похоже, такой возможности нет.

## Завершение

### Проверьте конфигурацию

Завершите настройку, выполнив команду vm configure. В частности, проверьте, подключена ли виртуальная машина к нужному коммутатору виртуальных машин

```
vm configure haos
```

### Запуск виртуальной машины

Запустите машину, выполнив команду vm start

```
vm start haos
```

Контролируйте запуск, запустив консоль виртуальной машины

```
vm console haos
```

https://github.com/stiana/tcbsd-haos-installer

https://forums.truenas.com/t/installing-haos-home-assistant-os-in-a-vm/108

wget [https://github.com/home-assistant/operating-system/releases/download/16.2/haos\_ova-16.2.qcow2.xz](https://github.com/home-assistant/operating-system/releases/download/16.2/haos_ova-16.2.qcow2.xz)

unxz -v haos\_ova-16.2.qcow2.xz

qemu-img convert -p -O raw haos\_ova-16.2.qcow2 ha\_.img

# Выполнение резервного копирования сервера

## Выполнение резервного копирования сервера

Выполним **резервную копию сервера** и сжатие файла образа.

Если Вы работаете на **удаленной машине**, которую нужно клонировать, указываем **LocalIP** — где будет храниться образ системы:

<div class="my-syntax-highlighter-pro" id="bkmrk-"><div class="CodeMirror cm-s-default"><div><textarea readonly="readonly" spellcheck="false" tabindex="0"></textarea>  
</div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div></div></div></div></div></div></div></div>```
```

<div class="my-syntax-highlighter-pro" id="bkmrk-1"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure">  
</div><div><div class="CodeMirror-selected">  
</div></div><div class="CodeMirror-cursors">  
</div><div class="CodeMirror-code" role="presentation"><div><div class="CodeMirror-gutter-wrapper"><div class="CodeMirror-linenumber CodeMirror-gutter-elt">1</div></div></div></div></div></div></div></div></div></div></div>```
$ dd if=/dev/sda | gzip -1 - | ssh user@LocalIP dd of=image.gz
```

<div class="my-syntax-highlighter-pro" id="bkmrk--2"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-code" role="presentation"><div></div></div></div></div></div></div><div>  
</div><div class="CodeMirror-gutters"><div class="CodeMirror-gutter CodeMirror-linenumbers">  
</div></div></div></div></div>Если Вы работаете на **локальной машине**, указываем **RemoteIP** — системы, которую нужно клонировать:

<div class="my-syntax-highlighter-pro" id="bkmrk--3"><div class="CodeMirror cm-s-default"><div><textarea readonly="readonly" spellcheck="false" tabindex="0"></textarea>  
</div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div></div></div></div></div></div></div></div>```
```

<div class="my-syntax-highlighter-pro" id="bkmrk-1-1"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure">  
</div><div><div class="CodeMirror-selected">  
</div></div><div class="CodeMirror-cursors">  
</div><div class="CodeMirror-code" role="presentation"><div><div class="CodeMirror-gutter-wrapper"><div class="CodeMirror-linenumber CodeMirror-gutter-elt">1</div></div></div></div></div></div></div></div></div></div></div>```
$ ssh user@RemoteIP "dd if=/dev/sda | gzip -1 -" | dd of=image.gz
```

<div class="my-syntax-highlighter-pro" id="bkmrk--5"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-code" role="presentation"><div></div></div></div></div></div></div><div>  
</div><div class="CodeMirror-gutters"><div class="CodeMirror-gutter CodeMirror-linenumbers">  
</div></div></div></div></div><a name="2"></a>

## Клонирование системы с помощью dd

Итак, что же еще можно сделать с помощью **dd**? Если Вы хотите **клонировать систему с одного диска на другой**, указываем **RemoteIP** — системы, которую нужно клонировать:

<div class="my-syntax-highlighter-pro" id="bkmrk--7"><div class="CodeMirror cm-s-default"><div><textarea readonly="readonly" spellcheck="false" tabindex="0"></textarea>  
</div><div class="CodeMirror-hscrollbar" cm-not-content="true" tabindex="-1"><div>  
</div></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div></div></div></div></div></div></div></div>```
```

<div class="my-syntax-highlighter-pro" id="bkmrk-1-2"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure">  
</div><div>  
</div><div class="CodeMirror-cursors"><div class="CodeMirror-cursor">  
</div></div><div class="CodeMirror-code" role="presentation"><div><div class="CodeMirror-gutter-wrapper"><div class="CodeMirror-linenumber CodeMirror-gutter-elt">1</div></div></div></div></div></div></div></div></div></div></div>```
ssh root@RemoteIP "sudo dd if=/dev/vda bs=16M | gzip -1" | gunzip | pv -W | dd of=/dev/vda bs=16M
```

<div class="my-syntax-highlighter-pro" id="bkmrk--9"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-code" role="presentation"><div></div></div></div></div></div></div><div>  
</div><div class="CodeMirror-gutters"><div class="CodeMirror-gutter CodeMirror-linenumbers">  
</div></div></div></div></div><div class="zEkZU0BI" id="bkmrk--10">  
</div>Или можно **клонировать систему в образ**, образ не сжатый:

<div class="my-syntax-highlighter-pro" id="bkmrk--11"><div class="CodeMirror cm-s-default"><div><textarea readonly="readonly" spellcheck="false" tabindex="0"></textarea>  
</div><div class="CodeMirror-hscrollbar" cm-not-content="true" tabindex="-1"><div>  
</div></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div></div></div></div></div></div></div></div>```
```

<div class="my-syntax-highlighter-pro" id="bkmrk-1-3"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure">  
</div><div>  
</div><div class="CodeMirror-cursors"><div class="CodeMirror-cursor">  
</div></div><div class="CodeMirror-code" role="presentation"><div><div class="CodeMirror-gutter-wrapper"><div class="CodeMirror-linenumber CodeMirror-gutter-elt">1</div></div></div></div></div></div></div></div></div></div></div>```
ssh root@srv1.hhbb.me "dd if=/dev/vda bs=16M | gzip -1" | gunzip | pv -W | dd of=system-image-raw.img bs=16M
```

<div class="my-syntax-highlighter-pro" id="bkmrk--13"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-code" role="presentation"><div></div></div></div></div></div></div><div>  
</div><div class="CodeMirror-gutters"><div class="CodeMirror-gutter CodeMirror-linenumbers">  
</div></div></div></div></div>**Восстанавливаем образ системы**, указываем **RemoteIP** — системы, которую нужно восстановить:

<div class="my-syntax-highlighter-pro" id="bkmrk--14"><div class="CodeMirror cm-s-default"><div><textarea readonly="readonly" spellcheck="false" tabindex="0"></textarea>  
</div><div class="CodeMirror-hscrollbar" cm-not-content="true" tabindex="-1"><div>  
</div></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div></div></div></div></div></div></div></div>```
```

<div class="my-syntax-highlighter-pro" id="bkmrk-1-4"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure">  
</div><div>  
</div><div class="CodeMirror-cursors"><div class="CodeMirror-cursor">  
</div></div><div class="CodeMirror-code" role="presentation"><div><div class="CodeMirror-gutter-wrapper"><div class="CodeMirror-linenumber CodeMirror-gutter-elt">1</div></div></div></div></div></div></div></div></div></div></div>```
ssh root@RemoteIP "gunzip -c image.gz" | pv -W | sudo dd of=/dev/vda bs=16M
```

<div class="my-syntax-highlighter-pro" id="bkmrk--16"><div class="CodeMirror cm-s-default"><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer"><div><div class="CodeMirror-lines" role="presentation"><div role="presentation"><div class="CodeMirror-code" role="presentation"><div></div></div></div></div></div></div><div>  
</div><div class="CodeMirror-gutters"><div class="CodeMirror-gutter CodeMirror-linenumbers">  
</div></div></div></div></div><a name="3"></a>

## Выводы

Спасибо за уделенное время на прочтение статьи. Теперь Вы больше знаете о том, как осуществить различные полезные операции с помощью команды **dd**.

# Matrix.org

Matrix.org  
[http://matrix.org](http://matrix.org/)  
"Matrix is an open standard for interoperable, decentralised, real-time communication over IP. It can be used to power Instant Messaging, VoIP/WebRTC signalling, Internet of Things communication - or anywhere you need a standard HTTP API for publishing and subscribing to data whilst tracking the conversation history."  
  
Synapse[  ](https://github.com/matrix-org/synapse)[<u><tt>net/py-matrix-synapse</tt></u>](http://www.freshports.org/net/py-matrix-synapse "net/py-matrix-synapse port")  
[https://github.com/matrix-org/synapse](https://github.com/matrix-org/synapse)  
  
Riot.im (Mobile Client)  
[https://riot.im](https://riot.im/)  
  
  
<u>**My Thoughts**</u>  
  
Matrix.org is brilliant! I work for a small IT company. We like to keep things in house so we chose to host our own communication services via XMPP (OpenFire) for internal chat and mobile messaging as well as IRC (UnrealIRCd + ZNC) just to have it. When I stumbled across Matrix.org I was excited to try this new project. Synapse is still in heavy beta however, after using it I'm even more excited for whats to come.  
  
I've written this tutorial for those of you who want to give a Matrix.org HomeServer a try.  
  
  
<u>**Lets Begin!**</u>  
  
  
Assuming you have a clean installation of FreeBSD 11 <span style="color: rgb(0, 0, 0);">**(14)**</span>  
  
Switch to root user or use sudo  
`<kbd>su root</kbd>`  
  
Update FreeBSD  
`<kbd>freebsd-update fetch install</kbd>`  
  
Install Ports Tree  
`<kbd>portsnap fetch extract</kbd>`  
  
Install [<u><tt>ports-mgmt/portmaster</tt></u>](http://www.freshports.org/ports-mgmt/portmaster "ports-mgmt/portmaster port")

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A"><div class="bbCodeBlock-title">Code:</div></div><div class="bbCodeBlock-content" dir="ltr" id="bkmrk-">  
</div><div class="bbCodeBlock-content" dir="ltr" id="bkmrk-pkg-install--y-py311"><span style="color: rgb(0, 0, 0);">**pkg install -y py311-matrix-synapse** </span></div><div class="bbCodeBlock-content" dir="ltr" id="bkmrk--1"></div>```
# cd /usr/ports/ports-mgmt/portmaster
# make install clean
```

  
I use portmaster due to the number of dependencies, however you could just jump to the next step and use "make install clean"  
  
Install [<u><tt>net/py-matrix-synapse</tt></u>](http://www.freshports.org/net/py-matrix-synapse "net/py-matrix-synapse port")

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-1"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
# cd /usr/ports/net/py-matrix-synapse
# portmaster
```

  
  
Do note, you can also do an install via `<kbd>pkg install py27-matrix-synapse</kbd>` with Synth `<kbd>pkg install synth</kbd>` for keeping packages current... However, that's another tutorial.  
  
Create directory for Synapse files. This can be done under your own account or you can create a synapse user. This is fine because Synapse does not require root/wheel permissions to run.  
  
`<kbd>mkdir ~/.synapse</kbd>`  
  
  
I created 3 scripts for the next three steps.

<span style="color: rgb(0, 0, 0);">**\# Enable services** </span>

<span style="color: rgb(0, 0, 0);"> **sysrc synapse\_enable="YES"** </span>

<span style="color: rgb(0, 0, 0);">**\# Obtain SSL Certificate certbot certonly --standalone -d matrix.example.com (14)**</span>

  
  
<u>**Script #1**</u>: <tt>synapse\_config.sh</tt>  
This will be used to configure synapse before starting the service.

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-2"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
#!/bin/sh
# Synapse: Config Synapse
cd ~/.synapse
python2.7 -m synapse.app.homeserver \
          --server-name  ip-mail.ru \         # *MyDomain.com* can be any internal or external domain
          --config-path /usr/local/etc/matrix-synapse/homeserver.yaml \
          --generate-config \
          --report-stats=no
```

  
For further details on this script, please visit Synapse on GitHub. For this tutorial, all you'll need to adjust is the domain. Save the script then run it to configure synapse. Which we'll do at this time.

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-3"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
# ~/synapse_config.sh
A config file has been generated in 'homeserver.yaml' for server name 'MyDomain.com' with corresponding SSL keys and self-signed certificates. Please review this file and customize it to your needs.
If this server name is incorrect, you will need to regenerate the SSL certificates
```

  
  
  
<u>**Script #2**</u>: <tt>synapse\_start.sh</tt>  
This script will be used to start Synapse. It will also be added to cron so it'll run at boot.

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-4"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
#!/bin/sh
# Synapse: Start Synapse
cd ~/.synapse
synctl start
```

  
Lets start Synapse then add this script to cron

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-5"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
# ~/synapse_start.sh
2017-02-21 22:06:39,476 - twisted - 131 - INFO - - SynapseSite starting on 8008
2017-02-21 22:06:39,477 - twisted - 131 - INFO - - Starting factory <synapse.http.site.SynapseSite instance at 0x80f17b680>
2017-02-21 22:06:39,477 - synapse.app.homeserver - 202 - INFO - - Synapse now listening on port 8008
started synapse.app.homeserver('homeserver.yaml')
```

  
The configuration should take a few seconds. Once done, you should see something similar to the text above.  
  
Lets add this script to the cronjobs. Not as root.

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-6"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
# crontab -e
@reboot ~/synapse_start.sh
```

  
  
<u>**Script #3**</u>: <tt>synapse\_add\_user.sh</tt>  
This script will be used to add users to the Synapse database.

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-7"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
#!/bin/sh
# Synapse: Add User
cd ~/.synapse
register_new_matrix_user -c /usr/local/etc/matrix-synapse/homeserver.yaml https://localhost:8008
```

  
Lets run this script...

<div class="bbCodeBlock bbCodeBlock--screenLimited bbCodeBlock--code" id="bkmrk-code%3A-8"><div class="bbCodeBlock-title">Code:</div><div class="bbCodeBlock-content" dir="ltr">  
</div></div>```
# ~/code/scripts/synapse_add_user.sh
New user localpart [tzuntzai]: tzuntzai
Password:
Confirm password:
Make admin [no]: yes
```

  
If everything goes well, you can point your browser to [https://localhost:8008](https://localhost:8448/) and you’ll be presented with a login screen.  
  
Use the account you just created to log into your Matrix.org Home Server and enjoy! Cheers!  
  
  
~ Alex

[https://ru.hostzealot.com/blog/how-to/posagovoe-rukovodstvo-po-ustanovke-servera-synapse-matrix-server-na-ubuntu-2204](https://ru.hostzealot.com/blog/how-to/posagovoe-rukovodstvo-po-ustanovke-servera-synapse-matrix-server-na-ubuntu-2204)

https://eurafri.com/projects/tutorials/tutorial-en-00009/

# Samba

<div id="bkmrk-%5Bglobal%5D">[global]</div><div id="bkmrk-%23%D0%A2%D0%B8%D0%BF-%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8">\#Тип аутентификации</div><div id="bkmrk-security-%3D-user">security = user</div><div id="bkmrk-%23%D0%91%D0%B0%D0%B7%D0%B0-%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D0%B5%D0%B9">\#База паролей</div><div id="bkmrk-passdb-backend-%3D-tdb">passdb backend = tdbsam</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B1%D0%BE%D1%87%D0%B0%D1%8F-%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B0">\#Рабочая группа</div><div id="bkmrk-workgroup-%3D-kdc">workgroup = kdc</div><div id="bkmrk-">  
</div><div id="bkmrk-%23%D0%A2%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D0%BE%D0%B5-%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-">\#Текстовое описание сервера</div><div id="bkmrk-server-string-%3D-stor">server string = storage</div><div id="bkmrk-%23netbios-%D0%B8%D0%BC%D1%8F">\#Netbios имя</div><div id="bkmrk-netbios-name-%3D-stora">netbios name = storage</div><div id="bkmrk--1">  
</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D1%82%D0%B5%D1%80-%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80">\#Мастер браузер</div><div id="bkmrk-local-master-%3D-no">local master = no</div><div id="bkmrk--2">  
</div><div id="bkmrk-%23%D0%9F%D1%80%D0%B8%D0%BE%D1%80%D0%B8%D1%82%D0%B5%D1%82-%D0%BC%D0%B0%D1%81%D1%82%D0%B5%D1%80-%D0%B1%D1%80">\#Приоритет мастер браузера</div><div id="bkmrk-os-level-%3D-255">os level = 255</div><div id="bkmrk--3">  
</div><div id="bkmrk-%23%D0%94%D0%BE%D0%BC%D0%B5%D0%BD-%D0%BA%D0%BE%D0%BD%D1%82%D1%80%D0%BE%D0%BB%D0%B5%D1%80">\#Домен контролер</div><div id="bkmrk-domain-master-%3D-no">domain master = no</div><div id="bkmrk--4">  
</div><div id="bkmrk-%23%D0%92%D0%B5%D1%80%D1%81%D0%B8%D0%B8-%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D0%BE%D0%B2">\#Версии протоколов</div><div id="bkmrk-server-min-protocol-">server min protocol = SMB2</div><div id="bkmrk-client-min-protocol-">client min protocol = SMB2</div><div id="bkmrk-client-max-protocol-">client max protocol = SMB3</div><div id="bkmrk--5">  
</div><div id="bkmrk-%23wins-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80">\#wins сервер</div><div id="bkmrk-wins-support-%3D-no">wins support = no</div><div id="bkmrk-%C2%A0"> </div><div id="bkmrk--6">  
</div><div id="bkmrk-%23%D0%9D%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88%D0%B0">\#Название сетевой шары</div><div id="bkmrk-%5Bstorage%5D">[storage]</div><div id="bkmrk-%23%D0%9F%D1%83%D1%82%D1%8C-%D0%B4%D0%BE-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B8-">\#Путь до директории шары</div><div id="bkmrk-path-%3D-%2Fdata%2Fstorage">path = /data/storage/files</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2">\#Разрешенные пользователи</div><div id="bkmrk-valid-users-%3D-%40samba">valid users = @samba,@buzz</div><div id="bkmrk-%23%D0%93%D1%80%D1%83%D0%BF%D0%BF%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-">\#Группа для сетевой шары</div><div id="bkmrk-force-group-%3D-samba">force group = samba</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D1%84%D0%B0%D0%B9%D0%BB">\#Маска создания файлов</div><div id="bkmrk-create-mask-%3D-0770">create mask = 0770</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B4%D0%B8%D1%80%D0%B5">\#Маска создания директорий</div><div id="bkmrk-directory-mask-%3D-077">directory mask = 0770</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81">\#Разрешение на запись</div><div id="bkmrk-writable-%3D-yes">writable = yes</div><div id="bkmrk-%23%D0%92%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88">\#Видимость сетевой шары</div><div id="bkmrk-browseable-%3D-yes">browseable = yes</div><div id="bkmrk--7">  
</div><div id="bkmrk--8">  
</div><div id="bkmrk-%23%D0%9D%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88%D0%B0-1">\#Название сетевой шары</div><div id="bkmrk-%5Badmin%5D">[admin]</div><div id="bkmrk-%23%D0%9F%D1%83%D1%82%D1%8C-%D0%B4%D0%BE-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B8--1">\#Путь до директории шары</div><div id="bkmrk-path-%3D-%2Fdata%2Fadmin">path = /data/admin</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2-1">\#Разрешенные пользователи</div><div id="bkmrk-valid-users-%3D-%40buzz">valid users = @buzz</div><div id="bkmrk-%23%D0%93%D1%80%D1%83%D0%BF%D0%BF%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9--1">\#Группа для сетевой шары</div><div id="bkmrk-force-group-%3D-buzz">force group = buzz</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D1%84%D0%B0%D0%B9%D0%BB-1">\#Маска создания файлов</div><div id="bkmrk-create-mask-%3D-0770-1">create mask = 0770</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B4%D0%B8%D1%80%D0%B5-1">\#Маска создания директорий</div><div id="bkmrk-directory-mask-%3D-077-1">directory mask = 0770</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81-1">\#Разрешение на запись</div><div id="bkmrk-writable-%3D-yes-1">writable = yes</div><div id="bkmrk-%23%D0%92%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88-1">\#Видимость сетевой шары</div><div id="bkmrk-browseable-%3D-yes-1">browseable = yes</div><div id="bkmrk--9">  
</div><div id="bkmrk--10">  
</div><div id="bkmrk-%23%D0%9D%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88%D0%B0-2">\#Название сетевой шары</div><div id="bkmrk-%5Bbase%5D">[base]</div><div id="bkmrk-create-mask-%3D-0770-2">create mask = 0770</div><div id="bkmrk-path-%3D-%2Fdata%2Fbase">path = /data/base</div><div id="bkmrk-browseable-%3D-yes-2">browseable = yes</div><div id="bkmrk-directory-mask-%3D-077-2">directory mask = 0770</div><div id="bkmrk-force-group-%3D-bd">force group = bd</div><div id="bkmrk-valid-users-%3D-%40bd%2C%40b">valid users = @bd,@buzz</div><div id="bkmrk-writeable-%3D-yes">writeable = yes</div><div id="bkmrk--12"></div><div id="bkmrk-%23%D0%9D%D0%B0%D0%B7%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88%D0%B0-3">\#Название сетевой шары</div><div id="bkmrk-%5Baccountancy%5D">[accountancy]</div><div id="bkmrk-%23%D0%9F%D1%83%D1%82%D1%8C-%D0%B4%D0%BE-%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B8--3">\#Путь до директории шары</div><div id="bkmrk-path-%3D-%2Fdata%2Faccount">path = /data/accountancy</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2-3">\#Разрешенные пользователи</div><div id="bkmrk-valid-users-%3D-%40buzz%2C">valid users = @buzz,@buh,@bd</div><div id="bkmrk-%23%D0%93%D1%80%D1%83%D0%BF%D0%BF%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9--3">\#Группа для сетевой шары</div><div id="bkmrk-force-group-%3D-buh">force group = buh</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D1%84%D0%B0%D0%B9%D0%BB-3">\#Маска создания файлов</div><div id="bkmrk-create-mask-%3D-0770-3">create mask = 0770</div><div id="bkmrk-%23%D0%9C%D0%B0%D1%81%D0%BA%D0%B0-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B4%D0%B8%D1%80%D0%B5-3">\#Маска создания директорий</div><div id="bkmrk-directory-mask-%3D-077-3">directory mask = 0770</div><div id="bkmrk-%23%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BD%D0%B0-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81-3">\#Разрешение на запись</div><div id="bkmrk-writable-%3D-yes-2">writable = yes</div><div id="bkmrk-%23%D0%92%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C-%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D0%BE%D0%B9-%D1%88-3">\#Видимость сетевой шары</div><div id="bkmrk-browseable-%3D-yes-3">browseable = yes</div>Создаём пользователя в Unix и добавляем его в samba, *smbpasswd -a &lt;Имя пользователя&gt;*

# Шпаргалка по FreeBSD для администраторов Linux

## Информация Об оборудовании

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Список <span class="caps">PCI</span> устройств</td><td>`pciconf -lv`</td><td>`lspci -v`</td></tr><tr><td>Список <span class="caps">USB</span> устройств</td><td>`usbconfig`</td><td>`lsusb`</td></tr><tr><td>Показывать информацию о <span class="caps">процессоре</span></td><td>`sysctl hw.model` или `dmesg \| grep CPU`</td><td>`cat /proc/cpuinfo` или `lscpu`</td></tr><tr><td>Показать информацию о памяти</td><td>`sysctl hw.physmem` или `top`</td><td>`free -h` или `cat /proc/meminfo`</td></tr><tr><td>Показывать модули ядра</td><td>`kldstat`</td><td>`lsmod`</td></tr><tr><td>Загрузить модуль ядра</td><td>`kldload module_name`</td><td>`modprobe module_name`</td></tr><tr><td>Выгрузить модуль ядра</td><td>`kldunload module_name`</td><td>`modprobe -r module_name`</td></tr></tbody></table>

## Управление дисками и хранилищем

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-1"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Перечислите все диски</td><td>`geom disk list`</td><td>`lsblk` или `fdisk -l`</td></tr><tr><td>Показывать разделы диска</td><td>`gpart show`</td><td>`fdisk -l` или `parted -l`</td></tr><tr><td>Показывать использование диска</td><td>`df -h`</td><td>`df -h`</td></tr><tr><td>Показывать смонтированные файловые системы</td><td>`mount`</td><td>`mount` или `findmnt`</td></tr><tr><td>Проверка файловой системы</td><td>`fsck`</td><td>`fsck`</td></tr><tr><td>Показать данные <span class="caps">SMART</span></td><td>`smartctl -a /dev/ada0`</td><td>`smartctl -a /dev/sda`</td></tr><tr><td>Список пулов <span class="caps">ZFS</span></td><td>`zpool list`</td><td>`zpool list` (если установлен <span class="caps">ZFS</span>)</td></tr><tr><td>Показать наборы данных <span class="caps">ZFS</span></td><td>`zfs list`</td><td>`zfs list` (если установлен <span class="caps">ZFS</span>)</td></tr></tbody></table>

## Сетевые команды

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-2"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Показывать сетевые интерфейсы</td><td>`ifconfig`</td><td>`ip addr` или `ifconfig`</td></tr><tr><td>Настройка интерфейса</td><td>`ifconfig em0 inet 192.168.1.10`</td><td>`ip addr add 192.168.1.10/24 dev eth0`</td></tr><tr><td>Показать таблицу маршрутизации</td><td>`netstat -rn`</td><td>`ip route` или `route -n`</td></tr><tr><td>Добавить статический маршрут</td><td>`route add default 192.168.1.1`</td><td>`ip route add default via 192.168.1.1`</td></tr><tr><td>Показать таблицу <span class="caps">ARP</span></td><td>`arp -a`</td><td>`arp -a` или `ip neigh`</td></tr><tr><td>Очистить запись <span class="caps">ARP</span></td><td>`arp -d hostname`</td><td>`arp -d hostname` или `ip neigh del`</td></tr><tr><td>Показывать сетевую статистику</td><td>`netstat -s`</td><td>`netstat -s` или `ss -s`</td></tr><tr><td>Показывать порты прослушивания</td><td>`sockstat -l` или `netstat -an`</td><td>`ss -tuln` или `netstat -tuln`</td></tr><tr><td>Показать все открытые порты/подключения</td><td>`sockstat`</td><td>`ss -tuan` или `netstat -tuan`</td></tr><tr><td>Захват пакетов</td><td>`tcpdump -i em0`</td><td>`tcpdump -i eth0`</td></tr></tbody></table>

## Управление процессами

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-3"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Перечислите все процессы</td><td>`ps aux`</td><td>`ps aux`</td></tr><tr><td>Дерево процессов</td><td>`pstree`</td><td>`pstree` или `ps axjf`</td></tr><tr><td>Просмотр процесса в режиме реального времени</td><td>`top`</td><td>`top` или `htop`</td></tr><tr><td>Процесс уничтожения</td><td>`kill PID`</td><td>`kill PID`</td></tr><tr><td>Показывать открытые файлы по процессам</td><td>`fstat`</td><td>`lsof`</td></tr><tr><td>Показать процесс, использующий порт</td><td>`sockstat -p 80`</td><td>`lsof -i :80` или `ss -tulpn \| grep :80`</td></tr></tbody></table>

## Управление пакетами

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-4"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux (в зависимости от дистрибутива)</th></tr></thead><tbody><tr><td>Установочный пакет</td><td>`pkg install package_name`</td><td>`apt install` / `yum install` / `dnf install`</td></tr><tr><td>Удалить пакет</td><td>`pkg delete package_name`</td><td>`apt remove` / `yum remove` / `dnf remove`</td></tr><tr><td>Обновить список пакетов</td><td>`pkg update`</td><td>`apt update` / `yum check-update`</td></tr><tr><td>Пакеты обновления</td><td>`pkg upgrade`</td><td>`apt upgrade` / `yum upgrade` / `dnf upgrade`</td></tr><tr><td>Поиск пакетов</td><td>`pkg search keyword`</td><td>`apt search` / `yum search` / `dnf search`</td></tr><tr><td>Показать информацию о пакете</td><td>`pkg info package_name`</td><td>`apt show` / `yum info` / `dnf info`</td></tr><tr><td>Список установленных пакетов</td><td>`pkg info`</td><td>`dpkg -l` / `rpm -qa`</td></tr></tbody></table>

## Системные службы

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-5"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux (systemd)</th></tr></thead><tbody><tr><td>Начать обслуживание</td><td>`service servicename start`</td><td>`systemctl start servicename`</td></tr><tr><td>Остановить обслуживание</td><td>`service servicename stop`</td><td>`systemctl stop servicename`</td></tr><tr><td>Перезапустить службу</td><td>`service servicename restart`</td><td>`systemctl restart servicename`</td></tr><tr><td>Состояние обслуживания</td><td>`service servicename status`</td><td>`systemctl status servicename`</td></tr><tr><td>Включить при загрузке</td><td>`sysrc servicename_enable="YES"`</td><td>`systemctl enable servicename`</td></tr><tr><td>Отключить при загрузке</td><td>`sysrc servicename_enable="NO"`</td><td>`systemctl disable servicename`</td></tr><tr><td>Перечислите все услуги</td><td>`service -e`</td><td>`systemctl list-units --type=service`</td></tr></tbody></table>

## Брандмауэр

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-%28pf%2Fi"><thead><tr><th>Задача</th><th>FreeBSD (pf/ipfw)</th><th>Linux (iptables/nftables)</th></tr></thead><tbody><tr><td>Правила показа (pf)</td><td>`pfctl -sr`</td><td>`iptables -L -n -v`</td></tr><tr><td>Показать правила (ipfw)</td><td>`ipfw list`</td><td>`nft list ruleset`</td></tr><tr><td>Включить брандмауэр (pf)</td><td>`pfctl -e`</td><td>`systemctl start firewalld`</td></tr><tr><td>Отключить брандмауэр (pf)</td><td>`pfctl -d`</td><td>`systemctl stop firewalld`</td></tr><tr><td>Правила перезарядки (pf)</td><td>`pfctl -f /etc/pf.conf`</td><td>`iptables-restore < /etc/iptables/rules.v4`</td></tr></tbody></table>

## Системная информация

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-6"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Время безотказной работы системы</td><td>`uptime`</td><td>`uptime`</td></tr><tr><td>Версия ядра</td><td>`uname -a` или `freebsd-version`</td><td>`uname -a`</td></tr><tr><td>Показать все переменные sysctl</td><td>`sysctl -a`</td><td>`sysctl -a`</td></tr><tr><td>Показывать системные сообщения</td><td>`dmesg`</td><td>`dmesg` или `journalctl -k`</td></tr><tr><td>Показывать системные журналы</td><td>`tail /var/log/messages`</td><td>`journalctl` или `tail /var/log/syslog`</td></tr></tbody></table>

## Управление пользователями

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-7"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Добавить пользователя</td><td>`adduser` или `pw useradd username`</td><td>`useradd username` или `adduser username`</td></tr><tr><td>Удалить пользователя</td><td>`rmuser` или `pw userdel username`</td><td>`userdel username`</td></tr><tr><td>Изменить пользователя</td><td>`pw usermod username`</td><td>`usermod username`</td></tr><tr><td>Сменить пароль</td><td>`passwd username`</td><td>`passwd username`</td></tr><tr><td>Показывать вошедших в систему пользователей</td><td>`who` или `w`</td><td>`who` или `w`</td></tr></tbody></table>

## Файловые системы

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-freebsd-linux-8"><thead><tr><th>Задача</th><th>FreeBSD</th><th>Linux</th></tr></thead><tbody><tr><td>Монтировать файловую систему</td><td>`mount /dev/ada0p2 /mnt`</td><td>`mount /dev/sda2 /mnt`</td></tr><tr><td>Размонтировать файловую систему</td><td>`umount /mnt`</td><td>`umount /mnt`</td></tr><tr><td>Создайте файловую систему <span class="caps">UFS</span></td><td>`newfs /dev/ada0p2`</td><td>Н/Д (<span class="caps">UFS</span> не распространено)</td></tr><tr><td>Создание файловой системы ext4</td><td>N/A</td><td>`mkfs.ext4 /dev/sda2`</td></tr><tr><td>Проверьте место на диске</td><td>`du -sh /path`</td><td>`du -sh /path`</td></tr></tbody></table>

## <span class="caps">ZFS</span> Команды (одинаковые для FreeBSD и Linux с <span class="caps">ZFS</span>)

### Операции с пулом

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Перечислите все пулы</td><td>`zpool list`</td><td>`zpool list`</td></tr><tr><td>Показать состояние пула</td><td>`zpool status`</td><td>`zpool status tank`</td></tr><tr><td>Показать историю пула</td><td>`zpool history`</td><td>`zpool history tank`</td></tr><tr><td>Показать статистику ввода-вывода</td><td>`zpool iostat`</td><td>`zpool iostat -v 2` (каждые 2 секунды)</td></tr><tr><td>Создайте простой пул</td><td>`zpool create`</td><td>`zpool create tank /dev/ada1`</td></tr><tr><td>Создание зеркального пула</td><td>`zpool create`</td><td>`zpool create tank mirror /dev/ada1 /dev/ada2`</td></tr><tr><td>Создайте пул <span class="caps">RAIDZ</span></td><td>`zpool create`</td><td>`zpool create tank raidz /dev/ada1 /dev/ada2 /dev/ada3`</td></tr><tr><td>Добавление диска в пул</td><td>`zpool add`</td><td>`zpool add tank /dev/ada4`</td></tr><tr><td>Замените диск в пуле</td><td>`zpool replace`</td><td>`zpool replace tank /dev/ada1 /dev/ada4`</td></tr><tr><td>Удаление устройства из пула</td><td>`zpool remove`</td><td>`zpool remove tank /dev/ada4`</td></tr><tr><td>Скраб-пул (проверка целостности)</td><td>`zpool scrub`</td><td>`zpool scrub tank`</td></tr><tr><td>Перестаньте скрести</td><td>`zpool scrub -s`</td><td>`zpool scrub -s tank`</td></tr><tr><td>Устранение ошибок пула</td><td>`zpool clear`</td><td>`zpool clear tank`</td></tr><tr><td>Экспортный пул</td><td>`zpool export`</td><td>`zpool export tank`</td></tr><tr><td>Пул импорта</td><td>`zpool import`</td><td>`zpool import tank`</td></tr><tr><td>Список импортируемых пулов</td><td>`zpool import`</td><td>`zpool import` (без названия пула)</td></tr><tr><td>Пул обновлений</td><td>`zpool upgrade`</td><td>`zpool upgrade tank`</td></tr><tr><td>Установить свойство пула</td><td>`zpool set`</td><td>`zpool set autoreplace=on tank`</td></tr><tr><td>Получить свойства пула</td><td>`zpool get`</td><td>`zpool get all tank`</td></tr></tbody></table>

### Операции с набором данных (файловой системой)

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5-1"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Перечислите все наборы данных</td><td>`zfs list`</td><td>`zfs list`</td></tr><tr><td>Список с конкретными свойствами</td><td>`zfs list`</td><td>`zfs list -o name,used,avail,mountpoint`</td></tr><tr><td>Список моментальных снимков</td><td>`zfs list -t snapshot`</td><td>`zfs list -t snapshot`</td></tr><tr><td>Создание набора данных</td><td>`zfs create`</td><td>`zfs create tank/home/user`</td></tr><tr><td>Уничтожить набор данных</td><td>`zfs destroy`</td><td>`zfs destroy tank/old_data`</td></tr><tr><td>Уничтожить набор данных и дочерние элементы</td><td>`zfs destroy -r`</td><td>`zfs destroy -r tank/old_data`</td></tr><tr><td>Установить свойство набора данных</td><td>`zfs set`</td><td>`zfs set compression=lz4 tank/home`</td></tr><tr><td>Получение свойств набора данных</td><td>`zfs get`</td><td>`zfs get all tank/home`</td></tr><tr><td>Установить квоту</td><td>`zfs set quota=`</td><td>`zfs set quota=10G tank/home/user`</td></tr><tr><td>Установленное резервирование</td><td>`zfs set reservation=`</td><td>`zfs set reservation=5G tank/database`</td></tr><tr><td>Набор данных для монтирования</td><td>`zfs mount`</td><td>`zfs mount tank/home`</td></tr><tr><td>Размонтировать набор данных</td><td>`zfs unmount`</td><td>`zfs unmount tank/home`</td></tr><tr><td>Показать подключённые файловые системы <span class="caps">ZFS</span></td><td>`zfs mount`</td><td>`zfs mount` (без аргументов)</td></tr></tbody></table>

### Операции Моментального снимка

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5-2"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Создать моментальный снимок</td><td>`zfs snapshot`</td><td>`zfs snapshot tank/home@backup-2024`</td></tr><tr><td>Создание рекурсивного моментального снимка</td><td>`zfs snapshot -r`</td><td>`zfs snapshot -r tank/home@daily-2024`</td></tr><tr><td>Список моментальных снимков</td><td>`zfs list -t snapshot`</td><td>`zfs list -t snapshot -r tank/home`</td></tr><tr><td>Откат к моментальному снимку</td><td>`zfs rollback`</td><td>`zfs rollback tank/home@backup-2024`</td></tr><tr><td>Уничтожить моментальный снимок</td><td>`zfs destroy`</td><td>`zfs destroy tank/home@old-backup`</td></tr><tr><td>Переименовать моментальный снимок</td><td>`zfs rename`</td><td>`zfs rename tank/home@old tank/home@archived`</td></tr><tr><td>Клонировать моментальный снимок</td><td>`zfs clone`</td><td>`zfs clone tank/home@backup tank/home_clone`</td></tr><tr><td>Показать использование диска моментального снимка</td><td>`zfs list -o space`</td><td>`zfs list -r -o space tank`</td></tr></tbody></table>

### Отправка/получение (репликация)

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5-3"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Отправить снимок</td><td>`zfs send`</td><td>`zfs send tank/home@backup > /backup/home.zfs`</td></tr><tr><td>Отправлять инкрементные</td><td>`zfs send -i`</td><td>`zfs send -i @snap1 tank/home@snap2 > incremental.zfs`</td></tr><tr><td>Получить моментальный снимок</td><td>`zfs receive`</td><td>`zfs receive tank/home_restore < /backup/home.zfs`</td></tr><tr><td>Отправить по <span class="caps">SSH</span></td><td>`zfs send \| ssh`</td><td>`zfs send tank/home@backup \| ssh user@host zfs receive tank/backup`</td></tr><tr><td>Приемное устройство для сухого прогона</td><td>`zfs receive -n`</td><td>`zfs receive -n tank/test < backup.zfs`</td></tr><tr><td>Отправлять с прогрессом</td><td>`zfs send -v`</td><td>`zfs send -v tank/home@backup > backup.zfs`</td></tr></tbody></table>

### Общие настройки свойств

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5-4"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Включить сжатие</td><td>`zfs set compression=`</td><td>`zfs set compression=lz4 tank/data`</td></tr><tr><td>Включить дедупликацию</td><td>`zfs set dedup=`</td><td>`zfs set dedup=on tank/backup`</td></tr><tr><td>Установите размер записи</td><td>`zfs set recordsize=`</td><td>`zfs set recordsize=1M tank/media`</td></tr><tr><td>Включить шифрование</td><td>`zfs create -o encryption=`</td><td>`zfs create -o encryption=on -o keyformat=passphrase tank/secure`</td></tr><tr><td>Установите время доступа</td><td>`zfs set atime=`</td><td>`zfs set atime=off tank/database`</td></tr><tr><td>Настройка режима синхронизации</td><td>`zfs set sync=`</td><td>`zfs set sync=disabled tank/temp`</td></tr><tr><td>Включить нечувствительность к регистру</td><td>`zfs set casesensitivity=`</td><td>`zfs create -o casesensitivity=insensitive tank/windows`</td></tr></tbody></table>

### Мониторинг и техническое обслуживание

<table id="bkmrk-%D0%97%D0%B0%D0%B4%D0%B0%D1%87%D0%B0-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5-5"><thead><tr><th>Задача</th><th>Команда</th><th>Пример</th></tr></thead><tbody><tr><td>Показать статистику ввода-вывода</td><td>`zpool iostat`</td><td>`zpool iostat -v tank 2`</td></tr><tr><td>Показать статистику <span class="caps">ARC</span> (FreeBSD)</td><td>`sysctl kstat.zfs.misc.arcstats`</td><td>`sysctl kstat.zfs.misc.arcstats.size`</td></tr><tr><td>Показать статистику <span class="caps">ARC</span> (Linux)</td><td>`arc_summary`</td><td>`arc_summary` или `cat /proc/spl/kstat/zfs/arcstats`</td></tr><tr><td>Проверьте состояние бассейна</td><td>`zpool status -x`</td><td>`zpool status -x` (показывает только проблемы)</td></tr><tr><td>Показывать мероприятия в бассейне</td><td>`zpool events`</td><td>`zpool events -v`</td></tr><tr><td>Расчетное время очистки</td><td>`zpool status`</td><td>`zpool status` (во время скрабирования)</td></tr><tr><td>Показать степень сжатия</td><td>`zfs get compressratio`</td><td>`zfs get compressratio tank/data`</td></tr><tr><td>Показывать использование пространства по типу</td><td>`zfs list -o space`</td><td>`zfs list -r -o space tank`</td></tr></tbody></table>

### Полезные однострочники

```
# Find largest datasets
zfs list -o name,used -s used

# Show all snapshots sorted by creation
zfs list -t snapshot -o name,creation -s creation

# Calculate total snapshot space
zfs list -t snapshot -o used -p | awk '{sum+=$1} END {print sum/1024/1024/1024 " GB"}'

# Show datasets with compression disabled
zfs get -r compression tank | grep -v "lz4\|gzip\|zle"

# Monitor pool I/O in real-time
zpool iostat -v 1

# Show properties that differ from defaults
zfs get all tank | grep -v default

# Quick backup to remote system
zfs snapshot tank/important@$(date +%Y%m%d) && \
zfs send tank/important@$(date +%Y%m%d) | ssh backup-server zfs receive tank/backup-2024

```

## Быстрые Советы

- **Именование устройств**: в FreeBSD используются другие соглашения об именовании (ada0 для <span class="caps">SATA</span>, da0 для <span class="caps">SCSI</span>/<span class="caps">USB</span>), чем в Linux (sda, sdb и т. д.).
- **Сетевые интерфейсы**: в FreeBSD интерфейсы называются по драйверу (em0, re0, bge0), в то время как в Linux традиционно используются eth0, eth1 (сейчас часто используются предсказуемые имена, такие как enp0s3)
- **Файлы конфигурации**: в FreeBSD многие конфигурации сосредоточены в `/etc/rc.conf`, в то время как в Linux они распределены по разным файлам
- **Страницы руководства**: в обоих случаях используется `man command`, но страницы руководства FreeBSD зачастую более подробные
- **Порты и пакеты**: в FreeBSD есть и порты (исходный код), и пакеты (бинарные файлы), в то время как в Linux обычно используется один менеджер пакетов для каждого дистрибутива
- **<span class="caps">ZFS</span>**: <span class="caps">ZFS</span> в Linux (ZoL) изначально поддерживается FreeBSD, но достигла паритета функций. Команды идентичны, но загрузка модулей ядра различается (`kldload zfs` в FreeBSD и `modprobe zfs` в Linux)

# Apache httpd : SSL/TLS Setting

<table class="base" id="bkmrk-%C2%A0-configure-ssl%2Ftls-"><tbody><tr><td class="num"> </td><td>Configure SSL/TLS setting to use secure encrypt HTTPS connection.

</td></tr><tr><td class="num">\[1\]</td><td>[Get SSL Certificate, refer to here](https://www.server-world.info/en/note?os=FreeBSD_14&p=ssl&f=2).

</td></tr><tr><td class="num">\[2\]</td><td>Enable SSL/TLS settings.</td></tr></tbody></table>

<table class="term" id="bkmrk-root%40www%3A%7E-%23%C2%A0-vi-%2Fus"><tbody><tr><td><div class="block">root@www:~ # <div class="color1">vi /usr/local/etc/apache24/httpd.conf</div></div><div class="block"><div class="color2">\# line 92 : uncomment</div>  
LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so</div><div class="block"><div class="color2">\# line 148 : uncomment</div>  
LoadModule ssl_module libexec/apache24/mod_ssl.so</div><div class="block"><div class="color2">\# line 526 : uncomment</div>  
Include etc/apache24/extra/httpd-ssl.conf</div><div class="block">root@www:~ # <div class="color1">vi /usr/local/etc/apache24/extra/httpd-ssl.conf</div></div><div class="block"><div class="color2">\# line 125, 126 : change to your server name and admin email</div>  
DocumentRoot "/usr/local/www/apache24/data"  
ServerName <div class="color1">www.srv.world:443</div>  
ServerAdmin <div class="color1">root@srv.world</div>  
ErrorLog "/var/log/httpd-error.log"  
TransferLog "/var/log/httpd-access.log"</div><div class="block"><div class="color2">\# line 144 : change to the certificate you got in [1]</div>  
SSLCertificateFile <div class="color1">"/usr/local/etc/letsencrypt/live/www.srv.world/cert.pem"</div></div><div class="block"><div class="color2">\# line 154 : change to the certificate you got in [1]</div>  
SSLCertificateKeyFile <div class="color1">"/usr/local/etc/letsencrypt/live/www.srv.world/privkey.pem"</div></div><div class="block"><div class="color2">\# line 165 : uncomment and change to the certificate you got in [1]</div>  
SSLCertificateChainFile <div class="color1">"/usr/local/etc/letsencrypt/live/www.srv.world/chain.pem"</div></div>root@www:~ # <div class="color1">service apache24 reload</div>  
</td></tr></tbody></table>

<table class="base" id="bkmrk-%5B3%5D-if-you%27d-like-to" style="width: 100%;"><tbody><tr><td class="num" style="width: 4.20409%;">\[3\]</td><td style="width: 95.7959%;">If you'd like to set HTTP connection to redirect to HTTPS (Always on SSL/TLS), Set RewriteRule to each Host settings.  
For example, [if you set Virtual Hostings like the link here](https://www.server-world.info/en/note?os=FreeBSD_14&p=httpd&f=2), Add RewriteRule like follows. Or It's possible to set RewriteRule in \[.htaccess\] not in \[httpd.conf\].</td></tr></tbody></table>

<table class="term" id="bkmrk-root%40www%3A%7E-%23%C2%A0-vi-%2Fus-1"><tbody><tr><td><div class="block">root@www:~ # <div class="color1">vi /usr/local/etc/apache24/httpd.conf</div></div><div class="block"><div class="color2">\# line 181 : uncomment</div>  
LoadModule rewrite_module libexec/apache24/mod_rewrite.so</div><div class="block">root@www:~ # <div class="color1">vi /usr/local/etc/apache24/Includes/vhost.conf</div></div>```
<VirtualHost *:80>
    DocumentRoot /usr/local/www/apache24/data
    ServerName www.srv.world
    # add RewriteRule
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

```

root@www:~ # <div class="color1">service apache24 reload</div>  
</td></tr></tbody></table>

<table class="base_win" id="bkmrk-%5B4%5D-verify-to-access"><tbody><tr><td class="num">\[4\]</td><td>Verify to access to the test page from any client computer with Web browser via HTTPS.</td></tr></tbody></table>

# Добавление диска и создание разделов во FreeBSD

#### <span style="color: rgb(68, 68, 68);">В этом руководстве будет рассмотрен процесс монтирования новых дисков и разделов на виртуальные серверы под управлением операционной системы </span>[FreeBSD](https://1cloud.ru/services/vps-vds/freebsd)<span style="color: rgb(68, 68, 68);">.</span>

### Разметка диска

Примечание: все действия в данном руководстве должны выполняться в привилегированном режиме.

Необходимо посмотреть какие диски доступны для монтирования:

<div id="bkmrk-geom-disk-list" itemprop="articleBody">`geom disk list`</div>![доступные диски](https://static.1cloud.ru/img/help/montirovanie-diska-vo-freebsd/1.png)

В нашем примере доступны диски: cd0 - CDROM, da0 - жесткий диск на котором установлена система, и дополнительный жесткий диск da1.

Примечание: если добавленный диск недоступен, то перезагрузите сервер.

В нашем примере мы будем монтировать устройство da1, полный путь к которому */dev/da1*.

Теперь с помощью команды gpart разобьем диск на разделы с разметкой GPT:

<div id="bkmrk-gpart-create%C2%A0-s%C2%A0gpt-" itemprop="articleBody">`gpart create <span class="hljs-_">-s</span> gpt /dev/da1`</div>```
da1 created
```

Примечание: GPT - GUID Partition Table, формат таблицы разделов, использует систему адресации логических блоков (LBA).

Проверяем получившиеся разделы:

<div id="bkmrk-gpart-show-da1" itemprop="articleBody">`gpart show da1`</div>```
=> 34 20971453 da1 GPT (10G)
   34 20971453  -free- (10G)
```

Теперь диск имеет разметку GPT.

### Пример 1

Создадим первый раздел:

<div id="bkmrk-gpart-add--t-freebsd" itemprop="articleBody">`gpart add -t freebsd-ufs <span class="hljs-_">-s</span> 1G /dev/da1`</div>```
da1p1 added
```

Второй раздел создадим без указания начального LBA и без указания размера — таким образом он будет создан на всем свободном пространстве:

<div id="bkmrk-gpart-add--t-freebsd-1" itemprop="articleBody">`gpart add -t freebsd-ufs /dev/da1`</div>```
da1p2 added
```

Проверяем получившиеся разделы:

<div id="bkmrk-gpart-show-da1-1" itemprop="articleBody">`gpart show da1`</div>```
 
=>    34 20971453 da1 GPT (10G)
      34 2097152 1 freebsd-ufs (1.0G)
2097186 18874301 2 freebsd-ufs (9.0G)
```

Для создания файловой системы на разделах диска выполните следующие команды:

<div id="bkmrk-newfs--u-%2Fdev%2Fda1p1n" itemprop="articleBody">`newfs -U /dev/da1p1``newfs -U /dev/da1p2`</div>Параметр -U указывает использование механизма Soft Update, который увеличивает скорость создания и удаления файлов путём использования кэширования.

![создание файловой системы](https://static.1cloud.ru/img/help/montirovanie-diska-vo-freebsd/2.png)

### Монтирование

Необходимо создать точку монтирования для каждого раздела:

<div id="bkmrk-mkdir-%2Fmnt%2Fdata1mkdi" itemprop="articleBody">`mkdir /mnt/data1``mkdir /mnt/data2`</div>Изменим режим доступа к разделам:

<div id="bkmrk-chmod--r-660-%2Fmnt%2Fda" itemprop="articleBody">`chmod -R 660 /mnt/data1``chmod -R 660 /mnt/data2`</div>Далее необходимо добавить новые разделы в файл /etc/fstab для того, чтобы при перезапуске сервера разделы монтировались автоматически. Откройте с помощью текстового редактора, например nano, данный файл:

<div id="bkmrk-nano-%2Fetc%2Ffstab" itemprop="articleBody">`nano /etc/fstab`</div>Добавьте следующие строки:

<div id="bkmrk-%2Fdev%2Fda1p1-%2Fmnt%2Fdata" itemprop="articleBody">`/dev/da1p1 /mnt/data1 ufs rw 0 0/dev/da1p2 /mnt/data2 ufs rw 0 0`</div>![добавление новых разделов](https://static.1cloud.ru/img/help/montirovanie-diska-vo-freebsd/3.png)

С помощью команды mount примонтируем все разделы согласно файлу /etc/fstab:

<div id="bkmrk-mount%C2%A0-a" itemprop="articleBody">`mount <span class="hljs-_">-a</span>`</div>### Пример 2 (добавление swap-раздела)

Для начала создадим раздел для swap:

<div id="bkmrk-gpart-add--t-freebsd-2" itemprop="articleBody">`gpart add -t freebsd-swap <span class="hljs-_">-s</span> 1G /dev/da1`</div>```
da1p1 added
```

Второй раздел создадим без указания начального LBA и без указания размера — таким образом он будет создан на всем свободном пространстве:

<div id="bkmrk-gpart-add--t-freebsd-3" itemprop="articleBody">`gpart add -t freebsd-ufs /dev/da1`</div>```
da1p2 added
```

Проверяем получившиеся разделы:

<div id="bkmrk-gpart-show-da1-2" itemprop="articleBody">`gpart show da1`</div>```
 
=>    34 20971453 da1 GPT (10G)
      34 2097152 1 freebsd-swap (1.0G)
2097186 18874301 2 freebsd-ufs (9.0G)
```

### Создание файловой системы

Раздел типа swap форматировать не нужно.

Для создания файловой системы на втором разделе диска выполните следующую команду:

<div id="bkmrk-newfs--u-%2Fdev%2Fda1p2" itemprop="articleBody">`newfs -U /dev/da1p2`</div>Параметр -U указывает использование механизма Soft Update, который увеличивает скорость создания и удаления файлов путём использования кэширования.

![создание файловой системы](https://static.1cloud.ru/img/help/montirovanie-diska-vo-freebsd/4.png)

### Монтирование

Необходимо создать точку монтирования для каждого раздела, кроме swap:

<div id="bkmrk-mkdir-%2Fmnt%2Fdata" itemprop="articleBody">`mkdir /mnt/data`</div>Измените режим доступа к разделам:

<div id="bkmrk-chmod--r-660-%2Fmnt%2Fda-1" itemprop="articleBody">`chmod -R 660 /mnt/data`</div>Далее нужно добавить новые разделы в файл */etc/fstab* для того чтобы при перезапуске сервера разделы монтировались автоматически. Откройте с помощью текстового редактора, например nano, данный файл:

<div id="bkmrk-nano-%2Fetc%2Ffstab-1" itemprop="articleBody">`nano /etc/fstab`</div>Добавьте следующие строки:

<div id="bkmrk-%2Fdev%2Fda1p1-none-swap" itemprop="articleBody">`/dev/da1p1 none swap sw 0 0/dev/da1p2 /mnt/data ufs rw 0 0`</div>![создание файловой системы](https://static.1cloud.ru/img/help/montirovanie-diska-vo-freebsd/5.png)

С помощью команды mount примонтируем все разделы согласно файлу */etc/fstab*:

<div id="bkmrk-mount%C2%A0-a-1" itemprop="articleBody">`mount <span class="hljs-_">-a</span>`</div>Проверим:

<div id="bkmrk-mount" itemprop="articleBody">`mount`</div>```
/dev/da1p2 on /mnt/data (ufs, local, soft-updates)
```

Далее с помощью команды swapon примонтируем swap-раздел:

<div id="bkmrk-swapon-%2Fdev%2Fda1p1" itemprop="articleBody">`swapon /dev/da1p1`</div>Проверим с помощью команды swapinfo:

<div id="bkmrk-swapinfo" itemprop="articleBody">`swapinfo`</div>```
Device    1K-blockes  Used  Avail  Capacity
/dev/da0p2 2097152      0   2097152   0%
/dev/da1p1 1028576      0   1028576   0%
Total      3145728      0   3145728   0%
```

<div id="bkmrk--5" itemprop="articleBody"><div class="help__onecloudweb hidden">  
</div></div>

# Soft for USB JTAG ARM Emulator v9 v11 v12 V13

[https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/?spm=a2g2w.chat.0.0.4a974aa64yqKBv](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/?spm=a2g2w.chat.0.0.4a974aa64yqKBv)

<header class="entry-header ast-no-thumbnail" id="bkmrk-%2F%C2%A0soft-download%C2%A0%2F-by"><div class="entry-meta">/ <span class="ast-terms-link">[Soft Download](https://jlinkzone.com/category/soft-download/)</span> / By <span class="posted-by vcard author">[<span class="author-name">LKC</span>](https://jlinkzone.com/author/vxbjpmmy/ "View all posts by LKC")</span></div></header>**Please download the soft here :**

***Windows** 64-bit Installer download link:*

//**[JLink\_Windows\_V924a\_x86\_64 ](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v924a_x86_64/)**[(2026-03-05)](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v924a_x86_64/)

//**[JLink\_Windows\_V924\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v924_x86_64/)**

//**[JLink\_Windows\_V922\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v922_x86_64/)**

//**[JLink\_Windows\_V920\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v920_x86_64/)**

**//[JLink\_Windows\_V918\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v918_x86_64/)**

//**[JLink\_Windows\_V916a\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v916a_x86_64/)**

//**[JLink\_Windows\_V916\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v916_x86_64/)**

//**[JLink\_Windows\_V914a\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v914a_x86_64/)**

[**//JLink\_Windows\_V912\_x86\_64**](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v912_x86_64/)

**[//JLink\_Windows\_V910\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v910_x86_64/)**

//**[JLink\_Windows\_V896\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v896_x86_64/)**

**[//JLink\_Windows\_V894\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v894_x86_64/)**

// [JLink\_Windows\_V892\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v892_x86_64/) // [JLink\_Windows\_V874\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v874_x86_64/) //[JLink\_Windows\_V796d\_x86\_64 // ](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v796d_x86_64/)[JLink\_Windows\_V856a\_x86\_64//](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v856a_x86_64/)

***Windows** 32-bit Installer download link:*

//**[JLink\_Windows\_V896\_i386 32-bit](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_windows_v896_i386-32-bit/)**

**MacOS** 64-bit Installer download link: [JLink\_MacOSX\_V796d\_x86\_64](https://jlinkzone.com/soft-for-usb-jtag-arm-emulator-v9-v11-v12/jlink_macosx_v796d_x86_64/)

# Webmin /tmp error

Это сообщение об ошибке появляется потому, что в FreeBSD 14 по умолчанию используется `tmpfs` для раздела `/tmp` (временное хранилище в оперативной памяти). Размер этого раздела по умолчанию или ограничен нулем из-за настроек монтирования, либо просто отображается некорректно .

Вот как это можно исправить, перенастроив Webmin на использование другой папки, расположенной на основном диске.

### Шаг 1: Создайте новую директорию для временных файлов

Подключитесь к серверу через SSH и выполните команду для создания папки. Например, создадим её в `/var/tmp` (этот каталог в FreeBSD не монтируется в RAM и подходит для таких целей):

<div class="md-code-block md-code-block-light" id="bkmrk-bash"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">bash</span></div></div></div></div></div>```
sudo mkdir -p /var/tmp/.webmin
```

**Важно:** Убедитесь, что у этой папки правильные права доступа, чтобы веб-сервер Webmin мог в неё писать:

<div class="md-code-block md-code-block-light" id="bkmrk-bash-1"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">bash</span></div></div></div></div></div>```
sudo chmod 1777 /var/tmp/.webmin
```

(Права `1777` означают «sticky-бит» — владелец может удалить только свои файлы, как в обычном `/tmp`).

### Шаг 2: Смените путь в настройках Webmin

Теперь нужно указать Webmin использовать новую папку вместо стандартной.

1. Войдите в веб-интерфейс Webmin.
2. Перейдите в раздел **Webmin** → **Webmin Configuration** (Конфигурация Webmin).
3. Нажмите на иконку **Advanced Options** (Расширенные опции) .
4. Найдите поле **Temporary files directory** (Директория временных файлов).
5. Замените значение по умолчанию `Default (/tmp/.webmin)` или просто путь, который там указан, на: `/var/tmp/.webmin`
6. Нажмите кнопку **Save** (Сохранить).

### Что произошло?

После этой смены:

- Webmin перестанет пытаться использовать `/tmp` (который лежит в оперативной памяти или смонтирован с ограничениями).
- Все временные файлы и резервные копии, которые он создает, теперь будут храниться в `/var/tmp/.webmin` на вашем основном диске, где достаточно места .

### Дополнительные рекомендации

- **Очистка старых файлов:** Webmin умеет автоматически чистить свою временную папку. Вы можете настроить "максимальный возраст временных файлов" (**Maximum age of temporary files**) там же, в расширенных опциях. Если вы используете нестандартную папку, убедитесь, что опция **Clear temp files in non-standard directory?** (Очищать временные файлы в нестандартной директории?) установлена в `Yes`, чтобы мусор не накапливался годами .
- **Перезагрузка:** Перезагружать Webmin после изменения этой настройки не требуется, изменения применяются сразу. Но если вы решите удалить старую папку (`/tmp/.webmin`), Webmin нужно предварительно остановить, чтобы не возникло конфликта открытых файлов .

Если после этого ошибка в интерфейсе осталась, просто обновите страницу — предупреждение должно исчезнуть.

# Диск Windows монтируется только для чтения (РЕШЕНО)

В настоящее время Windows использует файловую систему NTFS. Linux поддерживает эту файловую систему для чтения, записи, создания, форматирования и выполнения других операций.

Тем не менее, иногда при попытке смонтировать диск Windows может возникнуть одна из двух ситуаций:

- диск монтируется, но только для чтения. Специальное указание опция монтирования с правами записи не помогает
- диск вовсе не монтируется из-за ошибки

К примеру, при попытке смонтировать диск:

<div id="bkmrk-1-sudo-mount-%2Fdev%2Fsd"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-mount-%2Fdev%2Fsd-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `mount` `/dev/sdb4` `/mnt/disk_e`</div></div></td></tr></tbody></table>

</div></div>может возникнуть ошибка, что диск доступен только для чтения:

<div id="bkmrk-1-2-3-4-5-the-disk-c"><div class="syntaxhighlighter  plain" id="bkmrk-1-2-3-4-5-the-disk-c-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`The disk contains an unclean file system (0, 0).`</div><div class="line number2 index1 alt1">`Metadata kept in Windows cache, refused to mount.`</div><div class="line number3 index2 alt2">`Falling back to read-only mount because the NTFS partition is in an`</div><div class="line number4 index3 alt1">`unsafe state. Please resume and shutdown Windows fully (no hibernation`</div><div class="line number5 index4 alt2">`or fast restarting.)`</div></div></td></tr></tbody></table>

</div></div>А это пример ошибки, когда диск не смонтирован вовсе:

<div id="bkmrk-1-2-3-4-5-6-the-disk"><div class="syntaxhighlighter  plain" id="bkmrk-1-2-3-4-5-6-the-disk-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`The disk contains an unclean file system (0, 0).`</div><div class="line number2 index1 alt1">`Metadata kept in Windows cache, refused to mount.`</div><div class="line number3 index2 alt2">`Failed to mount '/dev/sdb1': Операция не позволена`</div><div class="line number4 index3 alt1">`The NTFS partition is in an unsafe state. Please resume and shutdown`</div><div class="line number5 index4 alt2">`Windows fully (no hibernation or fast restarting), or mount the volume`</div><div class="line number6 index5 alt1">`read-only with the 'ro' mount option.`</div></div></td></tr></tbody></table>

</div></div>Для решения этой проблемы нужно начать с установки драйвера **ntfs-3g**. Во-первых, он в любом случае необходим для полноценного функционирования файловой системы NTFS в Linux. Во-вторых, в этот пакет включена утилита **ntfsfix**, которая может помочь решить проблемы с диском Windows.

Для установки в Debian, Linux Mint, Ubuntu, Kali Linux и их производные:

<div id="bkmrk-1-sudo-apt-install-n"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-apt-install-n-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `apt ``install` `ntfs-3g`</div></div></td></tr></tbody></table>

</div></div>Для установки в Arch Linux и производные:

<div id="bkmrk-1-sudo-pacman--s-ntf"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-pacman--s-ntf-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `pacman -S ntfs-3g`</div></div></td></tr></tbody></table>

</div></div>Затем вновь попробуйте смонтировать диск — вполне возможно, что в этом случае он будет доступен с правами записи.

Если вновь возникла проблема, то отмонтируйте диск и запустите команду вида:

<div id="bkmrk-1-sudo-ntfsfix-%2F%D0%9F%D0%A3%D0%A2%D0%AC"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-ntfsfix-%2F%D0%9F%D0%A3%D0%A2%D0%AC-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `ntfsfix /ПУТЬ/ДО/ДИСКА`</div></div></td></tr></tbody></table>

</div></div>Пример команды для проверки и исправления проблемы с диском /dev/sdb4:

<div id="bkmrk-1-sudo-ntfsfix-%2Fdev%2F"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-ntfsfix-%2Fdev%2F-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `ntfsfix ``/dev/sdb4`</div></div></td></tr></tbody></table>

</div></div>Пример вывода:

<div id="bkmrk-1-2-3-4-5-6-7-8-9-10"><div class="syntaxhighlighter  plain" id="bkmrk-1-2-3-4-5-6-7-8-9-10-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`Mounting volume... The disk contains an unclean file system (0, 0).`</div><div class="line number2 index1 alt1">`Metadata kept in Windows cache, refused to mount.`</div><div class="line number3 index2 alt2">`FAILED`</div><div class="line number4 index3 alt1">`Attempting to correct errors... `</div><div class="line number5 index4 alt2">`Processing $MFT and $MFTMirr...`</div><div class="line number6 index5 alt1">`Reading $MFT... OK`</div><div class="line number7 index6 alt2">`Reading $MFTMirr... OK`</div><div class="line number8 index7 alt1">`Comparing $MFTMirr to $MFT... OK`</div><div class="line number9 index8 alt2">`Processing of $MFT and $MFTMirr completed successfully.`</div><div class="line number10 index9 alt1">`Setting required flags on partition... OK`</div><div class="line number11 index10 alt2">`Going to empty the journal ($LogFile)... OK`</div><div class="line number12 index11 alt1">`Checking the alternate boot sector... OK`</div><div class="line number13 index12 alt2">`NTFS volume version is 3.1.`</div><div class="line number14 index13 alt1">`NTFS partition /dev/sdb4 was processed successfully.`</div></div></td></tr></tbody></table>

</div></div>[![](https://zalinux.ru/wp-content/uploads/2019/11/ntfsfix.png)](https://zalinux.ru/wp-content/uploads/2019/11/ntfsfix.png)

Команда выводит причину проблемы: диск содержит нечистую файловую систему. Метаданные, хранимые в кэше Windows, препятствуют монтированию.

Затем выполняется ряд операций, каждая из которых заканчивается статусом OK и наконец сообщение **was processed successfully** говорит о том, что всё прошло успешно.

<div class="c88083470404aeda508e60e32ee4c3c6" data-index="10" id="bkmrk--1"><ins class="adsbygoogle" data-ad-client="ca-pub-7219829351026140" data-ad-format="auto" data-ad-slot="1097840891" data-full-width-responsive="true"></ins>  
</div>После этого вновь попытайтесь смонтировать диск — всё должно быть нормально.

## <a id="bkmrk--2" name="hibernated"></a>Решение ошибки «Windows is hibernated, refused to mount».  


Выполнение рассмотренной команды

<div id="bkmrk-1-sudo-ntfsfix-%2Fdev%2F-2"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-ntfsfix-%2Fdev%2F-3"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `ntfsfix ``/dev/sda4`</div></div></td></tr></tbody></table>

</div></div>может завершиться неудачей:

<div id="bkmrk-1-2-3-4-5-6-7-8-9-10-2"><div class="syntaxhighlighter  plain" id="bkmrk-1-2-3-4-5-6-7-8-9-10-3"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`Mounting volume… Windows is hibernated, refused to mount.`</div><div class="line number2 index1 alt1">`FAILED`</div><div class="line number3 index2 alt2">`Attempting to correct errors…`</div><div class="line number4 index3 alt1">`Processing $MFT and $MFTMirr…`</div><div class="line number5 index4 alt2">`Reading $MFT… OK`</div><div class="line number6 index5 alt1">`Reading $MFTMirr… OK`</div><div class="line number7 index6 alt2">`Comparing $MFTMirr to $MFT… OK`</div><div class="line number8 index7 alt1">`Processing of $MFT and $MFTMirr completed successfully.`</div><div class="line number9 index8 alt2">`Setting required flags on partition… OK`</div><div class="line number10 index9 alt1">`Going to empty the journal ($LogFile)… OK`</div><div class="line number11 index10 alt2">`Windows is hibernated, refused to mount.`</div><div class="line number12 index11 alt1">`Remount failed: Operation not permitted`</div></div></td></tr></tbody></table>

</div></div>Обратите особое внимание на строку «Windows is hibernated, refused to mount» которая повторяется дважды. Она означает, что работа Windows завершилась гибернацией, такой диск не может быть смонтирован для записи. Если вы специально выключили компьютер таким образом, то перезагрузитесь и выключите без гибернация или быстрого запуска.

Но это может не помочь, поскольку последние версии Windows делают гибернацию автоматически, без ведома пользователя.

<div class="c88083470404aeda508e60e32ee4c3c6" data-index="4" id="bkmrk--3"><ins class="adsbygoogle" data-ad-client="ca-pub-7219829351026140" data-ad-format="auto" data-ad-slot="2409866113"></ins>  
</div>### Гибернация Windows и быстрый перезапуск  


На компьютерах, на которых возможна двойная загрузка в Windows или Linux, Windows должна быть полностью выключена перед загрузкой в Linux, в противном случае файловые системы NTFS на внутренних дисках могут остаться в несогласованном состоянии, а изменения, сделанные Linux, могут быть проигнорированы Windows.

Таким образом, Windows нельзя оставлять в режиме гибернации при запуске Linux, чтобы избежать несоответствий. Кроме того, необходимо отключить функцию быстрого перезапуска, доступную в последних системах Windows. Этого можно добиться, выполнив в качестве администратора команду Windows, которая отключает как гибернацию, так и быстрый перезапуск, а также удаляет файл **hiberfile**:

<div id="bkmrk-1-powercfg-%2Fh-off"><div class="syntaxhighlighter  bash" id="bkmrk-1-powercfg-%2Fh-off-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`powercfg ``/h` `off`</div></div></td></tr></tbody></table>

</div></div>Если вы не хотите отключать гибернацию, то для одноразового выключения компьютера Windows без гибернация выключите его командой:

<div id="bkmrk-1-shutdown-%2Fs-%2Ft-0"><div class="syntaxhighlighter  bash" id="bkmrk-1-shutdown-%2Fs-%2Ft-0-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`shutdown` `/s` `/t` `0`</div></div></td></tr></tbody></table>

</div></div>### Удаление файла гибернации  


Когда том NTFS находится в спящем режиме, монтирование для чтения и записи запрещается, и том принудительно монтируется только для чтения. Необходимо либо возобновить работу Windows и правильно её выключить, либо использовать опцию **remove\_hiberfile**, которая удалит файл гибернации Windows. Обратите внимание, это означает, что сохранённый сеанс Windows будет полностью утерян, но сама Windows не пострадает. Напомним, что в файле гибернация хранится содержимое оперативной памяти на момент выключения. Кстати, именно поэтому размер файла гибернация равен размеру оперативной памяти компьютера. Используйте эту опцию под свою ответственность.

Пример команды с указанием опции **remove\_hiberfile**:

<div id="bkmrk-1-sudo-mount--t-ntfs"><div class="syntaxhighlighter  bash" id="bkmrk-1-sudo-mount--t-ntfs-1"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2">`sudo` `mount` `-t ntfs-3g -o remove_hiberfile ``/dev/sda2` `/mnt/spide`</div></div></td></tr></tbody></table>

</div></div><div class="c88083470404aeda508e60e32ee4c3c6" data-index="2" id="bkmrk--4"><ins class="adsbygoogle" data-ad-client="ca-pub-7219829351026140" data-ad-format="auto" data-ad-slot="3918354044" data-full-width-responsive="true"></ins>  
</div><div id="bkmrk--5">  
</div>Спасибо, что поделились решением! Вы абсолютно правы — `ntfsfix` действительно может решить эту проблему во многих случаях.

\## Ваше решение

```bash  
ntfsfix /dev/da0s1  
```

После этого можно монтировать как обычно:  
```bash  
mount /dev/da0s1 /data/ntfs  
```

\## Что делает `ntfsfix`

Утилита `ntfsfix` (из пакета `ntfs-3g`) исправляет некоторые распространённые проблемы NTFS:

1\. \*\*Сбрасывает "грязный" флаг\*\* (`dirty` flag) — тот самый флаг, который Windows оставляет после гибернации или быстрого запуска  
2\. \*\*Восстанавливает журнал\*\* ($LogFile)  
3\. \*\*Проверяет основные структуры\*\* NTFS

\## Важное предупреждение

`ntfsfix` \*\*не является полноценной заменой\*\* `chkdsk` из Windows. Он:  
\- ✅ Убирает блокировку и позволяет монтировать раздел в режиме чтения-записи  
\- ⚠️ \*\*Не проверяет\*\* и не восстанавливает содержимое файлов  
\- ⚠️ Может замаскировать проблемы с файловой системой

\## Как установить

```bash  
pkg install ntfs-3g  
```

\## Когда `ntfsfix` работает, а когда нет

| Ситуация | ntfsfix поможет |  
|----------|----------------|  
| Гибернация Windows | ✅ Да |  
| Быстрый запуск Windows | ✅ Да |  
| Корректно выключенная Windows | ❌ Не нужен |  
| Повреждённая MFT (Master File Table) | ❌ Нет, нужен `chkdsk /f` |  
| Ошибки файловой системы | ❌ Нет, нужен `chkdsk` |

\## Безопасная альтернатива

Если нет уверенности в целостности файловой системы:  
```bash  
\# Монтирование только для чтения (безопасно)  
mount -t ntfs -o ro /dev/da0s1 /data/ntfs

\# Или с ntfsfix (разблокирует, но рискованно)  
ntfsfix /dev/da0s1 &amp;&amp; mount /dev/da0s1 /data/ntfs  
```

\*\*Запомнили:\*\* `ntfsfix` — быстрое решение для разблокировки NTFS-раздела после Windows. Спасибо за совет!

# How to Install Apache, MySQL, PHP (FAMP Stack) on FreeBSD 14.0

## Introduction

FreeBSD, Apache, MySQL, and PHP (FAMP stack) is a collection of open-source software applications that manage the runtime and development of dynamic web applications on a server. Apache works as a web server to delivers web application files while MySQL functions as the database backend, and PHP processes dynamic web application contents.

This article explains how to install the Apache, MySQL, and PHP (FAMP) stack on FreeBSD 14.0 and deliver dynamic web applications on your server.

## Prerequisites

Before you begin:

- Deploy a [FreeBSD 14.0](https://www.vultr.com/servers/freebsd) instance on Vultr.
- Create a new [domain **A** record pointing to the instance IP address](https://docs.vultr.com/introduction-to-vultr-dns). For example, `app.example.com`.
- Access the server [using SSH](https://docs.vultr.com/how-to-use-ssh-with-vultr-servers).
- Create a non-root user with sudo privileges and switch to the user.
- [Update the server](https://docs.vultr.com/how-to-update-a-vultr-cloud-server).

## Install Apache

Apache is available in the default repositories on FreeBSD 14.0 with the latest package information. Follow the steps below to install the latest Apache web server package and enable the application to run on your server.

1. Update the server packages catalog.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-1">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg update
    ```
    
    <div class="code-block"><div id="bkmrk-"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-1">Explain Code</button></div>
2. Install Apache on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-2">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg install -y apache24
    ```
    
    <div class="code-block"><div id="bkmrk--1"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-2">Explain Code</button></div>
3. Verify that Apache is installed on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-3">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ apachectl -v
    ```
    
    <div class="code-block"><div id="bkmrk--2"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-3">Explain Code</button></div>Output:
    
    ```
    Server version: Apache/2.4.59 (FreeBSD)
    Server built:   unknown
    ```
4. Enable Apache to automatically start at boot.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-4">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 enable
    ```
    
    <div class="code-block"><div id="bkmrk--3"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-4">Explain Code</button></div>
5. Start the Apache web server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-5">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 start
    ```
    
    <div class="code-block"><div id="bkmrk--4"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-5">Explain Code</button></div>
6. View the Apache service status and verify that the web server is running.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-6">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 status
    ```
    
    <div class="code-block"><div id="bkmrk--5"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-6">Explain Code</button></div>Output:
    
    ```
    apache24 is running as pid 2536.
    ```
7. Access your server IP address using a web browser such as Chrome and verify that the default Apache virtual host web page displays.
    
    ```
    http://SERVER-IP
    ```
    
    ![Default Apache webpage](https://docs.vultr.com/public/doc-assets/1873/417147e3ea214c4e.png)

## Install MySQL

MySQL is available in the default FreeBSD 14.0 repositories with multiple versions. Follow the steps below to install the latest MySQL database server version and enable it to run on your server.

1. Search all MySQL versions available in the default FreeBSD repositories.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-7">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg search mysql
    ```
    
    <div class="code-block"><div id="bkmrk--6"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-7">Explain Code</button></div>Output:
    
    ```
    ...
    mysql80-client-8.0.35          Multithreaded SQL database (client)
    mysql80-server-8.0.35_1        Multithreaded SQL database (server)
    mysql81-client-8.1.0           Multithreaded SQL database (client)
    mysql81-server-8.1.0           Multithreaded SQL database (server)
    ...
    ```
2. Install the latest MySQL server and client packages.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-8">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg install mysql81-server mysql81-client
    ```
    
    <div class="code-block"><div id="bkmrk--7"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-8">Explain Code</button></div>
3. View the installed MySQL version on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-9">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ mysql --version
    ```
    
    <div class="code-block"><div id="bkmrk--8"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-9">Explain Code</button></div>Output:
    
    ```
    mysql  Ver 8.1.0 for FreeBSD14.0 on amd64 (Source distribution)
    ```
4. Enable the MySQL server to automatically start at boot.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-10">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service mysql enable
    ```
    
    <div class="code-block"><div id="bkmrk--9"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-10">Explain Code</button></div>Output:
    
    ```
    mysql enabled in /etc/rc.conf
    ```
5. Start the MySQL database server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-11">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service mysql-server start
    ```
    
    <div class="code-block"><div id="bkmrk--10"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-11">Explain Code</button></div>
6. View the MySQL server status and verify that it's running.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-12">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service mysql-server status
    ```
    
    <div class="code-block"><div id="bkmrk--11"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-12">Explain Code</button></div>Output:
    
    ```
    mysql is running as pid 3266.
    ```
7. Start the MySQL secure installation script.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-13">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo mysql_secure_installation
    ```
    
    <div class="code-block"><div id="bkmrk--12"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-13">Explain Code</button></div>
    - Enter <kbd class="key">Y</kbd> when prompted to enable the **VALIDATE PASSWORD** component and set strict password policies on the database server.
    
    ```
    VALIDATE PASSWORD COMPONENT can be used to test passwords
    and improve security. It checks the strength of password
    and allows the users to set only those passwords which are
    secure enough. Would you like to setup VALIDATE PASSWORD component?
    
    Press y|Y for Yes, any other key for No: Y
    ```
    
    
    - Enter your desired password strength level to enable on your server. For example, enter <kbd class="key">2</kbd> to require strong passwords with mixed characters.
    
    ```
    There are three levels of password validation policy:
    
    LOW    Length >= 8
    MEDIUM Length >= 8, numeric, mixed case, and special characters
    STRONG Length >= 8, numeric, mixed case, special characters and dictionary        file
    
    Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG:
    ```
    
    
    - Enter a new strong password to assign the `root` database user.
    
    ```
    Please set the password for root here.
    
    New password: 
    ```
    
    
    - Repeat the password and verify the estimated password strength.
    
    ```
    Re-enter new password: 
    
    Estimated strength of the password: 8
    ```
    
    
    - Enter <kbd class="key">Y</kbd> when prompted to validate and continue with the new user password.
    
    ```
    Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : 
    ```
    
    
    - Enter <kbd class="key">Y</kbd> and press <kbd class="key">Enter</kbd> to remove anonymous database users on your server.
    
    ```
    Remove anonymous users? (Press y|Y for Yes, any other key for No) : 
    ```
    
    
    - Enter <kbd class="key">Y</kbd> when prompted to disable remote access to your database server using the root user account.
    
    ```
    Disallow root login remotely? (Press y|Y for Yes, any other key for No) : 
    ```
    
    
    - Enter <kbd class="key">Y</kbd> when prompted to remove the test databases on your server.
    
    ```
    `Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 
    ```
    
    
    - Enter <kbd class="key">Y</kbd> and press <kbd class="key">Enter</kbd> to reload the MySQL privilege tables and apply your configuration changes.
    
    ```
    Reload privilege tables now? (Press y|Y for Yes, any other key for No) : 
    ```
8. Restart the MySQL database server to apply changes.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-14">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service mysql-server restart
    ```
    
    <div class="code-block"><div id="bkmrk--13"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-14">Explain Code</button></div>

## Install PHP and Configure PHP-FPM

PHP is available in the default FreeBSD repositories and includes the PHP-FPM package that manages connection requests using pool configurations on your server. Follow the steps below to install the latest PHP version on your server.

1. Search all available PHP packages in the default FreeBSD repositories.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-15">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ pkg search php | egrep '^php[0-9]+-[0-9]'
    ```
    
    <div class="code-block"><div id="bkmrk--14"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-15">Explain Code</button></div>Output:
    
    ```
    php81-8.1.29                   PHP Scripting Language (8.1.X branch)
    php82-8.2.18                   PHP Scripting Language (8.2.X branch)
    php83-8.3.6                    PHP Scripting Language (8.3.X branch)
    ```
2. Install the latest PHP package. For example, PHP version `8.3`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-16">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo apt install php83
    ```
    
    <div class="code-block"><div id="bkmrk--15"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-16">Explain Code</button></div>
3. Install common PHP modules required to enable application functionalities.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-17">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg install -y  php83-mysqli php83-curl php83-zip php83-gd php83-xml php83-mbstring
    ```
    
    <div class="code-block"><div id="bkmrk--16"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-17">Explain Code</button></div>
4. View the installed PHP version on your server..
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-18">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ php -v
    ```
    
    <div class="code-block"><div id="bkmrk--17"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-18">Explain Code</button></div>Output:
    
    ```
    PHP 8.3.6 (cli) (built: Jun 20 2024 02:08:30) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.3.6, Copyright (c) Zend Technologies
    ```
5. View the installed PHP-FPM version on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-19">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ php-fpm -v
    ```
    
    <div class="code-block"><div id="bkmrk--18"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-19">Explain Code</button></div>Output:
    
    ```
    PHP 8.3.6 (fpm-fcgi) (built: Jun 20 2024 02:08:43)
    Copyright (c) The PHP Group
    Zend Engine v4.3.6, Copyright (c) Zend Technologies
    ```
6. Enable PHP-FPM to automatically start at boot.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-20">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service php-fpm enable
    ```
    
    <div class="code-block"><div id="bkmrk--19"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-20">Explain Code</button></div>
7. View the PHP-FPM service status and verify that it's running.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-21">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service php-fpm status
    ```
    
    <div class="code-block"><div id="bkmrk--20"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-21">Explain Code</button></div>Output:
    
    ```
    php_fpm is running as pid 2558.
    ```

## Configure Apache with PHP-FPM

Apache uses the `mod_proxy` and `mod_proxy_fcgi` modules to process FastCGI requests and connect to the PHP-FPM service. Follow the steps below to enable the required Apache modules and forward all PHP application requests to the PHP-FPM service port `9000`.

1. Open the default PHP-FPM pool configuration file using a text editor such as the Easy Editor (`ee`).
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-22">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo ee /usr/local/etc/php-fpm.d/www.conf
    ```
    
    <div class="code-block"><div id="bkmrk--21"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-22">Explain Code</button></div>
    - Find the `user` and `group` directives and verify that PHP-FPM runs with the web server user profile `www`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">ini</span><button class="copy-button" data-code-id="code-block-23">Copy</button></div><div><div class="highlight"></div></div></div>```
    user = www
    group = www
    ```
    
    <div class="code-block"><div id="bkmrk--22"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-23">Explain Code</button></div>
    - Find the `listen` directive and verify that PHP-FPM listens for connection requests on the localhost port `9000`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">ini</span><button class="copy-button" data-code-id="code-block-24">Copy</button></div><div><div class="highlight"></div></div></div>```
    listen = 127.0.0.1:9000
    ```
    
    <div class="code-block"><div id="bkmrk--23"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-24">Explain Code</button></div>Save and close the file.
2. Run the following command to enable the `mod_proxy` and `mod_proxy_fcgi` Apache modules on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-25">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo sed -i '' -e 's/^#LoadModule proxy_module libexec\/apache24\/mod_proxy.so/LoadModule proxy_module libexec\/apache24\/mod_proxy.so/' -e 's/^#LoadModule proxy_fcgi_module libexec\/apache24\/mod_proxy_fcgi.so/LoadModule proxy_fcgi_module libexec\/apache24\/mod_proxy_fcgi.so/' /usr/local/etc/apache24/httpd.conf
    ```
    
    <div class="code-block"><div id="bkmrk--24"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-25">Explain Code</button></div>The above command uncomments the following Apache configuration directives to enable the modules on your server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">apacheconf</span><button class="copy-button" data-code-id="code-block-26">Copy</button></div><div><div class="highlight"></div></div></div>```
    LoadModule proxy_module libexec/apache24/mod_proxy.so
    LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so
    ```
    
    <div class="code-block"><div id="bkmrk--25"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-26">Explain Code</button></div>
3. Open the main Apache configuration file.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-27">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo ee /usr/local/etc/apache24/httpd.conf
    ```
    
    <div class="code-block"><div id="bkmrk--26"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-27">Explain Code</button></div>
4. Add the following configurations at the end of the file to forward all PHP file requests to the PHP-FPM port `9000`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">apacheconf</span><button class="copy-button" data-code-id="code-block-28">Copy</button></div><div><div class="highlight"></div></div></div>```
    <FilesMatch "\.php$">
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
    ```
    
    <div class="code-block"><div id="bkmrk--27"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-28">Explain Code</button></div>Save and close the file.
5. Test the Apache configuration for errors.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-29">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo apachectl configtest
    ```
    
    <div class="code-block"><div id="bkmrk--28"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-29">Explain Code</button></div>Your output should look like the one below when the test is successful:
    
    ```
    Performing sanity check on apache24 configuration:
    AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
    Syntax OK
    ```
6. Restart PHP-FPM to apply changes.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-30">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service php-fpm restart
    ```
    
    <div class="code-block"><div id="bkmrk--29"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-30">Explain Code</button></div>
7. Restart Apache to apply the configuration changes.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-31">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 restart
    ```
    
    <div class="code-block"><div id="bkmrk--30"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-31">Explain Code</button></div>

## Test the Installation

1. Log in to the MySQL database server using the `root` user and password you set earlier.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-32">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ mysql -u root -p
    ```
    
    <div class="code-block"><div id="bkmrk--31"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-32">Explain Code</button></div>
2. Create a new sample database `exampledb`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-33">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> create database exampledb;
    ```
    
    <div class="code-block"><div id="bkmrk--32"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-33">Explain Code</button></div>
3. Create a new database user such as `dbadmin` with a strong password.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-34">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> create user 'dbadmin'@'localhost' IDENTIFIED BY 'strong@@password25Bb';
    ```
    
    <div class="code-block"><div id="bkmrk--33"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-34">Explain Code</button></div>
4. Grant the `dbadmin` user full privileges to the `exampledb` database.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-35">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> GRANT ALL PRIVILEGES ON exampledb.* TO 'dbadmin'@'localhost';
    ```
    
    <div class="code-block"><div id="bkmrk--34"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-35">Explain Code</button></div>
5. Flush the MySQL privileges table to apply changes.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-36">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> FLUSH PRIVILEGES;
    ```
    
    <div class="code-block"><div id="bkmrk--35"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-36">Explain Code</button></div>
6. Switch to the sample database `exampledb`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-37">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> use exampledb;
    ```
    
    <div class="code-block"><div id="bkmrk--36"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-37">Explain Code</button></div>
7. Create a new sample table `exampletable` with the following columns to store integer and string values.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-38">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> CREATE TABLE exampletable (id INT AUTO_INCREMENT PRIMARY KEY, messages VARCHAR(255) NOT NULL);
    ```
    
    <div class="code-block"><div id="bkmrk--37"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-38">Explain Code</button></div>The above SQL statement creates a new table with the columns: `id` that stores numeric data, and `messages` that stores mixed characters.
8. Insert sample data into the table. For example, `Greetings from Vultr`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-39">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> INSERT INTO exampletable (messages) VALUES ('Greetings from Vultr');
    ```
    
    <div class="code-block"><div id="bkmrk--38"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-39">Explain Code</button></div>
9. Exit the MySQL database console.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">sql</span><button class="copy-button" data-code-id="code-block-40">Copy</button></div><div><div class="highlight"></div></div></div>```
    mysql> EXIT;
    ```
    
    <div class="code-block"><div id="bkmrk--39"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-40">Explain Code</button></div>
10. Create a new directory to store your web application files. For example, `app.example.com` in the default Apache web root path.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-41">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo mkdir -p /usr/local/www/apache24/app.example.com
    ```
    
    <div class="code-block"><div id="bkmrk--40"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-41">Explain Code</button></div>
11. Create a new sample PHP application file in the directory. For example, `index.php`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-42">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo ee /usr/local/www/apache24/app.example.com/index.php
    ```
    
    <div class="code-block"><div id="bkmrk--41"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-42">Explain Code</button></div>
12. Add the following contents to the file.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">php</span><button class="copy-button" data-code-id="code-block-43">Copy</button></div><div><div class="highlight"></div></div></div>```
    <?php
    $servername = "localhost";
    $username = "dbadmin";
    $password = "strong@@password25Bb";
    $dbname = "exampledb";
    
    // Connect to the MySQL database
    $conn = new mysqli($servername, $username, $password, $dbname);
    
    // Test the MySQL database connection
    if ($conn->connect_error) {
        die("Database Connection Failed." . $conn->connect_error);
    }
    
    // Fetch a string from exampletable
    $sql = "SELECT messages FROM exampletable";
    $result = $conn->query($sql);
    
    if ($result->num_rows > 0) {
        $row = $result->fetch_assoc();
        echo "<h1 align='center'> <br> <br>" . $row["messages"]. "</h1>";
    
    } else {
        echo "<h1 align='center'> <br> No Data Found.</h1>";
    }
    
    $conn->close();
    ?>
    ```
    
    <div class="code-block"><div id="bkmrk--42"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-43">Explain Code</button></div>Save the file and exit the text editor.
    
    The above PHP application connects to the MySQL database server and queries the `exampledb` database to output values in the `exampledata` column within the `messages` table. The application displays a `Greetings from Vultr` heading when successful or `No Data Found` when unsuccessful.
13. Create a new Apache virtual host configuration file. For example, `app.example.com.conf`.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-44">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo ee /usr/local/etc/apache24/Includes/app.example.com.conf
    ```
    
    <div class="code-block"><div id="bkmrk--43"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-44">Explain Code</button></div>
14. Add the following configurations to the file.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">apacheconf</span><button class="copy-button" data-code-id="code-block-45">Copy</button></div><div><div class="highlight"></div></div></div>```
    <VirtualHost *:80>
        ServerAdmin webmaster@yourdomain.com
        DocumentRoot "/usr/local/www/apache24/app.example.com/"
        ServerName app.example.com
    
        <Directory "/usr/local/www/apache24/app.example.com/">
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
            DirectoryIndex index.php index.html
    
        </Directory>
    
        ErrorLog "/var/log/app.example.com-error.log"
    </VirtualHost>
    ```
    
    <div class="code-block"><div id="bkmrk--44"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-45">Explain Code</button></div>Save the file and exit the text editor.
    
    The above Apache configuration creates a new virtual host that listens for connections using the domain `app.example.com` on the default HTTP port `80`. All PHP requests are forwarded to PHP-FPM on the host port `9000` applied in your main Apache configuration.
15. Test the Apache configuration for errors.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-46">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo apachectl configtest
    ```
    
    <div class="code-block"><div id="bkmrk--45"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-46">Explain Code</button></div>Output:
    
    ```
    Performing sanity check on apache24 configuration:
    AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
    Syntax OK
    ```
16. Restart Apache to apply the new virtual host configuration.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-47">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 restart
    ```
    
    <div class="code-block"><div id="bkmrk--46"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-47">Explain Code</button></div>
17. Access your domain using a web browser and verify that you can access the PHP web application.
    
    ```
    http://app.example.com
    ```
    
    ![A Sample PHP web application](https://docs.vultr.com/public/doc-assets/1873/0c0771b0137320db.png)

### Secure the Server

1. Install the Certbot Let's Encrypt client for Apache.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-48">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pkg install py39-certbot-apache
    ```
    
    <div class="code-block"><div id="bkmrk--47"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-48">Explain Code</button></div>
2. Run the following commands to enable the Apache `mod_rewrite` and `mod_ssl` modules to allow SSL configurations on your web server.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-49">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo sed -i '' 's/#LoadModule rewrite_module libexec\/apache24\/mod_rewrite.so/LoadModule rewrite_module libexec\/apache24\/mod_rewrite.so/' /usr/local/etc/apache24/httpd.conf
    
    $ sudo sed -i '' 's/#LoadModule ssl_module libexec\/apache24\/mod_ssl.so/LoadModule ssl_module libexec\/apache24\/mod_ssl.so/' /usr/local/etc/apache24/httpd.conf
    ```
    
    <div class="code-block"><div id="bkmrk--48"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-49">Explain Code</button></div>The above commands uncomment and enable the following directives in the `/usr/local/etc/apache24/httpd.conf` Apache configuration file:
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">apacheconf</span><button class="copy-button" data-code-id="code-block-50">Copy</button></div><div><div class="highlight"></div></div></div>```
    LoadModule ssl_module libexec/apache24/mod_ssl.so
    LoadModule rewrite_module libexec/apache24/mod_rewrite.so
    ```
    
    <div class="code-block"><div id="bkmrk--49"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-50">Explain Code</button></div>
3. Generate a new SSL certificate for your domain. Replace `app.example.com` with your actual domain.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-51">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo certbot --apache -d app.example.com --agree-tos
    ```
    
    <div class="code-block"><div id="bkmrk--50"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-51">Explain Code</button></div>
4. Test the Certbot SSL certificate automatic renewal process.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-52">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo certbot renew --dry-run
    ```
    
    <div class="code-block"><div id="bkmrk--51"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-52">Explain Code</button></div>Output:
    
    ```
    Account registered.
    Simulating renewal of an existing certificate for app.example.com
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Congratulations, all simulated renewals succeeded: 
      /usr/local/etc/letsencrypt/live/app.example.com/fullchain.pem (success)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ```
5. Restart Apache to apply your SSL configuration changes.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-53">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo service apache24 restart
    ```
    
    <div class="code-block"><div id="bkmrk--52"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-53">Explain Code</button></div>
6. Create a new Packet Filter (`pf`) firewall configuration.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-54">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo ee /etc/pf.conf
    ```
    
    <div class="code-block"><div id="bkmrk--53"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-54">Explain Code</button></div>
7. Add the following configurations to the file. Replace `vtnet0` with your public server interface name.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">ini</span><button class="copy-button" data-code-id="code-block-55">Copy</button></div><div><div class="highlight"></div></div></div>```
    ext_interface = "vtnet0"            # The external server interface
    
    pass quick on lo0 all      # Allow all connections on the loopback interface
    
    # Filter rules
    block in all                # Block incoming unpermitted traffic
    pass out all keep state     # Allow outgoing traffic
    
    pass in on $ext_interface proto tcp from any to any port 22 keep state  # Allow SSH
    pass in on $ext_interface proto tcp from any to any port 80 keep state  # Allow HTTP
    pass in on $ext_interface proto tcp from any to any port 443 keep state # Allow HTTPS
    ```
    
    <div class="code-block"><div id="bkmrk--54"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-55">Explain Code</button></div>Save the file and exit the text editor.
    
    The above firewall configuration enables network connections to the SSH port `22`, HTTP port `80`, and the HTTPS port `443`. In addition, the firewall blocks any other network connections to other ports on your server.
8. Enable the firewall to automatically start at boot.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-56">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo sysrc pf_enable="YES"
    ```
    
    <div class="code-block"><div id="bkmrk--55"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-56">Explain Code</button></div>Output:
    
    ```
    pf_enable: NO -> YES
    ```
9. Load your firewall configuration.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-57">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pfctl -f /etc/pf.conf
    ```
    
    <div class="code-block"><div id="bkmrk--56"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-57">Explain Code</button></div>
10. Start the Packet Filter firewall.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-58">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pfctl -e
    ```
    
    <div class="code-block"><div id="bkmrk--57"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-58">Explain Code</button></div>Output:
    
    ```
    pf enabled
    ```
11. View all firewall rules and verify that your SSH, HTTP, and HTTPS ports are available.
    
    <div class="code-block"><div class="code-heading"><span class="lexer-name">console</span><button class="copy-button" data-code-id="code-block-59">Copy</button></div><div><div class="highlight"></div></div></div>```
    $ sudo pfctl -sr
    ```
    
    <div class="code-block"><div id="bkmrk--58"><div class="highlight"></div></div><button class="explain-button" data-code-id="code-block-59">Explain Code</button></div>Output:
    
    ```
    pass quick on lo0 all flags S/SA keep state
    block drop in all
    pass in on vtnet0 proto tcp from any to any port = ssh flags S/SA keep state
    pass in on vtnet0 proto tcp from any to any port = http flags S/SA keep state
    pass in on vtnet0 proto tcp from any to any port = https flags S/SA keep state
    pass out all flags S/SA keep state
    ```
12. Access your domain using HTTPS to verify that your SSL certificate is valid and encrypted by the Apache web server.
    
    ```
    https://app.example.com
    ```

## Conclusion

You have successfully installed the Apache, MySQL, and PHP (FAMP) stack on your FreeBSD 14.0 server. All applications in the stack run collectively on the server to deliver dynamic web applications. You can configure the Apache web server and set up MySQL databases to securely deliver web applications or frameworks such as WordPress on your server.

# Ошибка Permission denied указывает на то, что процесс OpenDKIM

Ошибка `Permission denied` указывает на то, что процесс OpenDKIM не может прочитать ваш приватный ключ, потому что файл принадлежит не тому пользователю.

На FreeBSD стандартным пользователем для OpenDKIM является `mailnull`, а не `opendkim`.

### 🛠️ Пошаговое решение

Вот три последовательных шага, которые гарантированно исправят проблему. Выполните их от root.

**1️⃣ Правильный владелец файла и каталогов**  
Самый важный шаг — изменить владельца для всего, что касается DKIM, на пользователя и группу `mailnull`.

<div class="md-code-block md-code-block-light" id="bkmrk-bash"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">bash</span></div></div></div></div></div>```
chown -R mailnull:mailnull /var/db/dkim
```

**2️⃣ Безопасные права доступа**  
Вы уже делали эту часть ранее, но лучше повторить, чтобы исключить ошибку. Это даст OpenDKIM возможность читать ключ и заходить в каталог.

<div class="md-code-block md-code-block-light" id="bkmrk-bash-1"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">bash</span></div></div></div></div></div>```
chmod 0600 /var/db/dkim/ip-mail.ru/myselector.private
chmod 0750 /var/db/dkim
chmod 0750 /var/db/dkim/ip-mail.ru
```

**3️⃣ Перезапуск сервисов**  
Чтобы все изменения вступили в силу.

<div class="md-code-block md-code-block-light" id="bkmrk-bash-2"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">bash</span></div></div></div></div></div>```
service milter-opendkim restart
service sendmail restart   # или service postfix restart, если он у вас
```

### 💡 Почему это важно

- **Пользователь по умолчанию**: В отличие от многих других систем, где OpenDKIM часто запускается от собственного пользователя `opendkim`, в портах FreeBSD по умолчанию используется `mailnull`.
- **Безопасность**: OpenDKIM намеренно требователен к правам доступа и откажется загружать ключ, если он доступен кому-то ещё, кроме владельца.

После выполнения этих шагов выполните команду `tail -f /var/log/maillog` и попробуйте отправить тестовое письмо. Ошибка `Permission denied` должна исчезнуть.

Если проблема сохранится, проверьте еще одну вещь: в некоторых версиях требуется также явно указать пользователя в настройках. Убедитесь, что в файле `/etc/rc.conf` есть следующие строки:

<div class="md-code-block md-code-block-light" id="bkmrk-sh"><div class="md-code-block-banner-wrap"><div class="md-code-block-banner md-code-block-banner-lite"><div class="_121d384"><div class="d2a24f03"><span class="d813de27">sh</span></div></div></div></div></div>```
milteropendkim_uid="mailnull"
milteropendkim_gid="mailnull"
```

# Как установить Suricata на FreeBSD

<header class="entry-header" id="bkmrk-7-%D1%84%D0%B5%D0%B2%D1%80%D0%B0%D0%BB%D1%8F-2020-%D0%B3%D0%BE%D0%B4%D0%B0%C2%A0"><time class="entry-time">7 февраля 2020 года</time> от <span class="entry-author">[<span class="entry-author-name">Альберта Вальбуэны</span>](https://www.adminbyaccident.com/author/bert/)</span>

</header>![](https://www.adminbyaccident.com/wp-content/uploads/2020/02/Suricata-1024x609.png)

[Suricata](https://suricata-ids.org/) — это бесплатная система обнаружения вторжений с открытым исходным кодом, или [сокращённо IDS](https://en.wikipedia.org/wiki/Intrusion_detection_system). Но она также может выступать в качестве системы предотвращения вторжений, или [IPS](https://en.wikipedia.org/wiki/Intrusion_detection_system#Intrusion_prevention). Она работает на основе эвристических алгоритмов, выявляющих закономерности в сетевом трафике. Если система настроена только на предупреждение о подозрительной активности, она называется IDS, а если она блокирует трафик из-за вредоносной активности, то IPS. Suricata обычно устанавливается в качестве плагина в [pfSense](https://www.pfsense.org/) — полноценный брандмауэр и сетевой дистрибутив корпоративного уровня с открытым исходным кодом на базе FreeBSD. Если вы используете FreeBSD в качестве настольной системы, вот руководство по [тестированию pfSense в VirtualBox](https://www.adminbyaccident.com/network/how-to-test-pfsense-on-virtualbox-running-on-freebsd/). Однако вы можете использовать Suricata как отдельное программное обеспечение для анализа сетевого трафика.

**Если статьи на Adminbyaccident.com оказались для вас полезными, [пожалуйста, подумайте о том, чтобы сделать пожертвование](https://www.adminbyaccident.com/donate/).**

**[Воспользуйтесь этой ссылкой](https://m.do.co/c/4fa90eef5203), чтобы получить кредит на 200 долларов в DigitalOcean и поддержать расходы на Adminbyaccident.com.**

**Получите 100 долларов в подарок от Vultr по [этой ссылке](https://www.vultr.com/?ref=9526682) и поддержите расходы на Adminbyaccident.com.**

**Обратите внимание, что Vultr поддерживает FreeBSD в рамках своего предложения по VPS.**

Что касается требований к установке Suricata, то их немного. Вы можете использовать ее на том же сервере, на котором работает веб-сервер, но гораздо интереснее использовать ее вместе с брандмауэром, защищающим офис ([локальная сеть](https://en.wikipedia.org/wiki/Local_area_network)) или даже компанию с несколькими филиалами ([глобальная сеть](https://en.wikipedia.org/wiki/Wide_area_network)). Если вы решите использовать ее для защиты глобальной сети, то вам практически обязательно понадобится сервер или устройство с двумя [сетевыми интерфейсами](https://en.wikipedia.org/wiki/Network_interface_controller). Конечно, если вы планируете защищать компанию среднего или крупного размера, то чем больше сетевых адаптеров, тем лучше, хотя вы также можете рассмотреть вариант с [оборудованием Netgate](https://www.netgate.com/), на котором уже установлен pfSense. Что бы вы ни использовали, обязательным условием является [зеркальное отображение трафика](https://en.wikipedia.org/wiki/Port_mirroring) на устройстве, на котором вы собираетесь использовать Suricata, если вы запускаете ее параллельно с другими устройствами. Обычно это означает, что нужно подключить кабель от коммутатора или брандмауэра к устройству Suricata и настроить зеркалирование портов. Если вы хотите использовать его на том же веб-сервере, что и раньше, то можете это сделать, но, скорее всего, вам больше подойдет [HIDS](https://en.wikipedia.org/wiki/Host-based_intrusion_detection_system) (система обнаружения вторжений на уровне хоста).

Но зачем все это? Возможно, вам не нужна эта система обнаружения вторжений, но если у вас небольшой офис, то установка межсетевого экрана pfSense с пакетом Suricata (напомним, что pfSense полностью основан на FreeBSD) станет дополнительным уровнем безопасности. Опять же, для веб-сервера это не очень полезно, если только это не очень популярный веб-сервер и от него не зависит компания из 15 человек. В таком случае это программное обеспечение поможет защитить сеть, для чего оно и предназначено. Вопрос в том, как отображаются оповещения Suricata. Такое программное обеспечение обычно используется в средних и крупных организациях (опять же, в небольших компаниях можно использовать pfSense или нанять кого-то, кто сделает всю работу за вас). Обычно оповещения записываются в системный журнал и пересылаются в [SIEM](https://en.wikipedia.org/wiki/Security_information_and_event_management), специализированное программное обеспечение для анализа инцидентов. SIEM с открытым исходным кодом — это [OSSIM](https://en.wikipedia.org/wiki/OSSIM). Но поверх Suricata можно установить стек ELK, который добавит графические возможности и позволит легко работать с оповещениями без необходимости установки SIEM. Об этом мы расскажем в одной из статей в этом году.

Для демонстрации мы используем виртуальную машину DigitalOcean, но вы можете использовать любой VPS по своему выбору или просто физическое оборудование. Учитывайте размер устройства или виртуальной машины, которые вы планируете использовать в производственной среде, поскольку Suricata может потреблять довольно много ресурсов, особенно в загруженных сетях.

Сначала мы поищем пакет. Если у вас установлены последние версии пакетов из репозитория FreeBSD, то, скорее всего, вы найдете только Suricata 5. Однако если вы используете ежеквартальные обновления, то найдете Suricata версий 4.1.6 и 5. Выбирайте на свой вкус, но я обычно устанавливаю последнюю версию.

`[albert@VPN ~]$ pkg search suricata`

`suricata-5.0.1 High Performance Network IDS, IPS and Security Monitoring engine`

`suricata5-5.0.0.r1_2 High Performance Network IDS, IPS and Security Monitoring engine(v5)`

`[albert@VPN ~]$`

Найдя пакет, мы просто установим его. Если сомневаетесь, посетите [Freshports.org](https://www.freshports.org/), где можно найти всю необходимую информацию о программном обеспечении для FreeBSD.

`[albert@VPN ~]$ sudo pkg install suricata`

`Contrasenya:`

`Updating FreeBSD repository catalogue...`

`FreeBSD repository is up to date.`

`All repositories are up to date.`

`The following 8 package(s) will be affected (of 0 checked):`

`New packages to be INSTALLED:`

`suricata: 5.0.1`

`libyaml: 0.2.2`

`libnet: 1.1.6_5,1`

`python37: 3.7.6`

`py37-yaml: 5.2`

`py37-setuptools: 41.4.0_1`

`pcre: 8.43_2`

`jansson: 2.12`

`Number of packages to be installed: 8`

`The process will require 128 MiB more space.`

`20 MiB to be downloaded.`

`Proceed with this action? [y/N]: y`

`.........`

`.........`

`You may want to try BPF in zerocopy mode to test performance improvements:`

`sysctl -w net.bpf.zerocopy_enable=1`

`Don't forget to add net.bpf.zerocopy_enable=1 to /etc/sysctl.conf`

`[albert@VPN ~]$`

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

`=====`

`Message from suricata-5.0.1:`

`--`

`If you want to run Suricata in IDS mode, add to /etc/rc.conf:`

`suricata_enable="YES"`

`suricata_interface="<if>"`

`NOTE: Declaring suricata_interface is MANDATORY for Suricata in IDS Mode.`

`However, if you want to run Suricata in Inline IPS Mode in divert(4) mode,`

`add to /etc/rc.conf:`

`suricata_enable="YES"`

`suricata_divertport="8000"`

`NOTE:`

`Suricata won't start in IDS mode without an interface configured.`

`Therefore if you omit suricata_interface from rc.conf, FreeBSD's`

`rc.d/suricata will automatically try to start Suricata in IPS Mode`

`(on divert port 8000, by default).`

`Alternatively, if you want to run Suricata in Inline IPS Mode in high-speed`

`netmap(4) mode, add to /etc/rc.conf:`

`suricata_enable="YES"`

`suricata_netmap="YES"`

`NOTE:`

`Suricata requires additional interface settings in the configuration`

`file to run in netmap(4) mode.`

`RULES: Suricata IDS/IPS Engine comes without rules by default. You should`

`add rules by yourself and set an updating strategy. To do so, please visit:`

`http://www.openinfosecfoundation.org/documentation/rules.html`

`http://www.openinfosecfoundation.org/documentation/emerging-threats.html`

`You may want to try BPF in zerocopy mode to test performance improvements:`

`sysctl -w net.bpf.zerocopy_enable=1`

`Don't forget to add net.bpf.zerocopy_enable=1 to /etc/sysctl.conf`

Для начала выясним, какой у нас интерфейс, с помощью команды ifconfig. Поскольку это виртуальная машина FreeBSD DOcean по умолчанию, у нее только один интерфейс (не считая loop-интерфейса). Рекомендуется использовать один интерфейс для управления, а второй — для приема зеркалированного трафика с коммутатора или брандмауэра. Если по какой-то причине зеркалированный трафик превысит пропускную способность системы, у вас всегда будет запасной вариант. Для демонстрации мы будем использовать только один интерфейс, но мы вас предупредили. И вы это знаете.

`[albert@VPN ~]$ ifconfig`

`vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500`

`options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>`

`ether 2e:d3:db:28:6a:d8`

`inet6 fe80::2cd3:dbff:fe28:6ad8%vtnet0 prefixlen 64 scopeid 0x1`

`inet 142.93.75.244 netmask 0xfffff000 broadcast 142.93.79.255`

`inet 10.17.0.5 netmask 0xffff0000 broadcast 10.17.255.255`

`media: Ethernet 10Gbase-T <full-duplex>`

`status: active`

`nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>`

`lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384`

`options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>`

`inet6 ::1 prefixlen 128`

`inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2`

`inet 127.0.0.1 netmask 0xff000000`

`groups: lo`

`nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>`

`[albert@VPN ~]$`

Как мы видим, сетевой интерфейс здесь называется vtnet0. Давайте настроим этот интерфейс в режиме promiscuous. Зачем? Потому что мы хотим проверять сетевой трафик и хотим, чтобы каждый сетевой пакет проверялся полностью, а не только фреймы.

`[albert@VPN ~]$ sudo ifconfig vtnet0 promisc`

`[albert@VPN ~]$`

Чтобы проверить, что изменения вступили в силу, выполните следующую команду и найдите строку ‘promisc’.

`[albert@VPN ~]$ ifconfig vtnet0 | grep 'PROMISC'`

`vtnet0: flags=28943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,PPROMISC> metric 0 mtu 1500`

`[albert@VPN ~]$`

Вот и все, теперь интерфейс vtnet0 передает все полученные пакеты в ядро, где они будут проверены.

Теперь мы можем включить Suricata как службу и настроить ее для работы на интерфейсе vtnet0. Мы сделаем это с помощью команды [sysrc](https://www.freebsd.org/cgi/man.cgi?query=sysrc).

`[albert@VPN ~]$ sudo sysrc suricata_enable="YES"`

`suricata_enable: -> YES`

`[albert@VPN ~]$`

Теперь, когда служба добавлена, давайте настроим ее для работы на интерфейсе vtnet0.

`[albert@VPN ~]$ sudo sysrc suricata_interface="vtnet0"`

`suricata_interface: -> vtnet0`

`[albert@VPN ~]$`

Чтобы убедиться, что изменения внесены в файл /etc/rc.conf, просто введите следующую команду. Должны появиться две записи:

`[albert@VPN ~]$ grep -n 'suricata' /etc/rc.conf`

`46:suricata_enable="YES"`

`47:suricata_interface="vtnet0"`

`[albert@VPN ~]$`

Как видно выше, в строках 46 и 47 файла /etc/rc.conf указаны служба и интерфейс suricata.

Прежде чем мы запустим сервис и пакеты, проходящие через интерфейс, начнут проверяться, нужно настроить несколько параметров, таких как адрес электронной почты, на который будут приходить оповещения, расположение правил и ответы на некоторые другие вопросы о работе Suricata.

Suricata использует правила для проверки и работы в качестве системы обнаружения вторжений. Поэтому, если вы используете ее для защиты локальной сети, убедитесь, что в брандмауэре настроено правило для получения необходимых источников, иначе Suricata не сможет получать информацию и выполнять свою основную функцию. Правила находятся в следующем каталоге и файле:

`/var/lib/suricata`

`/var/lib/suricata/suricata.rules`

Правила также необходимо сортировать по приоритетам для уровней оповещений. Эта информация хранится в файле /usr/local/etc/suricata/classification.config. Следующий абзац взят из этого файла.

`# $Id$`

`# classification.config taken from Snort 2.8.5.3. Snort is governed by the GPLv2`

`#`

`# The following includes information for prioritizing rules`

`#`

`# Each classification includes a shortname, a description, and a default`

`# priority for that classification.`

`#`

`# This allows alerts to be classified and prioritized. You can specify`

`# what priority each classification has. Any rule can override the default`

`# priority for that rule.`

`#`

`# Here are a few example rules:`

`#`

`# alert TCP any any -> any 80 (msg: "EXPLOIT ntpdx overflow";`

`# dsize: > 128; classtype:attempted-admin; priority:10;`

`#`

`# alert TCP any any -> any 25 (msg:"SMTP expn root"; flags:A+; \`

`# content:"expn root"; nocase; classtype:attempted-recon;)`

`#`

`# The first rule will set its type to "attempted-admin" and override`

`# the default priority for that type to 10.`

`#`

`# The second rule set its type to "attempted-recon" and set its`

`# priority to the default for that type.`

`#`

`#`

`# config classification:shortname,short description,priority`

`#`

`config classification: not-suspicious,Not Suspicious Traffic,3`

`config classification: unknown,Unknown Traffic,3`

`config classification: bad-unknown,Potentially Bad Traffic, 2`

`config classification: attempted-recon,Attempted Information Leak,2`

`config classification: successful-recon-limited,Information Leak,2`

`config classification: successful-recon-largescale,Large Scale Information Leak,2`

Также есть справочный файл, в котором указаны URL-адреса источников информации.

`[albert@VPN /usr/local/etc/suricata]$ cat reference.config`

`# config reference: system URL`

`config reference: bugtraq http://www.securityfocus.com/bid/`

`config reference: bid http://www.securityfocus.com/bid/`

`config reference: cve http://cve.mitre.org/cgi-bin/cvename.cgi?name=`

`#config reference: cve http://cvedetails.com/cve/`

`config reference: secunia http://www.secunia.com/advisories/`

`#whitehats is unfortunately gone`

`config reference: arachNIDS http://www.whitehats.com/info/IDS`

`config reference: McAfee http://vil.nai.com/vil/content/v_`

`config reference: nessus http://cgi.nessus.org/plugins/dump.php3?id=`

`config reference: url http://`

`config reference: et <a href="http://doc.emergingthreats.net/">http://doc.emergingthreats.net/</a>`

`..........`

`..........`

`[albert@VPN /usr/local/etc/suricata]$`

Еще один файл, о котором стоит упомянуть, — это threshold.config, в котором можно указать, насколько система обнаружения вторжений должна быть чувствительна, чтобы предупреждать вас о возможных проблемах. Помните, что система обнаружения вторжений может быть довольно шумным элементом в наборе инструментов для защиты вашего офиса, компании или даже двух небольших серверов. Настройка системы требует времени и внимания, так что будьте готовы к ложным срабатываниям, особенно в средних и крупных сетях. Вот фрагмент файла threshold.config:

`[albert@VPN /usr/local/etc/suricata]$ cat threshold.config`

`# Thresholding:`

`#`

`# This feature is used to reduce the number of logged alerts for noisy rules.`

`# Thresholding commands limit the number of times a particular event is logged`

`# during a specified time interval.`

`#`

`# The syntax is the following:`

`#`

`# threshold gen_id <gen_id>, sig_id <sig_id>, type <limit|threshold|both>, track <by_src|by_dst>, count <n>, seconds <t>`

`#`

`# event_filter gen_id <gen_id>, sig_id <sig_id>, type <limit|threshold|both>, track <by_src|by_dst>, count <n>, seconds <t>`

`#`

`# suppress gen_id <gid>, sig_id <sid>`

`# suppress gen_id <gid>, sig_id <sid>, track <by_src|by_dst>, ip <ip|subnet>`

`#`

`# The options are documented at https://suricata.readthedocs.io/en/latest/configuration/global-thresholds.html`

`#`

`# Please note that thresholding can also be set inside a signature. The interaction between rule based thresholds`

`# and global thresholds is documented here:`

`# https://suricata.readthedocs.io/en/latest/configuration/global-thresholds.html#global-thresholds-vs-rule-thresholds`

`# Limit to 10 alerts every 10 seconds for each source host`

`#threshold gen_id 0, sig_id 0, type threshold, track by_src, count 10, seconds 10`

`# Limit to 1 alert every 10 seconds for signature with sid 2404000`

`#threshold gen_id 1, sig_id 2404000, type threshold, track by_dst, count 1, seconds 10`

`# Avoid to alert on f-secure update`

`# Example taken from https://blog.inliniac.net/2012/03/07/f-secure-av-updates-and-suricata-ips/`

`#suppress gen_id 1, sig_id 2009557, track by_src, ip 217.110.97.128/25`

`#suppress gen_id 1, sig_id 2012086, track by_src, ip 217.110.97.128/25`

`#suppress gen_id 1, sig_id 2003614, track by_src, ip 217.110.97.128/25`

`[albert@VPN /usr/local/etc/suricata]$`

Самый важный файл в Suricata — это основной конфигурационный файл suricata.yaml. В файлах .yaml нужно соблюдать отступы. Если их не соблюдать, правила не загрузятся, и файл будет бесполезен. Этот файл находится в папке:

`/usr/local/etc/suricata/suricata.yaml`

Файл довольно большой, поэтому приготовьтесь использовать grep с флагом -n, чтобы найти строку, которую нужно настроить. [Официальное руководство по администрированию](https://suricata.readthedocs.io/en/latest/configuration/index.html) будет вам очень полезно, ведь с помощью Suricata можно сделать очень многое.

Прежде чем мы углубимся в эту тему, давайте в общих чертах рассмотрим, что к чему. Первое, что нужно понять, — какой тип сети мы пытаемся контролировать: глобальную или локальную. По умолчанию в файле suricata.yaml (помните, что это основной файл конфигурации) [зарезервированный блок IP-адресов](https://en.wikipedia.org/wiki/Reserved_IP_addresses) интерпретируется как локальный, как видно из следующего фрагмента. Для локальной сети это нормально, но вам, возможно, придется внести некоторые изменения. Например, если у вас нет SQL-сервера, вы можете отключить эту переменную. Возможно, у вас не сервер OracleDB, а сервер MySQL, поэтому порт 3306 должен быть указан в разделе «port-groups». Просто уделите немного времени изучению следующего снимка из файла suricata.yaml.

`##`

`## Step 1: inform Suricata about your network`

`##`

`vars:`

`# more specific is better for alert accuracy and performance`

`address-groups:`

`HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"`

`#HOME_NET: "[192.168.0.0/16]"`

`#HOME_NET: "[10.0.0.0/8]"`

`#HOME_NET: "[172.16.0.0/12]"`

`#HOME_NET: "any"`

`EXTERNAL_NET: "!$HOME_NET"`

`#EXTERNAL_NET: "any"`

`HTTP_SERVERS: "$HOME_NET"`

`SMTP_SERVERS: "$HOME_NET"`

`SQL_SERVERS: "$HOME_NET"`

`DNS_SERVERS: "$HOME_NET"`

`TELNET_SERVERS: "$HOME_NET"`

`AIM_SERVERS: "$EXTERNAL_NET"`

`DC_SERVERS: "$HOME_NET"`

`DNP3_SERVER: "$HOME_NET"`

`DNP3_CLIENT: "$HOME_NET"`

`MODBUS_CLIENT: "$HOME_NET"`

`MODBUS_SERVER: "$HOME_NET"`

`ENIP_CLIENT: "$HOME_NET"`

`ENIP_SERVER: "$HOME_NET"`

`port-groups:`

`HTTP_PORTS: "80"`

`SHELLCODE_PORTS: "!80"`

`ORACLE_PORTS: 1521`

`SSH_PORTS: 22`

`DNP3_PORTS: 20000`

`MODBUS_PORTS: 502`

`FILE_DATA_PORTS: "[$HTTP_PORTS,110,143]"`

`FTP_PORTS: 21`

`VXLAN_PORTS: 4789`

`##`

Вторая важная тема — формат вывода данных, о котором вы можете подробно прочитать по этой [ссылке](https://suricata.readthedocs.io/en/latest/configuration/suricata-yaml.html#outputs). Если вкратце, то по умолчанию включены строковое оповещение fast и EVE (расширяемый формат событий), а также ряд протоколов, таких как http, snmp, smb, dhcp и многие другие. Настоятельно рекомендуем внимательно изучить документацию, но даже просто просмотрев основной конфигурационный файл, вы поймете, что к чему. Для этого вы всегда можете использовать следующую команду и нажать Enter, чтобы появилась новая строка. Чтобы выйти из программы, просто введите «q».

`cat /usr/local/etc/suricata/suricata.yaml | less`

Как уже было сказано, Suricata регистрирует оповещения в нескольких типах журналов, таких как журнал быстрого формата или EVE, а также в журнале suricata.log, где фиксируются и другие типы событий, например проблемы с некоторыми правилами, неполадки в работе демона и т. д. Запомните, где находятся журналы и с чем они связаны.

`[albert@VPN /usr/local/etc/suricata]$ sudo ls -la /var/log/suricata`

`total 1582`

`drwx------ 2 root wheel 6 28 des. 08:24 .`

`drwxr-xr-x 4 root wheel 52 28 des. 08:00 ..`

`-rw-r--r-- 1 root wheel 1207757 28 des. 20:42 eve.json`

`-rw-r--r-- 1 root wheel 0 28 des. 08:24 fast.log`

`-rw-r--r-- 1 root wheel 643645 28 des. 20:42 stats.log`

`-rw-r--r-- 1 root wheel 3957 28 des. 20:17 suricata.log`

`[albert@VPN /usr/local/etc/suricata]$`

После того как мы настроили Suricata в соответствии со своими предпочтениями, мы можем получить доступ к правилам, проверить, все ли в порядке, и запустить их. Следующая команда также используется для обновления установленных наборов правил.

`[albert@VPN ~]$ sudo suricata-update`

`28/12/2019 -- 08:24:27 - <Info> -- Using data-directory /var/lib/suricata.`

`28/12/2019 -- 08:24:27 - <Info> -- Using Suricata configuration /usr/local/etc/suricata/suricata.yaml`

`28/12/2019 -- 08:24:27 - <Info> -- Using /usr/local/share/suricata/rules for Suricata provided rules.`

`28/12/2019 -- 08:24:27 - <Info> -- Found Suricata version 5.0.1 at /usr/local/bin/suricata.`

`28/12/2019 -- 08:24:27 - <Info> -- Loading /usr/local/etc/suricata/suricata.yaml`

`28/12/2019 -- 08:24:27 - <Info> -- Disabling rules for protocol modbus`

`28/12/2019 -- 08:24:27 - <Info> -- Disabling rules for protocol dnp3`

`28/12/2019 -- 08:24:27 - <Info> -- Disabling rules for protocol enip`

`28/12/2019 -- 08:24:27 - <Info> -- No sources configured, will use Emerging Threats Open`

`28/12/2019 -- 08:24:27 - <Info> -- Fetching https://rules.emergingthreats.net/open/suricata-5.0.1/emerging.rules.tar.gz.`

`100% - 2516963/2516963`

`28/12/2019 -- 08:24:28 - <Info> -- Done.`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/app-layer-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/decoder-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dhcp-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dnp3-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/dns-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/files.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/http-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/ipsec-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/kerberos-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/modbus-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/nfs-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/ntp-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/smb-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/smtp-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/stream-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Loading distribution rule file /usr/local/share/suricata/rules/tls-events.rules`

`28/12/2019 -- 08:24:28 - <Info> -- Ignoring file rules/emerging-deleted.rules`

`28/12/2019 -- 08:24:31 - <Info> -- Loaded 26103 rules.`

`28/12/2019 -- 08:24:31 - <Warning> -- Disabling ja3 rules as Suricata is built without libnss.`

`28/12/2019 -- 08:24:31 - <Info> -- 122 ja3_hash rules disabled.`

`28/12/2019 -- 08:24:31 - <Info> -- Disabled 136 rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Enabled 0 rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Modified 0 rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Dropped 0 rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Enabled 59 rules for flowbit dependencies.`

`28/12/2019 -- 08:24:31 - <Info> -- Creating directory /var/lib/suricata/rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Backing up current rules.`

`28/12/2019 -- 08:24:31 - <Info> -- Writing rules to /var/lib/suricata/rules/suricata.rules: total: 26103; enabled: 20835; added: 26103; removed 0; modified: 0`

`28/12/2019 -- 08:24:31 - <Info> -- Testing with suricata -T.`

`28/12/2019 -- 08:24:43 - <Info> -- Done.`

`[albert@VPN ~]$`

Как мы уже видели, команда suricata-update загружает правила и проверяет их. Вы можете автоматизировать этот процесс, запустив специальное задание cron на каждый день. Кстати, обратите внимание, где находятся правила. Все они собраны в одном файле по следующему пути:

`/var/lib/suricata/rules/suricata.rules`

Suricata может работать в таком режиме, но управлять правилами таким образом довольно сложно. В другой статье мы расскажем о Oinkmaster — программе для управления правилами Snort (еще одного IDS), которая отлично работает и в Suricata. IDS может быть довольно «шумным» инструментом, и вы можете прийти в отчаяние, когда увидите, сколько времени уходит на его тонкую настройку. Oinkmaster может помочь в этом, поскольку вы можете отключать отдельные наборы правил, а не целые источники.

Еще одна интересная команда — suricata-update list-sources. Она показывает происхождение правил, например названия компаний, лицензии и некоторые другие параметры.

`[albert@VPN /usr/local/etc/suricata]$ sudo suricata-update list-sources`

`28/12/2019 -- 19:50:41 - <Info> -- Using data-directory /var/lib/suricata.`

`28/12/2019 -- 19:50:41 - <Info> -- Using Suricata configuration /usr/local/etc/suricata/suricata.yaml`

`28/12/2019 -- 19:50:41 - <Info> -- Using /usr/local/share/suricata/rules for Suricata provided rules.`

`28/12/2019 -- 19:50:41 - <Info> -- Found Suricata version 5.0.1 at /usr/local/bin/suricata.`

`28/12/2019 -- 19:50:41 - <Info> -- No source index found, running update-sources`

`28/12/2019 -- 19:50:41 - <Info> -- Downloading https://www.openinfosecfoundation.org/rules/index.yaml`

`28/12/2019 -- 19:50:41 - <Info> -- Saved /var/lib/suricata/update/cache/index.yaml`

`Name: et/open`

`Vendor: Proofpoint`

`Summary: Emerging Threats Open Ruleset`

`License: MIT`

`Name: et/pro`

`Vendor: Proofpoint`

`Summary: Emerging Threats Pro Ruleset`

`License: Commercial`

`Replaces: et/open`

`Parameters: secret-code`

`Subscription: https://www.proofpoint.com/us/threat-insight/et-pro-ruleset`

`Name: oisf/trafficid`

`Vendor: OISF`

`Summary: Suricata Traffic ID ruleset`

`License: MIT`

`Name: ptresearch/attackdetection`

`Vendor: Positive Technologies`

`Summary: Positive Technologies Attack Detection Team ruleset`

`License: Custom`

`Name: scwx/malware`

`Vendor: Secureworks`

`Summary: Secureworks suricata-malware ruleset`

`License: Commercial`

`Parameters: secret-code`

`Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures)`

`Name: scwx/security`

`Vendor: Secureworks`

`Summary: Secureworks suricata-security ruleset`

`License: Commercial`

`Parameters: secret-code`

`Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures)`

`Name: sslbl/ssl-fp-blacklist`

`Vendor: Abuse.ch`

`Summary: Abuse.ch SSL Blacklist`

`License: Non-Commercial`

`Name: sslbl/ja3-fingerprints`

`Vendor: Abuse.ch`

`Summary: Abuse.ch Suricata JA3 Fingerprint Ruleset`

`License: Non-Commercial`

`Name: etnetera/aggressive`

`Vendor: Etnetera a.s.`

`Summary: Etnetera aggressive IP blacklist`

`License: MIT`

`Name: tgreen/hunting`

`Vendor: tgreen`

`Summary: Threat hunting rules`

`License: GPLv3`

`[albert@VPN /usr/local/etc/suricata]$`

Теперь, когда мы кое-что прояснили, можно запускать Suricata без каких-либо изменений в файле suricata.yaml. Очевидно, что в зависимости от типа используемой сети потребуются корректировки. В противном случае вы будете получать слишком много предупреждений о ложных срабатываниях.

Если мы не загрузили правила до запуска Suricata, не волнуйтесь, это можно сделать сразу после запуска.

`[albert@VPN /usr/local/etc/suricata]$ sudo service suricata start`

`Starting suricata.`

`[100403] 28/12/2019 -- 20:53:16 - (suricata.c:1084) <Notice> (LogVersion) -- This is Suricata version 5.0.1 RELEASE running in SYSTEM mode`

`[albert@VPN /usr/local/etc/suricata]$`

Теперь проверим, что все работает.

`[albert@VPN /usr/local/etc/suricata]$ ps aux | grep suricata`

`root 24659 0,0 38,7 417296 389032 - Ss 20:53 0:17,55 /usr/local/bin/suricata -D --pcap=vtnet0 --pidfile /var/run/suricata.pid -c /usr/local/etc/suricata/suricata.yaml`

`albert 24683 0,0 0,0 524 336 1 R+ 20:59 0:00,00 grep suricata`

`[albert@VPN /usr/local/etc/suricata]$`

А если вам интересно, можете заглянуть в файл suricata.log, чтобы убедиться, что все прошло гладко.

`[albert@VPN /usr/local/etc/suricata]$ sudo tail /var/log/suricata/suricata.log`

`[100380] 28/12/2019 -- 20:53:18 - (detect-engine-build.c:1416) <Info> (SigAddressPrepareStage1) -- 20838 signatures processed. 1067 are IP-only rules, 4837 are inspecting packet payload, 14705 inspect application layer, 103 are decoder event only`

`[100380] 28/12/2019 -- 20:53:28 - (util-runmodes.c:173) <Info> (RunModeSetLiveCaptureAutoFp) -- Using 1 live device(s).`

`[100427] 28/12/2019 -- 20:53:28 - (source-pcap.c:351) <Info> (ReceivePcapThreadInit) -- using interface vtnet0`

`[100427] 28/12/2019 -- 20:53:28 - (source-pcap.c:362) <Info> (ReceivePcapThreadInit) -- running in 'auto' checksum mode. Detection of interface state will require 1000ULL packets`

`[100427] 28/12/2019 -- 20:53:28 - (util-ioctl.c:112) <Info> (GetIfaceMTU) -- Found an MTU of 1500 for 'vtnet0'`

`[100427] 28/12/2019 -- 20:53:28 - (source-pcap.c:399) <Info> (ReceivePcapThreadInit) -- Set snaplen to 1524 for 'vtnet0'`

`[100380] 28/12/2019 -- 20:53:28 - (runmode-pcap.c:295) <Info> (RunModeIdsPcapAutoFp) -- RunModeIdsPcapAutoFp initialised`

`[100380] 28/12/2019 -- 20:53:28 - (util-conf.c:162) <Info> (ConfUnixSocketIsEnable) -- Running in live mode, activating unix socket`

`[100380] 28/12/2019 -- 20:53:28 - (unix-manager.c:129) <Info> (UnixNew) -- Using unix socket file '/var/run/suricata/suricata-command.socket'`

`[100380] 28/12/2019 -- 20:53:28 - (tm-threads.c:2165) <Notice> (TmThreadWaitOnThreadInit) -- all 2 packet processing threads, 4 management threads initialized, engine started.`

`[albert@VPN /usr/local/etc/suricata]$`

Как видите, Suricata работает без проблем. В следующих статьях мы расскажем, как запустить службу системного журнала для отправки логов в [SIEM](https://en.wikipedia.org/wiki/Security_information_and_event_management), как [управлять правилами с помощью Oinkmaster](https://suricata.readthedocs.io/en/suricata-4.1.4/rule-management/oinkmaster.html) вместо обычных команд и как добавить стек ELK для графического отображения оповещений.

Краткий список того, на что следует обратить внимание при установке Suricata на FreeBSD.

– Не забудьте назначить хотя бы один интерфейс.

– Настройка локальной или глобальной сети.

– По умолчанию включены быстрый формат вывода, EVE и статистика. Активируйте все остальные необходимые параметры.

– Настройка пороговых значений. Границы срабатывания оповещения.

– Настройка классификации. Настройте приоритет любой категории, которую нужно изменить.

– Настройка ссылок. Добавьте источники или отключите те, которые вам не нужны.

– Системный журнал. Если вам нужно отправлять журналы в программное обеспечение SIEM, не забудьте включить это.

– Ротация журналов. Вы можете начать читать [это руководство](https://www.adminbyaccident.com/freebsd/how-to-enable-log-rotation-on-freebsd/).

– Обновления исходного кода. Задания Cron могут справиться с этим.

# The Top 20 Nmap Commands You Must Know

Вас сбивают с толку бесчисленные команды Nmap и их описания в официальной документации? Мы вас понимаем и готовы помочь. Хорошая новость в том, что не нужно знать все возможности Nmap, чтобы эффективно использовать его в повседневной работе.

 Мы расскажем о 20 самых популярных командах Nmap, которые пригодятся вам в работе. Независимо от того, являетесь ли вы этичным хакером, студентом, изучающим эту сферу, или просто любителем игр в стиле «захват флага», эти 20 основных команд Nmap помогут вам практически в любой ситуации.

   
 Вам больше не придется разбираться в тонкостях работы с Nmap. Давайте прокрутим страницу вниз и приступим к сканированию наших целей на предмет уязвимостей.

## <span class="uag-toc__heading-anchor" id="bkmrk-"></span>What Is Nmap?

Network Mapper [(Nmap)](https://www.stationx.net/nmap-cheat-sheet/) is a command-line-based multi-platform (Windows, Mac OS X, Linux, etc.) [network scanning](https://www.stationx.net/how-to-use-nmap-to-scan-a-network/) application designed to [detect hosts](https://www.stationx.net/nmap-host-discovery/) and services on a computer network.

Nmap is a vital tool for any student or professional in cyber security. This free and open-source utility helps you gather network information and assess the security posture of devices in the networks you scan with it. Nmap can identify a host’s operating system, running applications, open ports, firewall information, and more.

If you don’t have it yet, install Nmap [here](https://nmap.org/download.html).

<div class="astra-advanced-hook-18036 " id="bkmrk--1">[![All-20-Commands-at-a-Glance.jpg](https://wiki2.k-11.ru/uploads/images/gallery/2026-05/scaled-1680-/all-20-commands-at-a-glance.jpg)](https://wiki2.k-11.ru/uploads/images/gallery/2026-05/all-20-commands-at-a-glance.jpg)</div>## <span class="uag-toc__heading-anchor" id="bkmrk--2"></span>How To Use Nmap

The Nmap command syntax is the “nmap” keyword followed by at least two arguments:

`nmap <flag(s)> <target/file>`

All flags begin with one (-) or two (--) hyphens, and a single Nmap command may contain multiple flags. A target is typically an IPv4/IPv6 address or address range.

Some flags apply to files instead of targets; those are for Nmap commands that read from a file or write Nmap scan results to files.

<div class="stnx-download-link" id="bkmrk-download-the-%22nmap-c">[Download the "Nmap Cheat Sheet" PDF](https://www.stationx.net/top-nmap-commands/#cb19cfa140)</div><div class="inherit-container-width wp-block-group stnx-box-one stnx-box-border is-layout-constrained wp-container-core-group-is-layout-3fb40b71 wp-block-group-is-layout-constrained" id="bkmrk-generate"><div class="command-search-bar"><span class="uag-toc__heading-anchor" id="bkmrk--3"></span></div><div id="bkmrk--7"></div></div>### 1. List all hosts on a network

`nmap -sL <target>`

This type of scan (list scan) is a version of host discovery that only lists each host on the selected network (s) and doesn’t send any packets to the target hosts. By default, Nmap does a reverse DNS lookup to get host names.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--8"></figure>### 2. Disable port scanning and only discover active hosts

`nmap -sn <target>`

`nmap -sP <target>`

With this option, Nmap will only print the names of hosts that have responded to the host discovery probes without any port scan. By default, this option is slightly more intrusive than the list scan. Use this option as a “[ping sweep](https://www.stationx.net/nmap-ping-sweep/)” to count available machines on a network or monitor server availability.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--9"></figure><figure class="wp-block-image aligncenter size-full" id="bkmrk--10"></figure>### 3. Discover the network path to a host

`nmap --traceroute <target>`

A packet may traverse several hosts before reaching its destination. This option allows you to trace this packet’s journey from host to host.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--11">![Discover the network path to a host](https://www.stationx.net/wp-content/uploads/2023/03/3-Discover-the-network-path-to-a-host-1.png)</figure>### 4. Scan for open ports and version information of services

`nmap -sV <target>`

When preparing for and doing pentesting, the command above helps you find open ports and determine the versions of running processes. Having accurate version numbers enables you to assess a device’s vulnerabilities.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--12">![Scan for open ports and version information of services](https://www.stationx.net/wp-content/uploads/2023/03/4-Scan-for-open-ports-and-version-information-of-services-1.png)</figure>### 5. Scan the ports specified

`nmap -p <port number or numbers> <target>`

Use this option to tell Nmap which ports you want to scan. It admits individual port numbers and ranges separated by a hyphen (e.g., 1-1023). Nmap can also scan port zero, but you must specify it explicitly.

When scanning a combination of protocols (e.g., TCP and UDP), you can specify a particular protocol by preceding the port numbers using a single-letter qualifier:

- `T`: for TCP,
- `U`: for UDP,
- `S`: for SCTP, and
- `P`: for IP Protocol.

The qualifier lasts until you specify another qualifier. For example, the argument `-p U:53,111,137,T:21-25,80,139,8080` would scan UDP ports `53, 111,` and `137,` and the listed TCP ports.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--13">![Scan the ports specified](https://www.stationx.net/wp-content/uploads/2023/03/5-Scan-the-ports-specified-1.png)</figure>### 6. Scan all ports on a target

`nmap -p- <target>`

This command will scan ports numbered 1 through 65535.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--14">![Scan all ports on a target](https://www.stationx.net/wp-content/uploads/2023/03/6-Scan-all-ports-on-a-target-1.png)</figure>### 7. Scan for open ports on the target

`nmap --open <target>`

Only show hosts with open or likely open ports, and list those ports. Here, “open ports” refer to any ports that may be open, which includes the port states “open,” “open|filtered (open or filtered),” and “unfiltered.” The Nmap official documentation has more on [port states](https://nmap.org/book/man-port-scanning-basics.html).

<figure class="wp-block-image aligncenter size-full" id="bkmrk--15">![Scan for open ports on the target](https://www.stationx.net/wp-content/uploads/2023/03/7-Scan-for-open-ports-on-the-target-1.png)</figure>### 8. Scan for the specified number of most common ports

`nmap --top-ports <number> <target>`

Specify an arbitrary number of the most commonly open ports for Nmap to scan. Nmap scans the &lt;number&gt; highest-ratio ports found in nmap-services file after excluding all ports specified by --exclude-ports. &lt;number&gt; must be at least 1.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--16">![Scan for the specified number of most common ports](https://www.stationx.net/wp-content/uploads/2023/03/8-Scan-for-the-specified-number-of-most-common-ports-1.png)</figure>### 9. Perform a TCP connect scan

`nmap -sT <target>`

A TCP connect scan is where Nmap asks the underlying operating system to establish a connection with the target machine and port by issuing the “connect” system call. The “connect” system call is the same high-level system call that web browsers, P2P clients, and most other network-enabled applications use to establish a connection.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--17">![Perform a TCP connect scan](https://www.stationx.net/wp-content/uploads/2023/03/9-Perform-a-TCP-connect-scan-1.png)</figure>### 10. Scan for UDP ports

`nmap -sU <target>`

In a UDP scan, [Nmap sends a UDP packet to every targeted port](https://www.stationx.net/nmap-udp-scan/), usually without extra data, except for ports where a payload would increase the response rate, such as 53 and 161. If Nmap receives an error message, the port is unavailable. Avoid rushing UDP scans, as operating systems such as Linux and Solaris impose strict rate limits.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--18">![Scan for UDP ports](https://www.stationx.net/wp-content/uploads/2023/03/10-Scan-for-UDP-ports-1.png)</figure>### 11. Enable OS detection, version detection, script scanning, and traceroute

`nmap -A <target>`

This option turns on [operating system detection](https://www.stationx.net/nmap-os-detection/) and the advanced and aggressive functions mentioned above.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--19">![Enable OS detection, version detection, script scanning, and traceroute](https://www.stationx.net/wp-content/uploads/2023/03/11-Enable-OS-detection-version-detection-script-scanning-and-traceroute-1.png)</figure>### 12. Scan for remote operating system

`nmap -O <target>`

Perform remote operating system detection using TCP/IP stack fingerprinting: Nmap sends a series of TCP and UDP packets to the remote host, examines every bit in the responses, compares its `nmap-os-db` database of more than 2,600 known operating system fingerprints, and prints out the operating system details if there is a match.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--20">![(12) Scan for remote operating system](https://www.stationx.net/wp-content/uploads/2023/03/12-Scan-for-remote-operating-system.png)</figure>### 13. Scan a target with a specific timing template

`nmap -T<timing template: 0-5> <target>`

Timing templates allow users to specify how aggressive they wish to be, leaving Nmap to pick the exact timing values. The template names are paranoid (0), sneaky (1), polite (2), normal (3), aggressive (4), and insane (5). Polite mode slows the scan to use less bandwidth and target machine resources to evade intrusion detection systems.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--21">![(13) Scan a target with a specific timing template](https://www.stationx.net/wp-content/uploads/2023/03/13-Scan-a-target-with-a-specific-timing-template.png)</figure>### 14. Increase the verbosity of the output (second level)

`nmap -vv <target>`

A single `-v` flag increases the verbosity level, causing Nmap to print more information about the scan in progress, such as open ports found in real-time and completion time estimates for scans that may take considerable time. Use it twice or more for even greater verbosity: `-vv,` or give a verbosity level directly, for example `-v3`.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--22">![Increase the verbosity of the output (second level)](https://www.stationx.net/wp-content/uploads/2023/03/14-Increase-the-verbosity-of-the-output-second-level-1.png)</figure><div class="stnx-cta-embed" data-description="Want to keep all Nmap commands at your fingertips? Just enter your email address, and we’ll send the cheat sheet to your inbox." data-title="Grab Your FREE Nmap Cheat Sheet Now!" id="bkmrk--23">  
</div><div id="bkmrk-grab-your-free-nmap-"><div class="vue-portal-target"><div class="cb-box cb-box__type-embed cb-box__type-embed--large cb-box__layout-double cb-box__layout-left cb-box__hide-mobile__left cb-ready" data-v-0c1a6512="" data-v-3e1ea02c="" id="bkmrk-grab-your-free-nmap--1"><div class="cb-box__inner-wrap cb-box__bg-size-fill cb-box__bg-position-cc" data-v-3e1ea02c=""><div class="cb-box__bg-color" data-v-3e1ea02c="">  
</div><div class="cb-box__inner" data-v-3e1ea02c=""><div class="cb-box__inner-row" data-v-3e1ea02c=""><div class="cb-box__inner-col cb-box__bg-size-fill cb-box__bg-position-cc"><div class="cb-box__inner-bg">  
</div><div class="cb-box__inner-drag">  
</div></div><div class="cb-box__inner-col cb-box__bg-size-fill cb-box__bg-position-cc"><div class="cb-box__inner-bg">  
</div><div class="cb-box__inner-drag"><div class="cb-element cb-element__type-text cb-element__vertical-top-0 cb-element__vertical-bottom-0"><div class="cb-element__wrap"><div class="cb-element__inner ff-inherit"><div>**Grab Your FREE Nmap Cheat Sheet Now!**</div></div></div></div><div class="cb-element cb-element__type-text cb-element__vertical-top-0 cb-element__vertical-bottom-1"><div class="cb-element__wrap"><div class="cb-element__inner ff-inherit"><div>Want to keep all Nmap commands at your fingertips? Just enter your email address, and we’ll send the cheat sheet to your inbox.</div></div></div></div><div class="cb-element cb-element__type-form cb-element__vertical-top-0 cb-element__vertical-bottom-2 cb-element__size-medium cb-element__shape-rounded"><div class="cb-element__wrap"><div class="cb-element__inner"><form action="https://www.stationx.net/"><div class="cb-form-group"><div class="cb-form-group__component"><div class="cb-form-group__control"></div></div></div><div class="cb-form-group"><div class="cb-form-group__component"><div class="cb-form-group__control"></div></div></div><div class="cb-form-group"><button class="cb-form-group__btn ff-inherit" data-v-77830b0e="" type="submit"><span data-v-77830b0e="">**DOWNLOAD →**</span></button></div></form></div></div></div></div></div></div></div></div></div></div></div>### 15. Scan for commonly used ports and services

`nmap -sC <target>`

This command is equivalent to nmap `--script=default <target>`. It uses Nmap’s [default](https://nmap.org/nsedoc/categories/default.html) [Nmap Scripting Engine (NSE)](https://www.stationx.net/nmap-scripting-engine/) scripts to scan for individual ports and protocols, including HTML and POP3. The scripts are mostly safe but contain intrusive processes. For example, the default script “[​​jdwp-info](https://nmap.org/nsedoc/scripts/jdwp-info.html)” tries to exploit Java’s remote debugging port.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--24">![Scan for commonly used ports and services](https://www.stationx.net/wp-content/uploads/2023/03/15-Scan-for-commonly-used-ports-and-services-1.png)</figure>### 16. Run a script on the target

`nmap --script <script type> <target>`

Nmap runs a [script](https://nmap.org/book/man-nse.html) scan using the comma-separated list of filenames, script categories, and directories.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--25">![Run a script on the target](https://www.stationx.net/wp-content/uploads/2023/03/16-Run-a-script-on-the-target-1.png)</figure>### 17. Run all vulnerability scans on the target

`nmap --script vuln <target>`

The [vuln scripts](https://nmap.org/nsedoc/categories/vuln.html) check for specific known vulnerabilities, and Nmap generally only reports results when it finds any. Examples include `realvnc-auth-bypass` and `afp-path-vuln`.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--26">![(17) Run all vulnerability scans on the target](https://www.stationx.net/wp-content/uploads/2023/03/17-Run-all-vulnerability-scans-on-the-target.png)</figure>### 18. Read targets from a text file

`nmap -iL <file>`

Nmap reads a list of targets from a file as input. Entries can be in any format Nmap accepts on the command line (IP address, hostname, CIDR, IPv6, or octet ranges). Each entry must have spaces, tabs, or newlines as delimiters. The input file may contain comments that start with # and extend to the end of the line.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--27">![Read targets from a text file](https://www.stationx.net/wp-content/uploads/2023/03/18-Read-targets-from-a-text-file-1.png)</figure>### 19. Save scan results in normal, XML, and grepable formats at once

`nmap -oA <file>`

Store Nmap scan results as three separate files, with &lt;file&gt; as the base file name and file extensions .nmap (normal), .xml (XML), and .gnmap (grepable). Like most programs, &lt;file&gt; may include a directory path, such as ~/folder1/foo/ on Unix or c:\\folder2\\bar on Windows.

<figure class="wp-block-image aligncenter size-full" id="bkmrk--28">![Save scan results in normal, XML, and grepable formats at once](https://www.stationx.net/wp-content/uploads/2023/03/19-Save-scan-results-in-normal-XML-and-grepable-formats-at-once-1.png)</figure>### 20. Save the scan results to a normal format

`nmap -oN <file>`

Write the Nmap scan results to the given file name. Only use this command together with a valid Nmap scan command containing some &lt;target&gt; as shown in the example below (`nmap --top-ports 10 192.168.1.1-10 -oN tenports.txt`):

<figure class="wp-block-image aligncenter size-full" id="bkmrk--29">![Save the scan results to a normal format](https://www.stationx.net/wp-content/uploads/2023/03/20-Save-the-scan-results-to-a-normal-format-1.png)</figure>## <span class="uag-toc__heading-anchor" id="bkmrk--30"></span>Conclusion

We hope this brief guide to the top 20 Nmap commands helps you in your IT or cyber security journey. Don’t forget to share this article with someone who needs it. To learn more about Nmap, check out our other articles on [Nmap](https://www.stationx.net/?s=nmap) and courses on Nmap below. For access to over 30,000 courses and labs on all aspects of cyber security, join the [StationX Master's Program](https://www.stationx.net/membership/) today.

# SpamAssassin for Sendmail on FreeBSD

This page is about how to install and use SpamAssassin for Sendmail on FreeBSD. Tested on FreeBSD 14.3.

## What is SpamAssassin?

SpamAssassin is a filter system, that can detect spam mail. SpamAssassin is an open source project, that has been offered by Apache since 2001. The filter can be implemented as a mail filter for mail servers, such as Sendmail. Such a mail filter is also known as a milter. Unfortunately, the official documentation and the FreeBSD install instructions are rather old and outright wrong.

[https://spamassassin.apache.org](https://spamassassin.apache.org/)

## How does SpamAssassin work?

SpamAssassin reads the headers of email and use a set of rules to detect known spam characteristics and apply a spam score to the headers. Email clients can then use this score to identify the email as spam and move it to another inbox for spam or trash.

Below, is an example of SpamAssassin score headers in a filtered message, that spoofed a Google GMail account and presented a crypto extortion scheme.

```
X-Spam-Checker-Version: SpamAssassin 4.0.2 (2025-08-27) on wopr<br></br>X-Spam-Flag: YES<br></br>X-Spam-Level: ********************<br></br>X-Spam-Status: Yes, score=20.7 required=3.8 tests=BITCOIN_EXTORT_01,<br></br>        BITCOIN_SPAM_05,DKIM_ADSP_CUSTOM_MED,FORGED_GMAIL_RCVD,<br></br>        FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GB_HASHBL_BTC,HELO_MISC_IP,<br></br>        NML_ADSP_CUSTOM_MED,RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_DNSWL_BLOCKED,<br></br>        RCVD_IN_MSPIKE_BL,RCVD_IN_MSPIKE_L5,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,<br></br>        RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED,<br></br>        RCVD_IN_ZEN_BLOCKED_OPENDNS,RDNS_NONE,SPOOFED_FREEMAIL,<br></br>        SPOOFED_FREEMAIL_NO_RDNS,SPOOF_GMAIL_MID,SUBJ_ALL_CAPS,URIBL_BLOCKED,<br></br>        URIBL_DBL_BLOCKED_OPENDNS autolearn=spam autolearn_force=no<br></br>        version=4.0.2
```

## Install SpamAssassin on FreeBSD.

```
# pkg install spamass-milter
```

Check the default configuration.

```
# cat /usr/local/etc/mail/spamassassin/init.pre | grep -v '^#' | grep -v '^$'<br></br>enable_compat welcomelist_blocklist<br></br>loadplugin Mail::SpamAssassin::Plugin::URIDNSBL<br></br># cat /usr/local/etc/mail/spamassassin/local.cf | grep -v '^#' | grep -v '^$'<br></br>ifplugin Mail::SpamAssassin::Plugin::Shortcircuit<br></br>endif # Mail::SpamAssassin::Plugin::Shortcircuit
```

## Update spam detection rules.

```
# sa-update && sa-compile
```

## Test SpamAssassin with ham and spam manually.

You can filter mail folders through SpamAssassin and inspect the results in the mail client. In this example, ham and spam mail folders for Alpine is used for testing SpamAssassin manually. Alpine use the MBOX format.

```
$ ls mail<br></br>Ham     Spam<br></br>$ spamassassin --mbox < mail/Ham > mail/SpamAssassin<br></br>$ spamassassin --mbox < mail/Spam >> mail/SpamAssassin<br></br>$ alpine
```

The spam mail folder can later be used for training SpamAssassin, which can scan it regularly.

You can also save ham and spam messages as plain-text files and filter those through SpamAssassin.

## Settle on a maximum spam score.

Settle on a spam score for future use in the configuration. The default is 5. If DNS block lists are unavailable due to IP address range block or rate limiting, which is common, I recommend a score closer to 3,8.

## Configure SpamAssassin.

If you want SpamAssassin to learn from human marked spam, then create a directory for such database.

```
# mkdir -m 700 -p /usr/local/etc/spamassassin<br></br># nano /usr/local/etc/mail/spamassassin/init.pre<br></br># cat /usr/local/etc/mail/spamassassin/init.pre | grep -v '^#' | grep -v '^$'<br></br>loadplugin Mail::SpamAssassin::Plugin::URIDNSBL<br></br>enable_compat welcomelist_blocklist<br></br># nano /usr/local/etc/mail/spamassassin/local.cf<br></br># cat /usr/local/etc/mail/spamassassin/local.cf | grep -v '^#' | grep -v '^$'<br></br>score RDNS_NONE 2.8<br></br>required_score 3.2<br></br>use_bayes 1<br></br>bayes_auto_learn 1<br></br>body_part_scan_size 200000<br></br>rawbody_part_scan_size 2000000<br></br>ifplugin Mail::SpamAssassin::Plugin::Shortcircuit<br></br>bayes_path        /usr/local/etc/spamassassin/bayes<br></br>bayes_auto_learn  1<br></br>endif # Mail::SpamAssassin::Plugin::Shortcircuit
```

If DNS block lists are unavailable due to IP address range block or rate limiting, which is common, then you might want do disable the use of DNS. This is probably especially a good practice for higher volume mail servers to maintain speed.

## Test Bayes learning.

Test the Bayes learning and the new settings. It is important, that the mail box format is indicated.

```
# sa-learn --spam --mbox /home/lightman/mail/Spam
```

## Configure FreeBSD to start SpamAssassin.

If the spam score reaches 10, then the message will be rejected at the port.

```
# nano /etc/rc.conf<br></br># grep spam /etc/rc.conf<br></br>spamd_enable="YES"<br></br>spamd_flags="-c --max-children=10"<br></br>spamass_milter_enable="YES"<br></br>spamass_milter_socket="/var/run/spamd/spamass-milter.sock"<br></br>spamass_milter_flags="-r 10 -f -u spamd -p ${spamass_milter_socket}"<br></br># find /usr/local/etc/rc.d -name '*spam*'<br></br>/usr/local/etc/rc.d/sa-spamd<br></br>/usr/local/etc/rc.d/spamass-milter<br></br># service sa-spamd start<br></br># service spamass-milter start<br></br># ls -l /var/run/spamd<br></br>total 1<br></br>srw-r--r--  1 root  wheel  0 Mar 12 02:09 spamass-milter.sock<br></br>-rw-r--r--  1 root  spamd  5 Mar  9 18:19 spamd.pid
```

## Configure Sendmail to use SpamAssassin milter on FreeBSD.

```
# cd /etc/mail<br></br># nano $(hostname).mc<br></br># grep spamassassin $(hostname).mc<br></br>INPUT_MAIL_FILTER(`spamassassin',`S=local:/var/run/spamd/spamass-milter.sock, F=T, T=C:15m;S:4m;R:4m;E:10m')<br></br># make && make install<br></br># service sendmail restart<br></br># cd
```

## Configure CRON for SpamAssassin.

```
# nano bin/spamassassin-update<br></br># cat bin/spamassassin-update<br></br>#!/bin/sh<br></br>sa-update && sa-compile<br></br>service sa-spamd restart<br></br>service spamass-milter restart<br></br>sa-learn --spam /home/lightman/mail/Spam<br></br># chmod 700 bin/spamassassin-update<br></br># spamassassin-update<br></br># nano /etc/crontab<br></br># grep spam /etc/crontab<br></br>37  13  *   *   5   root /root/bin/spamassassin-update >/dev/null 2>&1<br></br># service cron restart
```

## Configure Dovecot IMAP server for handling spam.

I am still testing this feature. If you have tips, let me know. Thanks.

If the server runs [Dovecot](https://doc.dovecot.org/) IMAP server, or a similar IMAP server, it might support automatic handling of spam mail by reading mail headers, creating user spam folders and moving spam into those. The [Pigeonhole Sieve](#bkmrk-pigeonhole-sieve) plug-in for Dovecot can do this.

```
# pkg install dovecot-pigeonhole
```

Create the global script and compile it.

```
# mkdir -p /usr/local/etc/dovecot/sieve<br></br># nano /usr/local/etc/dovecot/sieve/global.sieve<br></br># cat /usr/local/etc/dovecot/sieve/global.sieve<br></br>require ["fileinto", "imap4flags"];<br></br>if header :contains "X-Spam-Flag" "YES" {<br></br>  fileinto "Spam";<br></br>  stop;<br></br>}<br></br># sievec /usr/local/etc/dovecot/sieve/global.sieve
```

Configure Dovecot.

```
# nano /usr/local/etc/dovecot/dovecot.conf
# cat /usr/local/etc/dovecot/dovecot.conf | grep -v '^#' | grep -v '^$' | tail -n 6
protocol lda {
  mail_plugins = sieve
}
plugin {
  sieve_global_path = /usr/local/etc/dovecot/sieve/global.svbin
}
# service dovecot restart
```

## Configure Alpine or other mail client for handling spam.

You can now configure your mail client for handling spam. The spam features of mail clients include looking in mail headers and using this information to move the mail to a spam folder or deleting it outright.

In Alpine, you can go to “Setup”, “Rules” and “Filters”. Here, you can create filtering rules. Create a new filter. If it has an “X-Spam-Status” mail header and the the value is “Yes”, then move the message to the “Spam” folder. You can also use other spam headers and options.

```
X-Spam-Checker-Version: SpamAssassin 4.0.2 (2025-08-27) on wopr<br></br>X-Spam-Flag: YES<br></br>X-Spam-Level: ********************<br></br>X-Spam-Status: Yes, score=20.7 required=3.8 tests=BITCOIN_EXTORT_01,<br></br>        BITCOIN_SPAM_05,DKIM_ADSP_CUSTOM_MED,FORGED_GMAIL_RCVD,<br></br>        FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GB_HASHBL_BTC,HELO_MISC_IP,<br></br>        NML_ADSP_CUSTOM_MED,RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_DNSWL_BLOCKED,
```

## Check SpamAssassin related entries in the system mail log.

Check for issues by following and scanning the system mail log, investigate specific messages and adjust configuration as necessary.

```
# tail -f /var/log/maillog<br></br># grep -e spamc -e spamass /var/log/maillog
```

## More about SpamAssassin.

<div class="entry-content" id="bkmrk-https%3A%2F%2Fman.freebsd.">- [https://man.freebsd.org/cgi/man.cgi?query=Mail::SpamAssassin::Conf&amp;sektion=3&amp;manpath=FreeBSD+14.0-RELEASE+and+Ports](https://man.freebsd.org/cgi/man.cgi?query=Mail::SpamAssassin::Conf&sektion=3&manpath=FreeBSD+14.0-RELEASE+and+Ports)
- [https://vintners.net/mikel/howto/spamass.html](https://vintners.net/mikel/howto/spamass.html)

</div><footer class="entry-footer" id="bkmrk-2026-03-11"><span class="posted-on">[<time class="entry-date published" datetime="2026-03-11T16:39:19+01:00">2026-03-11</time>](https://www.micski.dk/2026/03/11/spamassassin-for-sendmail-on-freebsd/)</span></footer>

# SendMail, Dovecot, SpamAssassin, RainLoop, Sieve, OpenDkim, SPF, DMARC on FreeBSD

In this article, we will learn how to set up a complete email system. We will be able to send/receive emails, access them through a web interface, filter spam, define Sieve filters, and sign outgoing emails using DKIM.

The technologies used for this are:

- [SendMail ](https://www.proofpoint.com/us/products/email-protection/open-source-email-solution): Sends and receives emails
- [Dovecot ](https://www.dovecot.org/): Allows access to stored emails through the web interface
- [SpamAssassin ](https://spamassassin.apache.org/): Filters incoming emails based on certain rules
- [RainLoop ](https://www.rainloop.net/): Web interface for accessing emails
- [Sieve ](http://sieve.info/): Email filtering/categorization system

---

This article is quite extensive, so I have divided it into several sections:

- [SendMail](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#sendmail)
- [Dovecot](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#dovecot)
- [RainLoop](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#rainloop)
- [SpamAssassin](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#spamassassin)
- [SPF](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#spf)
- [DKIM](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#dkim)
- [DMARC](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#dmarc)
- [SSL RainLoop](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#ssl-rainloop)
- [SSL SendMail](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#ssl-sendmail)
- [Reverse DNS](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#reverse-dns)
- [Account maintenance](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#account-maintenance)
- [Debug](https://alfaexploit.com/en/posts/sendmail_dovecot_spamassassin_rainloop_sieve_opendkim_spf_dmarc_on_freebsd/#debug)

---

#### SendMail

The first step will be to make sure our server knows its own hostname:

<div class="box" id="bkmrk-vi-%2Fetc%2Fhosts">vi /etc/hosts</div>```txt
127.0.0.1               HellStorm HellStorm.alfaexploit.com mail.alfaexploit.com localhost localhost.my.domain

```

SendMail is installed by default on FreeBSD, we start the service:

<div class="box" id="bkmrk-sysrc-sendmail_enabl">sysrc sendmail_enable=yes  
sysrc sendmail_msp_queue_enable=yes  
service sendmail start</div>We check that we can access it over the network:

<div class="box" id="bkmrk-telnet-x.x.x.x-25">telnet X.X.X.X 25</div>```shell
220 HellStorm.alfaexploit.com ESMTP Sendmail 8.16.1/8.16.1; Sun, 1 Jan 2023 17:39:07 +0100 (CET)

```

In the magnificent FreeBSD handbook, we can find a [guide ](https://www.freebsd.org/doc/handbook/sendmail.html)from which I have extracted the following information.

Access permissions are filtered by origin in the file: /etc/mail/access

```
OK: Permitiremos la entrada del mail siempre y cuando el destino sea un dominio local(/etc/mail/local-host-names)
RELAY: Permitiremos el envío de mails a dominios de terceros a través de nuestro server
ERROR: Denegaremos el envío de mails con el mensaje indicado
SKIP: Denegaremos el envío de mails sin avisar al cliente que el email ha sido destruido
QUARANTINE: El mail se guardará en el servidor local pero no se enviará a su destino, el cliente recibirá una explicación de porque su email ha sido retenido

#From:cyberspammer.com ERROR:"550 We don't accept mail from spammers"
#From:okay.cyberspammer.com OK
#Connect:sendmail.org RELAY
#To:sendmail.org RELAY
#Connect:128.32 RELAY
#Connect:128.32.2 SKIP
#Connect:IPv6:1:2:3:4:5:6:7 RELAY
#Connect:suspicious.example.com QUARANTINE:Mail from suspicious host
#Connect:[127.0.0.3] OK
#Connect:[IPv6:1:2:3:4:5:6:7:8] OK

```

By default, the OK policy is applied from any IP as long as the destination is local or listed in /etc/mail/local-host-names.

For example, if we try to send an email to [kr0m@alfaexploit.com ](mailto:kr0m@alfaexploit.com), access will be denied, but for kr0m@localhost, it will be allowed:

<div class="box" id="bkmrk-telnet-192.168.69.17">telnet 192.168.69.17 25</div>```shell
Trying 192.168.69.17...
Connected to 192.168.69.17.
Escape character is '^]'.
220 HellStorm.alfaexploit.com ESMTP Sendmail 8.16.1/8.16.1; Sun, 1 Jan 2023 17:39:07 +0100 (CET)
ehlo 192.168.69.17
250-HellStorm.alfaexploit.com Hello [192.168.69.17], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-STARTTLS
250-DELIVERBY
250 HELP
mail from: test@kr0m.com
250 2.1.0 test@kr0m.com... Sender ok
rcpt to: kr0m@alfaexploit.com
250 2.1.5 kr0m@alfaexploit.com... Recipient ok
data
354 Enter mail, end with "." on a line by itself
prueba00
.
250 2.0.0 301Gd7Qr028498 Message accepted for delivery
quit
221 2.0.0 HellStorm.alfaexploit.com closing connection
Connection closed by foreign host.

```

In the telnet session, there will be no error, but in the logs, we can see that the mail has not been sent:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fmai">tail -f /var/log/maillog</div>```
Jan  1 17:41:05 HellStorm sm-mta[32142]: 301Gd7Qr028498: to=kr0m@alfaexploit.com, delay=00:00:12, xdelay=00:00:00, mailer=esmtp, pri=30009, relay=alfaexploit.com., dsn=5.3.5, stat=Local configuration error

```

However, if the recipient is kr0m@localhost, we will see the delivery:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fmai-1">tail -f /var/log/maillog</div>```
Jan  1 17:45:31 HellStorm sm-mta[35699]: 301Gj39N027210: to=kr0m@localhost, delay=00:00:18, xdelay=00:00:00, mailer=local, pri=30396, relay=local, dsn=2.0.0, stat=Sent

```

The user kr0m can read this last email:

<div class="box" id="bkmrk-mail">mail</div>```shell
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/kr0m": 1 message 1 new
>N  1 test@kr0m.com         Sun Jan  1 17:45  13/455  
& 1
Message 1:
From test@kr0m.com Sun Jan  1 17:45:31 2023
Date: Sun, 1 Jan 2023 17:45:03 +0100 (CET)
From: test@kr0m.com
To: undisclosed-recipients:;

prueba01

& 

```

We add alfaexploit.com to the group of local domains:

<div class="box" id="bkmrk-vi-%2Fetc%2Fmail%2Flocal-h">vi /etc/mail/local-host-names</div>```txt
alfaexploit.com

```

We restart SendMail:

<div class="box" id="bkmrk-service-sendmail-res">service sendmail restart</div>We perform the test again:

<div class="box" id="bkmrk-telnet-192.168.69.17-1">telnet 192.168.69.17 25</div>```shell
Trying 192.168.69.17...
Connected to 192.168.69.17.
Escape character is '^]'.
220 HellStorm.alfaexploit.com ESMTP Sendmail 8.16.1/8.16.1; Sun, 1 Jan 2023 17:48:01 +0100 (CET)
ehlo 192.168.69.17
250-HellStorm.alfaexploit.com Hello [192.168.69.17], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-STARTTLS
250-DELIVERBY
250 HELP
mail from: test@kr0m.com
250 2.1.0 test@kr0m.com... Sender ok
rcpt to: kr0m@alfaexploit.com
250 2.1.5 kr0m@alfaexploit.com... Recipient ok
data
354 Enter mail, end with "." on a line by itself
prueba02
.
250 2.0.0 301Gm17S090416 Message accepted for delivery
quit
221 2.0.0 HellStorm.alfaexploit.com closing connection
Connection closed by foreign host.

```

We can see that now the delivery has been made correctly:

```
Jan  1 17:48:28 HellStorm sm-mta[13349]: 301Gm17S090416: to=kr0m@alfaexploit.com, delay=00:00:12, xdelay=00:00:00, mailer=local, pri=30402, relay=local, dsn=2.0.0, stat=Sent

```

We read the mail:

<div class="box" id="bkmrk-mail-1">mail</div>```shell
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/kr0m": 1 message 1 new
>N  1 test@kr0m.com         Sun Jan  1 17:48  13/461  
& 1
Message 1:
From test@kr0m.com Sun Jan  1 17:48:28 2023
Date: Sun, 1 Jan 2023 17:48:01 +0100 (CET)
From: test@kr0m.com
To: undisclosed-recipients:;

prueba02

& 

```

**NOTE**: By adding the domain alfaexploit.com to local-host-names, it is equivalent to creating email accounts for all users in the operating system. For larger environments, we should look for some kind of integration of virtual users from a MySQL, LDAP, or similar database.

The aliases file defines email addresses that expand to other users, external addresses, files, programs, or other aliases. In my case, we leave it as it comes by default, but root will be an alias to [kr0m@alfaexploit.com ](mailto:kr0m@alfaexploit.com):

<div class="box" id="bkmrk-vi-%2Fetc%2Fmail%2Faliases">vi /etc/mail/aliases</div>```txt
MAILER-DAEMON: postmaster
postmaster: root
_dhcp: root
_pflogd: root
auditdistd: root
bin: root
bind: root
daemon: root
games: root
hast: root
kmem: root
mailnull: postmaster
man: root
news: root
nobody: root
operator: root
pop: root
proxy: root
smmsp: postmaster
sshd: root
system: root
toor: root
tty: root
usenet: news
uucp: root
abuse: root
security: root
ftp: root
ftp-bugs: ftp
root: kr0m@alfaexploit.com

```

We regenerate the hash of the file:

<div class="box" id="bkmrk-newaliases">newaliases</div>To convert an email address to a mailbox, we will use the virtusertable file. The destination can be local mailboxes, remote mailboxes, aliases defined in /etc/mail/aliases, or files. In my case, it is not necessary to generate the file since I do not use these functionalities.

```txt
root@example.com root
postmaster@example.com postmaster@noc.example.net
@example.com joe

```

**NOTE**: Entries are checked in the order they appear in the configuration file. In this example, a generic entry has been configured for the example.com domain. If the recipient is anyone other than root or postmaster, it will be sent to joe.

If we have generated the /etc/mail/virtusertable file, we refresh the hash of the file and restart SendMail:

<div class="box" id="bkmrk-makemap-hash-%2Fetc%2Fma">makemap hash /etc/mail/virtusertable &lt; /etc/mail/virtusertable  
service sendmail restart</div>If we need an external computer to be able to use our server to send emails, we must indicate the IPs/DNS in the relay-domains file. In my case, it is not necessary:

<div class="box" id="bkmrk-vi-%2Fetc%2Fmail%2Frelay-d">vi /etc/mail/relay-domains</div>```txt
service sendmail restart

```

We can find the documentation on SendMail configuration in the file: /usr/share/sendmail/cf/README

---

#### Dovecot

With SendMail, we can send and receive emails but not read the received ones. For this, we need an IMAP server:

<div class="box" id="bkmrk-pkg-install-dovecot">pkg install dovecot</div>We copy the example configuration files:

<div class="box" id="bkmrk-cp--r-%2Fusr%2Flocal%2Fetc">cp -R /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot/</div>We remove the SSL configuration since we will access emails through the web interface, the only point of contact with the outside world will be through SendMail to send/receive emails.

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo">vi /usr/local/etc/dovecot/conf.d/10-ssl.conf</div>```txt
ssl = no
#ssl_cert = </etc/ssl/certs/dovecot.pem
#ssl_key = </etc/ssl/private/dovecot.pem

```

The web interface only accesses Dovecot via IMAP:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-1">vi /usr/local/etc/dovecot/dovecot.conf</div>```txt
protocols = imap lmtp

```

We bind Dovecot to the server’s IP:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-2">vi /usr/local/etc/dovecot/dovecot.conf</div>```txt
listen = 192.168.69.17

```

We tell Dovecot where to organize Sent/Drafts/Spam/Trash/Archive emails and where to look for received emails:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-3">vi /usr/local/etc/dovecot/conf.d/10-mail.conf</div>```txt
mail_location = mbox:~/mboxDir:INBOX=/var/mail/%u
mail_privileged_group = mail

```

We adjust the permissions of the /var/mail directory:

<div class="box" id="bkmrk-chmod-a%2Brwxt-%2Fvar%2Fma">chmod a+rwxt /var/mail</div>We create the email directories in the user’s home directory:

su -l kr0m

mkdir mboxDir  
chmod 700 mboxDir

touch mboxDir/Sent  
touch mboxDir/Drafts  
touch mboxDir/Spam  
touch mboxDir/Trash  
touch mboxDir/Archive

chmod 600 mboxDir/Sent  
chmod 600 mboxDir/Drafts  
chmod 600 mboxDir/Spam  
chmod 600 mboxDir/Trash  
chmod 600 mboxDir/Archive

exit

We start the service:

<div class="box" id="bkmrk-sysrc-dovecot_enable">sysrc dovecot_enable=yes  
service dovecot start</div>---

#### RainLoop

We install RainLoop, a web interface that will allow us to read and send emails:

pkg install -y unzip curl wget socat  
pkg install -y php82 php82-mbstring php82-tokenizer php82-pdo php82-pdo\_mysql php82-phar php82-filter php82-zlib php82-dom php82-xml php82-xmlwriter php82-xmlreader php82-pecl-imagick php82-curl php82-session php82-ctype php82-iconv php82-gd php82-simplexml php82-zip php82-filter php82-tokenizer php82-calendar php82-fileinfo php82-intl php82-phar php82-soap php82-opcache php82-mysqli php82-bcmath php82-gmp

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

We adjust some parameters in php.ini to be able to send larger attachments:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fph">vi /usr/local/etc/php.ini</div>```ini
date.timezone = Europe/Madrid
upload_max_filesize = 25M
post_max_size = 25M

```

We start the php-fpm service:

<div class="box" id="bkmrk-sysrc-php_fpm_enable">sysrc php_fpm_enable=yes  
service php-fpm start</div>We install MySQL to store user contacts:

<div class="box" id="bkmrk-pkg-install--y-mysql">pkg install -y mysql80-server</div>We start the service:

<div class="box" id="bkmrk-sysrc-mysql_enable%3Dy">sysrc mysql_enable=yes  
service mysql-server start</div>We configure the database:

<div class="box" id="bkmrk-mysql_secure_install">mysql_secure_installation</div>We create the configuration file to be able to log in without typing the password every time:

<div class="box" id="bkmrk-vi-.my.cnf">vi .my.cnf</div>```txt
[client]
user     = root
password = XXXXXXXXX

```

We secure access:

<div class="box" id="bkmrk-chmod-600-.my.cnf">chmod 600 .my.cnf</div>We create the database and a user with access to it:

<div class="box" id="bkmrk-mysql">mysql</div>```sql
CREATE DATABASE rainloop;
CREATE USER rainloop@'192.168.69.17' IDENTIFIED WITH mysql_native_password BY 'XXXXXXXXX';
GRANT ALL PRIVILEGES ON rainloop.* TO rainloop@'192.168.69.17';
FLUSH PRIVILEGES;
exit;

```

We install Nginx:

<div class="box" id="bkmrk-pkg-install--y-nginx">pkg install -y nginx</div>We start the service:

<div class="box" id="bkmrk-sysrc-nginx_enable%3Dy">sysrc nginx_enable=yes  
service nginx start</div>We create a vhost for RainLoop:

<div class="box" id="bkmrk-vim-%2Fusr%2Flocal%2Fetc%2Fn">vim /usr/local/etc/nginx/rainloop.conf</div>```nginx
server {

  listen 80;
  server_name mail.alfaexploit.com;

  root /usr/local/www/rainloop;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ^~ /data {
     deny all;
  }

  location ~ \.php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_keep_conn on;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
  }
  
}

```

We include the vhost in the general Nginx configuration, add the include and increase the maximum body size in the http{} section:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fng">vi /usr/local/etc/nginx/nginx.conf</div>```nginx
http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 25M;
    include rainloop.conf;

```

We restart the service:

<div class="box" id="bkmrk-service-nginx-reload">service nginx reload</div>We download and install RainLoop:

<div class="box" id="bkmrk-mkdir--p-%2Fusr%2Flocal%2F">mkdir -p /usr/local/www/rainloop  
cd /usr/local/www/rainloop  
wget [http://www.rainloop.net/repository/webmail/rainloop-latest.zip](http://www.rainloop.net/repository/webmail/rainloop-latest.zip)  
unzip rainloop-latest.zip -d /usr/local/www/rainloop  
rm rainloop-latest.zip  
chown -R www:www /usr/local/www/rainloop</div>We access the administration panel:  
[http://mail.alfaexploit.com/?admin](http://mail.alfaexploit.com/?admin)

```
admin
12345

```

The first step is to change the password.

<figure id="bkmrk--4">![](https://alfaexploit.com/images/mailFreeBSD/rainloop7.png)</figure>We configure access to the database where user contacts will be saved:

```
Contacts -> MySQL:
mysql:host=192.168.69.17;port=3306;dbname=rainloop
rainloop
XXXXXXXXX

```

<figure id="bkmrk--5">![](https://alfaexploit.com/images/mailFreeBSD/rainloop4.png)</figure>We click on the Test button to check the correct access.

We tell the login to automatically add @alfaexploit.com to the user:

<figure id="bkmrk--6">![](https://alfaexploit.com/images/mailFreeBSD/rainloop5b.png)</figure>We add the domain:

```
Domains -> alfaexploit.com
IMAP
X.X.X.X
143

```

```
SMTP
X.X.X.X
25

```

```
Use short login

```

**NOTE**: Use short login -&gt; Since RainLoop will automatically add @alfaexploit.com as we have indicated in the previous step.

<figure id="bkmrk--7">![](https://alfaexploit.com/images/mailFreeBSD/rainloop5.png)</figure>We access the email account as a user:  
[http://mail.alfaexploit.com](http://mail.alfaexploit.com/)

```
kr0m
PASSWORD-SO

```

We configure the directories where to save the emails:

```
Bottom gear -> Folders
System Folders

```

We assign the directory to each Folder, we can click on the eye for Deleted items and Junk emails so they don’t show up.

<figure id="bkmrk--8">![](https://alfaexploit.com/images/mailFreeBSD/rainloop6.png)</figure>We perform tests of sending and receiving emails and check the associated logs:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fmai-2">tail -f /var/log/maillog</div>---

Sieve is an email classification service, through filters defined by the sysadmin/user we can classify incoming emails, for example based on certain headers, origins, this is very useful if we combine SpamAssassin with Sieve since SpamAssassin will mark emails with their headers and through Sieve we will filter based on these.

#### SpamAssassin

We install the Spamassassin milter:

<div class="box" id="bkmrk-pkg-install--y-spama">pkg install -y spamass-milter</div>We enable the spamd service indicating from which IPs it will accept connections, in this case the server’s own IP:

<div class="box" id="bkmrk-sysrc-spamd_enable%3D%22">sysrc spamd_enable="yes"  
sysrc spamd_flags="-u spamd -H /var/spool/spamd -A 192.168.69.17"</div>We enable the milter indicating where it should generate the Unix socket:

<div class="box" id="bkmrk-sysrc-spamass_milter">sysrc spamass_milter_enable="yes"  
sysrc spamass_milter_socket="/var/run/spamass-milter.sock"</div>The rest of the options that we can configure can be seen in:

<div class="box" id="bkmrk-cat-%2Fusr%2Flocal%2Fetc%2Fr">cat /usr/local/etc/rc.d/spamass-milter</div>```shell
: ${spamass_milter_enable="NO"}
: ${spamass_milter_socket="/var/run/spamass-milter.sock"}
: ${spamass_milter_flags="-f -p ${spamass_milter_socket} ${spamass_milter_localflags}"}
: ${spamass_milter_socket_owner="root"}
: ${spamass_milter_socket_group="wheel"}
: ${spamass_milter_socket_mode="644"}

```

We update the SpamAssassin rules and compile them:

<div class="box" id="bkmrk-sa-updatesa-compile">sa-update  
sa-compile</div>We start SpamAssassin and SpamAssassin-milter:

<div class="box" id="bkmrk-service-sa-spamd-sta">service sa-spamd start  
service spamass-milter start</div>We generate a base configuration file for SendMail:

<div class="box" id="bkmrk-cd-%2Fetc%2Fmail%2Fmake">cd /etc/mail/  
make</div>The above command will have generated a file with the name of the host, we define the milter at the end of the file:

<div class="box" id="bkmrk-vi-hellstorm.mc">vi HellStorm.mc</div>```txt
MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
define(`confINPUT_MAIL_FILTERS', `spamassassin')

```

We compile the new configuration to M4:

<div class="box" id="bkmrk-make">make</div>We update the SendMail configuration with ours:

<div class="box" id="bkmrk-cp-sendmail.cf-sendm">cp sendmail.cf sendmail.cf.ori  
cp HellStorm.cf sendmail.cf</div>We restart the service:

<div class="box" id="bkmrk-service-sendmail-res-2">service sendmail restart</div>We put a tail to see the logs, some errors will appear since SpamAssassin is not yet fully configured:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fmai-3">tail -f /var/log/maillog</div>We send ourselves an email and we can see in the logs how spamd intercepts the incoming email and assigns it a score:

```
Jan  1 19:42:55 HellStorm spamd[41333]: spamd: result: . -5 - DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_HI,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,TVD_SPACE_RATIO scantime=0.3,size=2793,user=root,uid=58,required_score=5.0,rhost=192.168.69.17,raddr=192.168.69.17,rport=50983,mid=<CA+SWLLzfBAmUfQQTmiFejuKVkaRpkZKdd7ECv3qXLrPaW-QJAQ@mail.gmail.com>,autolearn=unavailable autolearn_force=no 

```

If we look at the email in raw, we will see the headers added by SpamAssassin:

```
X-Spam-Status: No, score=-5.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
	DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE,
	RCVD_IN_DNSWL_HI,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,
	TVD_SPACE_RATIO autolearn=unavailable autolearn_force=no version=3.4.6
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on
	HellStorm.alfaexploit.com

```

**NOTE**: If we want to mark a specific domain or address as spam, we add it to the end of the local.cf file of SpamAssassin:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fma">vi /usr/local/etc/mail/spamassassin/local.cf</div>```txt
blacklist_from *@126.com
blacklist_from hacker@xxxxxxx.com

```

Restart the service:

<div class="box" id="bkmrk-service-sa-spamd-res">service sa-spamd restart</div>If you see errors like this in the logs:

```
Oct 21 22:21:19 DrWho spamd[3572]: plugin: eval failed: bayes: (in learn) locker: safe_lock: cannot create tmp lockfile /root/.spamassassin/bayes.lock.DrWho.alfaexploit.com.3572 for /root/.spamassassin/bayes.lock: Permission denied

```

You must define the [location of the database ](https://cwiki.apache.org/confluence/display/spamassassin/SiteWideBayesSetup)of SpamAssasin to a location where the user spamd has access:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fma-1">vi /usr/local/etc/mail/spamassassin/local.cf</div>```txt
bayes_path /var/spamassassin/bayes_db/bayes
bayes_file_mode 0775

```

Create the directory:

<div class="box" id="bkmrk-mkdir--p-%2Fvar%2Fspamas">mkdir -p /var/spamassassin/bayes_db/</div>Assign the permissions mentioned in the [documentation:](https://cwiki.apache.org/confluence/display/spamassassin/SiteWideBayesSetup)

<div class="box" id="bkmrk-chmod-775-%2Fvar%2Fspama">chmod 775 /var/spamassassin/bayes_db/  
chown root:spamd /var/spamassassin/bayes_db/</div>Restart the service:

<div class="box" id="bkmrk-service-sa-spamd-res-1">service sa-spamd restart</div>Now that we have marked our emails, we will have to categorize them according to the reputation assigned by SpamAssassin. For this, we will use Sieve, which will allow us to configure filters based on many aspects of the email, but to use it, we must make SendMail deliver local mails via LMTP to Dovecot:

<div class="box" id="bkmrk-cd-%2Fetc%2Fmail%2F">cd /etc/mail/</div><div class="box" id="bkmrk-vi-hellstorm.mc-1">vi HellStorm.mc</div>Replace:

```txt
FEATURE(local_lmtp)

```

With:

```txt
FEATURE(local_lmtp,`[IPC]',`FILE /var/run/dovecot/lmtp')dnl

```

Recompile the configuration:

<div class="box" id="bkmrk-make-1">make</div>Replace the current configuration with ours:

<div class="box" id="bkmrk-cp-hellstorm.cf-send">cp HellStorm.cf sendmail.cf</div>Restart the service:

<div class="box" id="bkmrk-service-sendmail-res-3">service sendmail restart</div>We install the necessary package for Dovecot to support Sieve:

<div class="box" id="bkmrk-pkg-install--y-dovec">pkg install -y dovecot-pigeonhole</div>We enable it as a protocol:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-4">vi /usr/local/etc/dovecot/dovecot.conf</div>```txt
protocols = imap lmtp sieve

```

And as an LMTP plugin:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-5">vi /usr/local/etc/dovecot/conf.d/20-lmtp.conf</div>```txt
protocol lmtp {
  mail_plugins = $mail_plugins sieve
}

```

In the plugin configuration, we set where the users’ Sieve filters will be stored and which filter should be applied. We also indicate a filter that will always be executed before those defined by the user, ideal for sysadmins to perform their pre-user filtering:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fdo-6">vi /usr/local/etc/dovecot/conf.d/90-plugin.conf</div>```txt
plugin {
    sieve = file:~/.sieve;active=~/.sieve/dovecot.sieve
    sieve_before = file:/var/lib/dovecot/default.sieve
}

```

When scripting in Sieve, the required libraries must be indicated at the top and then used throughout the rest of the script:

<div class="box" id="bkmrk-mkdir-%2Fvar%2Flib%2Fdovec">mkdir /var/lib/dovecot</div><div class="box" id="bkmrk-vi-%2Fvar%2Flib%2Fdovecot%2F">vi /var/lib/dovecot/default.sieve</div>```txt
require ["fileinto"];
  
if header :contains "X-Spam-Flag" "YES" {
    fileinto "Spam";
    stop;
}

```

We compile the script:

<div class="box" id="bkmrk-sievec-%2Fvar%2Flib%2Fdove">sievec /var/lib/dovecot/default.sieve</div>We create the Sieve scripts directory in the user’s home directory:

<div class="box" id="bkmrk-su--l-kr0mmkdir-%2Fhom">su -l kr0m  
mkdir /home/kr0m/.sieve  
exit</div>We check that Dovecot’s LMTP module has loaded the Sieve plugin:

<div class="box" id="bkmrk-doveconf--f-service%3D">doveconf -f service=lmtp mail_plugins</div>```shell
mail_plugins = sieve

```

We restart Dovecot:

<div class="box" id="bkmrk-service-dovecot-rest">service dovecot restart</div>We manually connect to the Sieve-manager:

<div class="box" id="bkmrk-telnet-127.0.0.1-419">telnet 127.0.0.1 4190</div>```shell
Trying 127.0.0.1...
Connected to HellStorm.
Escape character is '^]'.
"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext"
"NOTIFY" "mailto"
"SASL" "PLAIN"
"VERSION" "1.0"
OK "Dovecot ready."

```

The sieve\_before script (/var/lib/dovecot/default.sieve) that moves emails marked as spam by SpamAssassin to the Spam directory should already be running.

We access the RainLoop administration panel and enable Sieve for our domain:  
[http://mail.alfaexploit.com/?admin](http://mail.alfaexploit.com/?admin)

```
admin
XXXXXXX

```

```
Domains -> alfaexploit.com

```

<figure id="bkmrk--10">![](https://alfaexploit.com/images/mailFreeBSD/rainloop1.png)</figure>```
Sieve configuration:
Allow sieve scripts
Allow custom user script

```

```
Server: 192.168.69.17 Port: 4190
Secure: None

```

<figure id="bkmrk--11">![](https://alfaexploit.com/images/mailFreeBSD/rainloop2.png)</figure>Click on the Update button.

Access with the normal user account and configure a filter:

```
Configuration -> Filters

```

<figure id="bkmrk--12">![](https://alfaexploit.com/images/mailFreeBSD/rainloop3.png)</figure>NOTE: We must filter network traffic through a [firewall ](https://alfaexploit.com/en/posts/basic_pf)to prevent unauthorized access to Sieve(4190)/SpamAssassin(783) services.

---

#### SPF

Through [SPF ](https://en.wikipedia.org/wiki/Sender_Policy_Framework)we will indicate which servers are authorized to send emails from our domain, this is nothing more than DNS entries indicating the IPs, in my case it would be as follows.

```
A 92.176.161.228 mail.alfaexploit.com
MX mail.alfaexploit.com
TXT spf2.0/mfrom,pra a mx -all
TXT v=spf1 mx -all

```

**NOTE**: The first entry is a simple A entry resolving mail.alfaexploit.com to the IP, the second indicates which server(MX) is responsible for receiving emails, the third indicates that the IP of the server indicated in the MX record of the domain is authorized to send emails and the fourth does the same as the third but it is spf1.

SPF supports two types of fails:

- hardfails: Any email coming from an unauthorized IP will be deleted, this behavior is indicated by entering -all in the DNS entry.
- softfail: Any email coming from an unauthorized IP will be marked as Spam, this behavior is indicated by entering ~all in the DNS entry.

We check that all entries resolve as they should:

<div class="box" id="bkmrk-dig-mx-alfaexploit.c">dig mx alfaexploit.com +short</div>```shell
0 mail.alfaexploit.com.

```

<div class="box" id="bkmrk-dig-mail.alfaexploit">dig mail.alfaexploit.com +short</div>```shell
79.116.145.12

```

<div class="box" id="bkmrk-dig-txt-alfaexploit.">dig txt alfaexploit.com +short</div>```shell
"spf2.0/mfrom,pra a mx ~all"
"v=spf1 mx ~all"

```

---

#### DKIM

Through [DKIM ](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail)we will be able to sign outgoing emails with a private key so that the recipient can verify that the email was sent from our server and not from another pretending to be us, the key to this process is to publish the pubkey in a DNS entry so that the recipient can obtain it and thus verify the authenticity of the email.

We install the OpenDkim milter:

<div class="box" id="bkmrk-pkg-install--y-opend">pkg install -y opendkim</div>We enable the service:

<div class="box" id="bkmrk-sysrc-milteropendkim">sysrc milteropendkim_enable=yes</div>We generate the private-key/pub-key pair:

<div class="box" id="bkmrk-mkdir-%2Fvar%2Fdb%2Fdkimcd">mkdir /var/db/dkim  
cd /var/db/dkim  
opendkim-genkey -s smtp -d alfaexploit.com</div>**NOTE**: The -s smtp parameter is just the selector, it is a string with which the DNS query will have to be made to obtain the value of the pubkey.

The OpenDkim configuration would be as follows:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fma-2">vi /usr/local/etc/mail/opendkim.conf</div>```txt
Domain          alfaexploit.com
KeyFile         /var/db/dkim/smtp.private
InternalHosts   /var/db/dkim/internal_hosts
Selector        smtp
Socket          local:/var/run/milteropendkim/milter-opendkim.sock
Syslog          Yes

```

We adjust the permissions so that OpenDkim can generate the unix socket file:

<div class="box" id="bkmrk-chown-mailnull%3Amailn">chown mailnull:mailnull /var/run/milteropendkim/</div>We define which IPs can connect to the milter, in my case the IP of the server itself:

<div class="box" id="bkmrk-vi-%2Fvar%2Fdb%2Fdkim%2Finte">vi /var/db/dkim/internal_hosts</div>```txt
192.168.69.17

```

We start the service:

<div class="box" id="bkmrk-service-milter-opend">service milter-opendkim start</div>We configure SendMail to use the new milter:

<div class="box" id="bkmrk-cd-%2Fetc%2Fmail">cd /etc/mail</div><div class="box" id="bkmrk-vi-hellstorm.mc-2">vi HellStorm.mc</div>```txt
MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
MAIL_FILTER(`dkim-filter', `S=/var/run/milteropendkim/milter-opendkim.sock, F=T, T=R:2m')
define(`confINPUT_MAIL_FILTERS', `spamassassin, dkim-filter')

```

We compile and update the configuration:

<div class="box" id="bkmrk-makecp-hellstorm.cf-">make  
cp HellStorm.cf sendmail.cf</div>We restart the service:

<div class="box" id="bkmrk-service-sendmail-res-4">service sendmail restart</div>If we send an email, we will see that they are signed.

```
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=alfaexploit.com; s=smtp; t=1672616405; bh=G1jVXBHX92kUkSHkyQ6MzL5LYYAW8yEUeAJmHQPkbeQ=; h=Date:From:Subject:To; b=u49nGRAoDNY0tWxab5lbE7GSDvJ796snMaJbMDKA9+Iz5NSxeqGbfCCswsDo+yuZ8
	 96TXfWXO0tzo0kjSqCcrm5s2gdhNPeG9Q2+eTjs71pXJS7sonqw4AncamPQl2kOx3i
	 ZFCq67c/BK+gup601dSdrurFVLt57jpgUcOwD9Kc=

```

But we must publish our pubkey on the Internet so that servers that receive our emails can verify that the email signature was generated with the private key corresponding to the published pubkey:

<div class="box" id="bkmrk-cat-%2Fvar%2Fdb%2Fdkim%2Fsmt">cat /var/db/dkim/smtp.txt</div>```shell
smtp._domainkey    IN    TXT    ( "v=DKIM1; k=rsa; "
      "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+6l6oAODR0hUzsHqb2StBHVKlXdemKhbRNaCNDdoqMH9yi7TOfYeO4Ko5Wnp4Gq449ur8h14Afvgji24DC6GCBNbHCcDh67M9HZW28BJPRoaaIInQHzt5+9oVa9BREliNa50gfbwmNS/WnrZ6o3X94xCCbb6xcdQJC6FCrGoyMQIDAQAB" )  ; ----- DKIM key smtp for alfaexploit.com

```

The TXT record will have the following content:

```
v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+6l6oAODR0hUzsHqb2StBHVKlXdemKhbRNaCNDdoqMH9yi7TOfYeO4Ko5Wnp4Gq449ur8h14Afvgji24DC6GCBNbHCcDh67M9HZW28BJPRoaaIInQHzt5+9oVa9BREliNa50gfbwmNS/WnrZ6o3X94xCCbb6xcdQJC6FCrGoyMQIDAQAB

```

The final DNS entry should contain the selector (smtp):

```
TXT smtp._domainkey v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+6l6oAODR0hUzsHqb2StBHVKlXdemKhbRNaCNDdoqMH9yi7TOfYeO4Ko5Wnp4Gq449ur8h14Afvgji24DC6GCBNbHCcDh67M9HZW28BJPRoaaIInQHzt5+9oVa9BREliNa50gfbwmNS/WnrZ6o3X94xCCbb6xcdQJC6FCrGoyMQIDAQAB

```

If we consult the entry, it returns the configured pubkey:

<div class="box" id="bkmrk-dig-txt-smtp._domain">dig TXT smtp._domainkey.alfaexploit.com +short</div>```shell
"v=DKIM1;k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+6l6oAODR0hUzsHqb2StBHVKlXdemKhbRNaCNDdoqMH9yi7TOfYeO4Ko5Wnp4Gq449ur8h14Afvgji24DC6GCBNbHCcDh67M9HZW28BJPRoaaIInQHzt5+9oVa9BREliNa50gfbwmNS/WnrZ6o3X94xCCbb6xcdQJC6FCrGoyMQIDAQAB;t=s;"

```

---

#### DMARC

[DMARC ](https://en.wikipedia.org/wiki/DMARC)are DNS records where we indicate to email servers what to do when the incoming email does not pass SPF/DKIM. Of course, each ISP can then respect what is indicated in the DMARC or not.

```
TXT _dmarc.alfaexploit.com
v=DMARC1\; p=reject\; rua=mailto:kr0m@alfaexploit.com\; ruf=mailto:kr0m@alfaexploit.com\; pct=100

```

Let’s break down each of the fields:

- v: Protocol version
- p: Indicates the DMARC policy to follow
- rua: Where notifications will be sent when an email that does not pass SPF/DKIM is received
- ruf: Where a copy of the spam emails will be sent when an email that does not pass SPF/DKIM is received
- pct: What percentage of received emails should have the DMARC filter applied

The possible policies are:

- none: Treat the email without applying DMARC
- quarantine: Accept the email but treat it as spam
- reject: Reject the email

We check that the DNS record responds with the correct information:

<div class="box" id="bkmrk-dig-txt-_dmarc.alfae">dig TXT _dmarc.alfaexploit.com +short</div>```shell
"v=DMARC1; p=reject; rua=mailto:kr0m@alfaexploit.com; ruf=mailto:kr0m@alfaexploit.com; pct=100"

```

We can see how Google approves the three checks:

<figure id="bkmrk--17">![](https://alfaexploit.com/images/mailFreeBSD/spfdkimdmarc.png)</figure>---

#### SSL RainLoop

If we are going to access the RainLoop interface from the Internet, it is better to do it through SSL.

To do this, we will reconfigure Nginx by temporarily removing the include of the rainloop.conf file:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fng-1">vi /usr/local/etc/nginx/nginx.conf</div>```nginx
...
http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 25M;
    #include rainloop.conf;
...

```

We restart the service:

<div class="box" id="bkmrk-service-nginx-restar">service nginx restart</div>We install ACME:

<div class="box" id="bkmrk-pkg-install--y-curl-">pkg install -y curl socat  
curl [https://get.acme.sh ](https://get.acme.sh/)| sh -s <email=kr0m@alfaexploit.com></div>We issue the certificate request:

<div class="box" id="bkmrk-%2Froot%2F.acme.sh%2Facme.">/root/.acme.sh/acme.sh --issue -d mail.alfaexploit.com -w /usr/local/www/nginx --renew-hook 'service nginx restart'</div>```shell
[Mon Jan  2 08:02:05 CET 2023] Your cert is in: /root/.acme.sh/mail.alfaexploit.com/mail.alfaexploit.com.cer
[Mon Jan  2 08:02:05 CET 2023] Your cert key is in: /root/.acme.sh/mail.alfaexploit.com/mail.alfaexploit.com.key
[Mon Jan  2 08:02:05 CET 2023] The intermediate CA cert is in: /root/.acme.sh/mail.alfaexploit.com/ca.cer
[Mon Jan  2 08:02:05 CET 2023] And the full chain certs is there: /root/.acme.sh/mail.alfaexploit.com/fullchain.cer

```

We include rainloop.conf again:

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fng-2">vi /usr/local/etc/nginx/nginx.conf</div>```nginx
...
http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 25M;
    #include rainloop.conf;
...

```

But this time it will only listen on port 443, and since my traffic goes through a traffic balancer, I use [proxy\_protocol ](https://alfaexploit.com/en/posts/proxy_protocol):

<div class="box" id="bkmrk-vi-%2Fusr%2Flocal%2Fetc%2Fng-3">vi /usr/local/etc/nginx/rainloop.conf</div>```nginx
server {

  listen 443 ssl proxy_protocol;
  server_name mail.alfaexploit.com;

  set_real_ip_from 192.168.69.11;
  real_ip_header proxy_protocol;

  root /usr/local/www/rainloop;

  ssl_certificate "/root/.acme.sh/mail.alfaexploit.com/fullchain.cer";
  ssl_certificate_key "/root/.acme.sh/mail.alfaexploit.com/mail.alfaexploit.com.key";

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ^~ /data {
     deny all;
  }

  location ~ \.php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_keep_conn on;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
  }
  
}

```

We restart the service:

<div class="box" id="bkmrk-service-nginx-restar-1">service nginx restart</div>---

#### SSL Sendmail

By default, SendMail comes with SSL enabled with self-signed certificates:

```
dnl Enable STARTTLS for receiving email.
define(`CERT_DIR', `/etc/mail/certs')dnl
define(`confSERVER_CERT', `CERT_DIR/host.cert')dnl
define(`confSERVER_KEY', `CERT_DIR/host.key')dnl
define(`confCLIENT_CERT', `CERT_DIR/host.cert')dnl
define(`confCLIENT_KEY', `CERT_DIR/host.key')dnl
define(`confCACERT', `CERT_DIR/cacert.pem')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confDH_PARAMETERS', `CERT_DIR/dh.param')dnl

```

To configure ours, we will first make a copy of the originals:

<div class="box" id="bkmrk-cp--r-%2Fetc%2Fmail%2Fcert">cp -r /etc/mail/certs /etc/mail/certs.ori</div>The certificates are obtained on the web server, so we synchronize them using the following script:

<div class="box" id="bkmrk-vi-%7E%2F.scripts%2Fget_al">vi ~/.scripts/get_alfaexploit_certs.sh</div>```bash
#!/usr/local/bin/bash

function sendTelegram {
        message=${@:1}
        #curl -s -X POST https://api.telegram.org/botAPI_KEY/sendMessage -d chat_id=CHAT_ID -d text="$message"
        curl -s -X POST https://api.telegram.org/bot535179217:AAGXRe1df_1WNgqxOCfC8VrCNKGqouhslLw/sendMessage -d chat_id=30418601 -d text="$message"
}

if [ -f "/etc/mail/certs/alfaexploit.com/fullchain.cer" ] && [ -f "/etc/mail/certs/alfaexploit.com/alfaexploit.com.key" ] && [ -f "/etc/mail/certs/alfaexploit.com/ca.cer" ]; then
    mv /etc/mail/certs/alfaexploit.com/fullchain.cer /etc/mail/certs/alfaexploit.com/fullchain.cer.ori
    mv /etc/mail/certs/alfaexploit.com/alfaexploit.com.key /etc/mail/certs/alfaexploit.com/alfaexploit.com.key.ori
    mv /etc/mail/certs/alfaexploit.com/ca.cer /etc/mail/certs/alfaexploit.com/ca.cer.ori
    PREV_CERTS_FOUND=1
else
    PREV_CERTS_FOUND=0
fi

if [ ! -d /etc/mail/certs/alfaexploit.com/ ]; then
    mkdir /etc/mail/certs/alfaexploit.com/
fi
fetch http://admin:XXXX@192.168.69.19:8080/fullchain.cer -o /etc/mail/certs/alfaexploit.com/fullchain.cer
if [ $? -ne 0 ]; then
    sendTelegram "$HOSTNAME-SMTP/SSL: Cant download http://admin:XXXX@192.168.69.19:8080/fullchain.cer"
fi
fetch http://admin:XXXX@192.168.69.19:8080/alfaexploit.com.key -o /etc/mail/certs/alfaexploit.com/alfaexploit.com.key
if [ $? -ne 0 ]; then
    sendTelegram "$HOSTNAME-SMTP/SSL: Cant download http://admin:XXXX@192.168.69.19:8080/alfaexploit.com.key"
fi
fetch http://admin:XXXX@192.168.69.19:8080/ca.cer -o /etc/mail/certs/alfaexploit.com/ca.cer
if [ $? -ne 0 ]; then
    sendTelegram "$HOSTNAME-SMTP/SSL: Cant download http://admin:XXXX@192.168.69.19:8080/ca.cer"
fi
chmod 600 /etc/mail/certs/alfaexploit.com/*

if [ $PREV_CERTS_FOUND -eq 1 ]; then
    for file in /etc/mail/certs/alfaexploit.com/*.ori; do
      md5_ori=$(md5 $file|awk '{print$4}')
      file=${file::-4}
      md5=$(md5 $file|awk '{print$4}')
      #echo "md5_ori: $md5_ori -- md5: $md5"
      if [ "$md5_ori" != "$md5" ]; then
        echo ">> New certs detected -> Restarting SendMail"
        service sendmail restart
        sendTelegram "$HOSTNAME:25-SSL alfaexploit certificates updated"
        break
      fi
    done
fi

check=$(echo Q|openssl s_client -connect 192.168.69.17:25 -starttls smtp 2>/dev/null | grep '0 s:' | grep 'CN =' | awk -F "CN = " '{print$2}' | awk -F "," '{print$1}')
#echo "check: $check"
if [ "$check" != "alfaexploit.com" ]; then
    sendTelegram "$HOSTNAME-SMTP/SSL Incorrect CommonName: $check"
fi

```

We assign the necessary permissions:

<div class="box" id="bkmrk-chmod-700-%7E%2F.scripts">chmod 700 ~/.scripts/get_alfaexploit_certs.sh</div>We add it to the crontab:

<div class="box" id="bkmrk-crontab--e">crontab -e</div>```
*/30 * * * * /root/.scripts/get_alfaexploit_certs.sh >/dev/null 2>&1

```

Once copied, we perform the following configuration:

<div class="box" id="bkmrk-cd-%2Fetc%2Fmail-1">cd /etc/mail</div><div class="box" id="bkmrk-vi-hellstorm.mc-3">vi HellStorm.mc</div>```txt
dnl Enable STARTTLS for receiving email.
define(`CERT_DIR', `/etc/mail/certs/alfaexploit.com')dnl
define(`confSERVER_CERT', `CERT_DIR/fullchain.cer')dnl
define(`confSERVER_KEY', `CERT_DIR/alfaexploit.com.key')dnl
define(`confCLIENT_CERT', `CERT_DIR/fullchain.cer')dnl
define(`confCLIENT_KEY', `CERT_DIR/alfaexploit.com.key')dnl
define(`confCACERT', `CERT_DIR/ca.cer')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl

```

We compile the configuration:

<div class="box" id="bkmrk-makecp-hellstorm.cf--1">make  
cp HellStorm.cf sendmail.cf</div>We restart the service:

<div class="box" id="bkmrk-service-sendmail-res-5">service sendmail restart</div>We leave a tail in the log to make sure everything is still working:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fmai-4">tail -f /var/log/maillog</div>We perform a manual test to verify that the correct certificate is being used:

<div class="box" id="bkmrk-echo-q%7Copenssl-s_cli">echo Q|openssl s_client -connect mail.alfaexploit.com:25 -starttls smtp 2&gt;/dev/null|grep ‘Verification:’</div>```shell
Verification: OK

```

One way to check SSL for both incoming and outgoing mail is through this website:  
[https://ssl-tools.net/mailservers](https://ssl-tools.net/mailservers)  
[https://ssl-tools.net/mails](https://ssl-tools.net/mails)

---

#### Reverse DNS

Regarding reverse DNS, GMail/HotMail/OVH servers only require that the origin IP of the email has a reverse, it doesn’t matter what the reverse is, they **DO NOT** require it to match the origin domain of the email.

---

#### Account maintenance

Over time, mailboxes can fill up with emails due to neglect by users, thus causing excessive disk space consumption, SMTP denial of service, or even causing problems for the entire operating system if the disk is not partitioned correctly or disk quotas are not applied.

Dovecot provides an email system management tool called [doveadm ](https://wiki.dovecot.org/Tools/Doveadm)which also provides useful commands for user account administration.

We can see where the user stores their emails with the following command:

<div class="box" id="bkmrk-doveadm-user-kr0m">doveadm user kr0m</div>```shell
field	value
uid	1001
gid	1001
home	/home/kr0m
mail	mbox:~/mboxDir:INBOX=/var/mail/kr0m
system_groups_user	kr0m

```

We can check the email folders:

<div class="box" id="bkmrk-doveadm-mailbox-list">doveadm mailbox list -u kr0m</div>```shell
Drafts
Trash
Archive
Sent
Spam
INBOX

```

We can see the general status of each folder:

<div class="box" id="bkmrk-doveadm-mailbox-stat">doveadm mailbox status -u kr0m all Spam</div>```shell
Spam messages=4 recent=0 uidnext=2343 uidvalidity=1584649428 unseen=4 highestmodseq=4277 vsize=31212 guid=1e54ce3009d6735e13310000d09efc50 firstsaved=1661967302

```

We can also get a list of emails in that folder:

<div class="box" id="bkmrk-doveadm--f-tab-fetch">doveadm -f tab fetch -u kr0m "uid date.saved" mailbox Spam</div>```shell
uid	date.saved
2339	2022-08-31 19:35:02
2340	2022-09-01 07:14:41
2341	2022-09-01 09:25:54
2342	2022-09-01 22:00:09

```

It’s very useful to perform a search before deleting emails to make sure we’re deleting the correct content:

<div class="box" id="bkmrk-doveadm-search--u-kr">doveadm search -u kr0m mailbox Spam savedbefore 1d</div>```shell
1e54ce3009d6735e13310000d09efc50 2339
1e54ce3009d6735e13310000d09efc50 2340

```

We delete the emails:

<div class="box" id="bkmrk-doveadm-expunge--u-k">doveadm expunge -u kr0m mailbox Spam savedbefore 1d</div>If we check now, we’ll see that only two emails remain:

<div class="box" id="bkmrk-doveadm--f-tab-fetch-1">doveadm -f tab fetch -u kr0m "uid date.saved" mailbox Spam</div>```shell
uid	date.saved
2341	2022-09-01 09:25:54
2342	2022-09-01 22:00:09

```

<div class="box" id="bkmrk-doveadm-mailbox-stat-1">doveadm mailbox status -u kr0m all Spam</div>```shell
Spam messages=2 recent=0 uidnext=2343 uidvalidity=1584649428 unseen=2 highestmodseq=4278 vsize=15667 guid=1e54ce3009d6735e13310000d09efc50 firstsaved=1662017154

```

It’s a good idea to schedule a script to clean the accounts periodically:

<div class="box" id="bkmrk-vi-%7E%2F.scripts%2Fclearm">vi ~/.scripts/clearMail</div>```bash
#!/usr/local/bin/bash
/usr/local/bin/doveadm expunge -u kr0m mailbox Spam savedbefore 1d
/usr/local/bin/doveadm expunge -u kr0m mailbox Trash savedbefore 7d

```

Assign the necessary permissions to the script:

<div class="box" id="bkmrk-chmod-700-%7E%2F.scripts-1">chmod 700 ~/.scripts/clearMail</div>Schedule the script:

<div class="box" id="bkmrk-crontab--e-1">crontab -e</div>```sh
00 00 * * * /root/.scripts/clearMail >/dev/null 2>&1

```

The [expunge ](https://wiki.dovecot.org/Tools/Doveadm/Expunge)command allows executing commands on all existing users but NOT when system users are being used:

```
If the -A option is present, the command will be performed for all users.
Using this option in combination with system users from userdb { driver = passwd } is not recommended, because it contains also users with a lower UID than the one configured with the first_valid_uid setting.
When the SQL userdb module is used make sure that the iterate_query setting in /etc/dovecot/dovecot-sql.conf.ext matches your database layout. When using the LDAP userdb module, make sure that the iterate_attrs and iterate_filter settings in /etc/dovecot/dovecot-ldap.conf.ext match your LDAP schema. Otherwise doveadm(1) will be unable to iterate over all users.

```

---

#### Debug

We can enable Dovecot and Sieve debug by configuring certain parameters:

<div class="box" id="bkmrk-vi-conf.d%2F10-logging">vi conf.d/10-logging.conf</div>```txt
log_path = syslog
syslog_facility = mail
mail_debug = yes

```

Check the logs:

<div class="box" id="bkmrk-tail--f-%2Fvar%2Flog%2Fdeb">tail -f /var/log/debug.log</div>We can dump the entire running-config of Dovecot with:

<div class="box" id="bkmrk-doveconf--a">doveconf -a</div>The plugins loaded in the Dovecot LMTP service:

<div class="box" id="bkmrk-doveconf--f-service%3D-1">doveconf -f service=lmtp mail_plugins</div>Some interesting links:  
[https://wiki.dovecot.org/Pigeonhole/Sieve/Troubleshooting](https://wiki.dovecot.org/Pigeonhole/Sieve/Troubleshooting)  
[https://wiki1.dovecot.org/Logging](https://wiki1.dovecot.org/Logging)

A very interesting website when experiencing deliverability issues is:  
[https://mxtoolbox.com/](https://mxtoolbox.com/)