# FreeBSD

# Смена shell на zsh

#### Установка пакетов

```bash
sudo pkg install zsh ohmyzsh zsh-antigen zsh-autosuggestions zsh-completions zsh-navigation-tools zsh-syntax-highlighting
```

#### Копирование шаблона конфигурации ohmyzsh в локальный профиль

```bash
sudo cp /usr/local/share/ohmyzsh/templates/zshrc.zsh-template ~/.zshrc
```

#### Включаем автоматическое дополнение

В конфигурационный файл `~/.zshrc` добавляем `source /usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh`

#### Меняем shell пользователя

```bash
sudo chsh -s zsh <user name>
```

# Управление пользователями

### Вывод списка групп пользователя

```bash
id <user_name>
```

### Вывод списка пользователей группы

```bash
pw group show <group_name>
```

### Добавление пользователя в группу

```
pw useradd <user_name> -G <group_name>
```

### Добавление пользователя в группу с сохранением членства в других

```
pg group mod <group_name> -m <user_name01>,<user_name02>
```

### Добавление пользователя в группу с заменой существующего членства

```
pw usermod <user_name> -G <group_name01>,<group_name02>
```

### Список используемых источников

- [FreeBSD add a user to group](https://www.cyberciti.biz/faq/freebsd-add-a-user-to-group/)

# Межсетевые экраны

# Ipfw

Когда-то давно мы настраивали фаервол в Linux с помощью iptables. При этом отмечалось, что утилиту iptables я нахожу исключительно неудобной по сравнению с FreeBSD’шным ipfw. Сегодня мы наконец-то познакомимся с этим ipfw и постараемся ответить на вопрос, действительно ли он удобнее. Отмечу, что на момент написания этих строк FreeBSD предлагает аж *три* фаервола на выбор — ipfw, pf и ipf. Однако по моим представлениям из них ipfw используется чаще всего. <span id="bkmrk-"></span>

Описанные в этом посте действия были проверены мной на FreeBSD 10.3, но по идее не должны ничем отличаться в других версиях FreeBSD.

Итак, первое, что требуется выполнить при настройке ipfw — это команду:

```shell
sudo kenv net.inet.ip.fw.default_to_accept=1
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9F%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E-ipfw-%D0%B7%D0%B0" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">По умолчанию ipfw запрещает передачу вообще всех пакетов. Если вы сидите на сервере по ssh, что весьма вероятно, и просто включите ipfw, то на сервер вы больше не зайдете до следующего ребута. Приведенная команда временно меняет поведение ipfw на «разрешить всем и все», тем самым решая описанную проблему.</div></div>Теперь включаем ipfw:

```shell
sudo kldload ipfw
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9F%D1%80%D0%B8-%D1%8D%D1%82%D0%BE%D0%BC-%D0%B2-%2Fvar%2Flog%2F" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">При этом в /var/log/messages мы должны увидеть что-то вроде:</div></div>```shell
ipfw2 (+ipv6) initialized, divert loadable, nat loadable,
  default to accept, logging disabled
```

<div class="codecolorer-container text default" id="bkmrk-%D0%9A%D0%B0%D0%BA-%D0%B2%D0%B8%D0%B4%D0%B8%D1%82%D0%B5%2C-ipfw-%D0%BF%D1%80%D0%B5" style="overflow: auto; white-space: nowrap;"><div class="text codecolorer">Как видите, ipfw представляет собой обычный модуль ядра.</div></div>Давайте посмотрим на текущий список правил:

```
sudo ipfw list
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%94%D0%BE%D0%BB%D0%B6%D0%BD%D1%8B-%D1%83%D0%B2%D0%B8%D0%B4%D0%B5%D1%82%D1%8C%3A" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Должны увидеть:</div></div>```shell
65535 allow ip from any to any
```

<div class="codecolorer-container text default" id="bkmrk-%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8" style="overflow: auto; white-space: nowrap;"><div class="text codecolorer">Приведенный синтаксис довольно очевидный — номер правила, резрешить / запретить, название протокола, от кого, к кому. Тут мы видим правило с номером 65535, разрешающее передачу входящих и исходящих IP пакетов от кого угодно кому угодно на всех интерфейсах.</div></div>Также можно посмотреть время, когда правило последний раз срабатывало:

```shell
sudo ipfw -t list
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%94%D0%B0%D0%B2%D0%B0%D0%B9%D1%82%D0%B5-%D0%BF%D0%BE%D0%BF%D1%80%D0%BE%D0%B1%D1%83%D0%B5%D0%BC-%D0%B4%D0%BE" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Давайте попробуем добавить парочку правил. Например, запретим пинги:</div></div>```shell
# флаг -q выполняет команду в "тихом" режиме, без вывода
sudo ipfw -q add 00100 deny icmp from any to any
sudo ipfw list
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9A%D0%B0%D0%BA-%D0%B2%D0%B8%D0%B4%D0%B8%D1%82%D0%B5%2C-%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D1%8F" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Как видите, указывая номер правила, мы знаем точно, на какую позицию оно встанет. Принцип простой. При получении новых пакетов сначала проверяются правила с меньшими номерами, потом с большими. Когда находится совпавшее по условиям правило, оно срабатывает, а следующие за ним правила игнорируются.</div></div>Попытаемся что-нибудь пингануть и убедимся, что пинги больше не ходят. Теперь, когда мы осознали свою ошибку, удаляем правило:

```shell
sudo ipfw -q delete 00100
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%97%D0%B0%D0%BC%D0%B5%D1%82%D1%8C%D1%82%D0%B5%2C-%D1%87%D1%82%D0%BE-ipfw-%D0%BF" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Заметьте, что ipfw позволяет создавать множество правил с одинаковыми номерами. В этом случае их можно удалить одной командой. Также можно удалить вообще все правила, оставив только правило по умолчанию:</div></div>```shell
sudo ipfw -q -f flush
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9F%D0%B5%D1%80%D0%B5%D0%B4-%D1%82%D0%B5%D0%BC%2C-%D0%BA%D0%B0%D0%BA-%D1%80%D0%B5%D0%B0%D0%BB%D1%8C" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Перед тем, как реально добавлять правило, не лишним бывает собрать статистику о том, как много пакетов ему соответствует:</div></div>```shell
sudo ipfw -q add 00100 count udp from me to any out via em0
sudo ipfw -q add 00200 count udp from any to me in via em0
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9A%D0%B0%D0%BA-%D0%B2%D0%B8%D0%B4%D0%B8%D1%82%D0%B5%2C-%D1%82%D1%83%D1%82-%D0%B4%D0%B5%D0%BC%D0%BE" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Как видите, тут демонстрируется не только новое действие (count), но и расширенный синтаксис с частью in/out и указанием конкретного сетевого интерфейса. Кстати, при срабатывании count-правила следующие за ним правила *продолжают* применяться.</div></div>Теперь посмотрим количество пакетов с их суммарным размером в байтах, соответствующих правилу:

<div class="codecolorer-container bash default" id="bkmrk--1" style="overflow: auto; white-space: nowrap;"><div class="codecolorer-container bash default" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer"><span class="kw2"></span></div></div></div>```shell
sudo ipfw -a list
# или:
sudo ipfw show
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%A1%D1%87%D0%B5%D1%82%D1%87%D0%B8%D0%BA%D0%B8-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D0%BF%D1%80%D0%B8-%D0%B6" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Счетчики можно при желании обнулить так:</div></div>```shell
# для конкретного правила
sudo ipfw zero 00200

# для всех правил
sudo ipfw zero
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%92-%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0%D1%85-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D0%B8%D1%81%D0%BF" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">В правилах можно использовать не только слова `<span class="text">me</span>` и `<span class="text">any</span>`, но и указывать конкретные хосты или подсети:</div></div>```shell
sudo ipfw -q add 00100 deny tcp from any to 192.168.0.1
sudo ipfw -q add 00200 deny tcp from any to 192.168.0.1/24
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%A2%D0%B0%D0%BA%D0%B6%D0%B5-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D1%82" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Также можно указывать порты или диапазоны портов:</div></div>```shell
sudo ipfw -q add 00100 deny tcp from any to 192.168.0.1/24 80
sudo ipfw -q add 00200 deny tcp from any to 192.168.0.1/24 1-1024
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9F%D0%BE%D0%BC%D0%B8%D0%BC%D0%BE-%D1%81%D0%B1%D0%BE%D1%80%D0%B0-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Помимо сбора статистики о срабатывании правил, их также можно логировать:</div></div>```shell
sudo ipfw enable verbose
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BB%D0%BE" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Пример добавления логируемых правил:</div></div>```shell
sudo ipfw -q add 00200 deny log \
  tcp from any to 212.193.240.1/24 80

sudo ipfw -q add 00200 deny log logamount 3 \
  tcp from any to 212.193.240.1/24 80
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%95%D1%81%D0%BB%D0%B8-%D1%82%D0%B5%D0%BF%D0%B5%D1%80%D1%8C-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Если теперь несколько раз попытаться прителнетиться к хосту из используемой выше сети и заглянуть в /var/log/security, то увидим что-то вроде:</div></div>```shell
ipfw: 200 Deny TCP 10.0.2.15:41738 212.193.240.242:80 out via em0
ipfw: 200 Deny TCP 10.0.2.15:43564 212.193.240.242:80 out via em0
ipfw: 200 Deny TCP 10.0.2.15:55804 212.193.240.242:80 out via em0
ipfw: limit 3 reached on entry 200
```

<div class="codecolorer-container text default" id="bkmrk-%D0%9B%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE-%D0%B3%D0%BB" style="overflow: auto; white-space: nowrap;"><div class="text codecolorer">Логирование можно глобально включать и выключать таким образом:</div></div>```shell
sudo sysctl net.inet.ip.fw.verbose=1
sudo sysctl net.inet.ip.fw.verbose=0
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%95%D1%81%D0%BB%D0%B8-%D0%B2-%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B5-%D0%BD%D0%B5-%D1%83%D0%BA" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Если в правиле не указывается logamount, используется следующее значение:</div></div>```shell
sudo sysctl net.inet.ip.fw.verbose_limit=5
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Значение по умолчанию равно нулю, что означает отсутствие ограничений.</div></div>Сбросить счетчики логирования можно так:

```shell
sudo ipfw resetlog
```

```shell
Для сохранения правил при перезагрузке системы создадим файл /etc/ipfw.rules следующего содержания:
#!/bin/sh

fwcmd="ipfw -q add"

ipfw -q -f flush

$fwcmd 00100 deny log tcp from any to 1.2.3.0/24
$fwcmd 00200 deny log tcp from any to 4.5.6.0/24
$fwcmd 65000 allow ip from any to any
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%92%D0%B0%D0%B6%D0%BD%D0%BE%21-%D0%95%D1%81%D0%BB%D0%B8-%D1%85%D0%BE%D1%82%D0%B8%D1%82%D0%B5-%D0%BF" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">**Важно!** Если хотите подключиться к машине после перезагрузки, обязательно добавьте последнее правило. Сейчас оно добавляется автоматически, благодаря описанному выше хаку с `<span class="text">net.inet.ip.fw.default_to_accept</span>`. Однако после ребута вернется поведение фаервола по умолчанию, при котором запрещается вообще все.</div></div>Заметьте, что только что мы написали обыкновенный шелл скрипт. Следовательно, в нем можно использовать сокращения имен команд, как продемонстрировано выше, а также условные операторы, процедуры и вот это все. Проверяем скрипт:

```shell
sudo sh /etc/ipfw.rules
sudo ipfw list
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%95%D1%81%D0%BB%D0%B8-%D0%B2%D1%81%D0%B5-%D0%9E%D0%9A%2C-%D0%B2-%2Fetc%2F" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Если все ОК, в /etc/rc.conf дописываем:</div></div>```shell
firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
```

<div class="codecolorer-container text default" id="bkmrk-%D0%95%D1%81%D0%BB%D0%B8-%D1%80%D0%B5%D1%88%D0%B8%D0%BB%D0%B8-%D0%B2%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C" style="overflow: auto; white-space: nowrap;"><div class="text codecolorer">Если решили включить логирование, убедитесь, что вы не забыли дописать в /etc/sysctl.conf что-то вроде:</div></div>```shell
net.inet.ip.fw.verbose_limit=5
```

<div class="codecolorer-container text default" id="bkmrk-%D0%9F%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D1%8F%D0%B5%D0%BC%3A" style="overflow: auto; white-space: nowrap;"><div class="text codecolorer">Проверяем:</div></div>```shell
sudo kldunload ipfw
sudo service ipfw start
sudo ipfw list
```

<div class="codecolorer-container bash default" id="bkmrk-%D0%95%D1%81%D0%BB%D0%B8-%D0%B2%D1%81%D0%B5-%D0%B1%D1%8B%D0%BB%D0%BE-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BD" style="overflow: auto; white-space: nowrap;"><div class="bash codecolorer">Если все было сделано правильно, долждны увидеть наши правила. Кроме того, они должны сохраняться и после перезагрузки.</div></div>Это все, о чем я хотел рассказать. Подробности вы найдете в `<span class="text">man 8 ipfw</span>`. Маны во FreeBSD, как всегда, классные. В частности, из мана вы узнаете про такие элементы синтаксиса правил ipfw, оставшиеся за рамками поста, как skipto, tag / untag и другие.

Неправда ли, синтаксис в ipfw куда более читаемый, чем вот эти все `<span class="text">-A</span>`, `<span class="text">-p</span>`, `<span class="text">-j</span>`, <span style="white-space: nowrap;">`<span class="text">--sport</span>`</span> и `<span class="text">-m multiport</span>` в iptables?

## Список используемых источников

- [Настраиваем фаервол во FreeBSD при помощи ipfw](https://eax.me/freebsd-ipfw/)