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

Итак, на "самом дешевом в мире" VPS у меня ~500 метров оперативки и 6 гигов "HDD". Как обычно заходим по SSH и прямо сразу top:

last pid:  1167;  load averages:  0.09,  0.19,  0.16    up 0+00:12:28  13:31:56
16 processes:  1 running, 15 sleeping
CPU:  0.0% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 9812K Active, 1076K Inact, 66M Wired, 32M Buf, 386M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE    TIME    WCPU COMMAND
 1167 root          1  20    0    14M  3472K RUN      0:00   0.02% top
 1157 root          1  20    0    21M  9128K select   0:00   0.01% sshd
 1007 root          1  20    0    21M  8404K select   0:00   0.00% sshd
  899 root          1  20    0    13M  2612K select   0:00   0.00% syslogd
 1160 root          1  20    0    14M  3800K pause    0:00   0.00% csh
  976 root          1  20    0    13M  2524K nanslp   0:00   0.00% cron
  655 root          1  20    0    11M  1272K select   0:00   0.00% devd
 1027 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1033 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1028 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1030 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1031 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1034 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1029 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
 1032 root          1  52    0    13M  2172K ttyin    0:00   0.00% getty
  966 root          2  52    0    18M  4688K select   0:00   0.00% qemu-ga

А в этом что-то есть…

Подготовка ОС

Для начала установим свой собственный пароль.

passwd

Обновление

https://docs.freebsd.org/en/books/handbook/cutting-edge/

Обновим систему:

freebsd-update fetch
freebsd-update install

При работе первой команды выдаются различные предупреждения - о локально измененных файлах, а также удаляемых, добавляемых и обновляемых в рамках обновления. Нажимаем q. После обновления reboot для пущей важности.

Что касается "ресурсоемкости", то после вышеупомянутых операций обновления старая добрая команда df -H показывает, что системой заняты все те же примерно 2 гигабайта.

df -H
Filesystem      Size    Used   Avail Capacity  Mounted on
/dev/vtbd0p2    6.2G    2.1G    3.6G    37%    /
devfs           1.0k    1.0k      0B   100%    /dev

Прямо скажем, свежая установка 14.1 из ISO занимает всего 1,4 гига, так что по возможности наверное лучше так и поступить - заодно вы получите стандартную систему, а не что там хостер навертел, плюс отдельный раздел подкачки. С другой стороны, по мере установок/обновлений все равно место интенсивно расходуется.

Если вдруг кому интересно, то вот вывод знакомой по статье про TrueNAS gpart show:

gpart show
=>      40  12582832  vtbd0  GPT  (6.0G)
        40      1024      1  freebsd-boot  (512K)
      1064  12581808      2  freebsd-ufs  (6.0G)

Т.е. ни о каком ZFS речи в данном случае не идет.

Что касается оперативной памяти, то информацию об этом можно получить, например, так:

grep memory /var/run/dmesg.boot
real memory  = 536870912 (512 MB)
avail memory = 481378304 (459 MB)

Опять же top показывает в районе 380 свободных мегабайт.

На моем VPS изначально ставится FreeBSD 13.1, которая к октябрю 2024 года (публикация статьи, к сожалению, сильно задержалась) явно устарела. Согласно Supported FreeBSD releases, 13-я ветка будет поддерживаться до 30 апреля 2026 года, а 14 - до 30 ноября 2028. Теоретически пока можно "посидеть" и на 13-й, но перспективнее все же обновиться до 14.1 (актуальную на момент исследования).

freebsd-update -r 14.1-RELEASE upgrade

Задал вопрос:

The following components of FreeBSD seem to be installed:
kernel/generic world/base

The following components of FreeBSD do not seem to be installed:
kernel/generic-dbg world/base-dbg world/lib32 world/lib32-dbg

Does this look reasonable (y/n)? y

На мой взгляд - вполне себе резонно, так что, как видите, ответил y. Процесс на данном VPS, надо сказать, весьма небыстрый, так что пришлось запастись терпением, а заодно на будущее уточнить, как во FreeBSD создать файл подкачки. Стал опасаться, что поторопился с обновлением без оного, но вроде бы все прошло гладко.

Потребовалось вручную разрешить конфликты обновления:

  • /etc/hosts
  • /etc/master.passwd

Автоматические конфликты (ответил y):

  • /etc/login.conf
  • /etc/ssh/sshd_config
  • /etc/sysctl.conf

Установил обновления ядра:

freebsd-update install

Далее - перезагрузка и повторный вызов этой же команды для завершения обновления. И даже еще раз. А потом на всякий случай перезагрузил и сделал fetch - сказал, что обновления не требуются. Фух.

Midnight Commander

Хотел поставить, да возникла ошибка:

pkg install mc
ld-elf.so.1: Shared object "libssl.so.111" not found, required by "pkg"

Вообще-то я немножко проигнорировал просьбу переустановить стороннее ПО, так что:

pkg-static upgrade -f

Командир не дружит с sh, теоретически можно поменять оболочку (после чего перезайти):

pw usermod root -s /bin/tcsh

Хотя, забегая вперед, толку от этого немного - как засорялась история команд, так и засоряется.

Теперь можно устанавливать:

pkg install mc

Файл подкачки

К вопросу о файле подкачки - создаем скажем /usr/swap0 на 512 мегабайт:

dd if=/dev/zero of=/usr/swap0 bs=1m count=512

Как обычно, назначаем права доступа 600:

chmod 0600 /usr/swap0

В /etc/fstab добавляем:

md none swap sw,file=/usr/swap0,late 0 0

Перезагружаемся и проверяем к примеру top'ом:

top
Mem: 11M Active, 1660K Inact, 68M Wired, 36M Buf, 382M Free
Swap: 512M Total, 512M Free

Свободного места, к сожалению, в результате практически не осталось. В принципе можно удалить содержимое /var/db/freebsd-update - это примерно гигабайт (!).

rm -r /var/db/freebsd-update/*

Очень теоретически - /boot/kernel.old. И есть еще pkg clean или pkg clean -a и pkg autoremove, но не сказать, чтобы это много место высвобождало.

fail2ban

Обычно fail2ban интегрируют с ipfw. Активируем его в "открытом" варианте:

sysrc firewall_enable="YES"
sysrc firewall_type="open"

В идеале бы, конечно, открыть только нужные порты, но откровенно говоря заморачиваться неохота да и по большому счету незачем, как по мне. PHP FPM будет слушать сокет, MariaDB - только 127.0.0.1.

Лучше, наверное, перезагрузиться, поскольку если сразу запустить сервис ipfw, то он почему-то все заблокирует.

Установим fail2ban:

pkg install py311-fail2ban

В соответствии с рекомендациями установщика не трогаем jail.conf, однако вместо jail.local я предлагаю создать /usr/local/etc/fail2ban/jail.d/sshd.conf:

[sshd]

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
mode      = aggressive
enabled   = true
banaction = bsd-ipfw[table=ssh]
maxretry  = 3
bantime   = 12h

Установил агрессивный режим, далее собственно включаем правило, говорим, что делать (banaction) - bsd-ipfw как раз преднастроенное действие для нашего случая (FreeBSD и ipfw) - и указываем количество допустимых попыток и время бана.

Включаемся:

service fail2ban enable
service fail2ban start

Смотрим статус:

fail2ban-client status
Status
|- Number of jail:      1
`- Jail list:   sshd

Правило вроде бы тоже добавилось:

ipfw list
...
00111 unreach port ip from table(ssh) to me 22
...

И даже после перезагрузки все сохраняется.

Агрессивный режим практически сразу же начинает банить всех подряд:

fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     5
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 7
   |- Total banned:     7
   `- Banned IP list:   ...

На всякий случай я конечно же попробовал зайти через мобильный интернет с неправильным паролем - заблокировал (хоть и, кажется, с некоторой задержкой).

Опять же на всякий случай - как разбанить:

fail2ban-client set sshd unbanip 85.249.16.128

PHP

Хотел было посмотреть, что вообще есть по поводу PHP в пакетах:

pkg search php

Но это прямо много. Хотя стало понятно, что есть не только 8.3, но и уже 8.4 (хотя на момент исследования эта версия являлась лишь кандидатом на релиз). Более детальными поисками выяснил, что 7-х PHP уже нет, а из 8-х есть еще 8.1 и 8.2.

Что ж, установим сам PHP 8.3 и некий набор расширений:

pkg install php83 php83-composer php83-dom php83-gd php83-iconv php83-opcache php83-pdo_sqlite php83-session php83-simplexml php83-tokenizer php83-xml

Обратите внимание на установку composer как расширения (в свою очередь, он подтягивает по зависимостям еще несколько). Да, получилось многовато, но кое-что я добавил согласно требованиям фреймворка Symfony, демо-приложение которого мы и установим впоследствии.

Подобно образам Docker, очень желательно создать файл php.ini на основе поставляемых примеров - php.ini-development или php.ini-production. В отличие от Linux, во FreeBSD конфиги в основном размещаются в /usr/local/etc (по крайней мере те, что нас интересуют в первую очередь). Итак, делаем "продуктовый" php.ini:

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

Про "тюнинг", думаю, все все знают.

Для очистки совести можно проверить (весьма обширный, надо сказать) вывод команды php -i. Помимо прочего, там перечисляются загруженные конфигурационные файлы и загруженные расширения. Также можно сделать composer --version и/или composer diagnose. Кстати при желании можно установить git - pkg install git.

Пул PHP-FPM настраивается в файле /usr/local/etc/php-fpm.d/www.conf, что опять же больше похоже на образы Docker, нежели "обычные" установки в Linux. По умолчанию пользователь www и прослушивание 9000-го порта. Предлагаю сразу переключить на сокет:

listen = /var/run/php-fpm/www.sock

Создадим соответствующую директорию и назначим права с владельцем:

mkdir /var/run/php-fpm
chown www:www /var/run/php-fpm
chmod 700 /var/run/php-fpm

Добавим сервис в "автозагрузку" и запустим:

service php_fpm enable
service php_fpm start

Обратите внимание на подчеркивание в названии сервиса (в соответствии с файлом в /usr/local/etc/rc.d).

Соответственно просмотр состояния сервиса:

service php_fpm status

Который, в отличие от Линуксов с systemd, сообщает лишь PID процесса.

Caddy

Я в последнее время очень полюбил этот веб-сервер, поскольку он настраивается намного проще, чем Nginx, да еще и интегрирован с Let's Encrypt "из коробки". Что особенно приятно, он есть в пакетах, так что:

pkg install caddy

При установке создается или проверяется наличие пользователя www, который, соответственно, уже у нас есть благодаря установке PHP (или даже вообще изначально при установке FreeBSD). Отлично, ставим сервис в "автозагрузку" под этим пользователем:

sysrc caddy_user=www caddy_group=www
service caddy enable

А также необходимо выполнить инструкцию (выводится после установки и размещена прямо в /usr/local/etc/rc.d/caddy) для разрешения прослушивания портов 80 и 443 непривилегированным пользователем:

pkg install security/portacl-rc
sysrc portacl_users+=www
sysrc portacl_user_www_tcp="http https"
sysrc portacl_user_www_udp="https"
service portacl enable
service portacl start

Перезагружаемся, проверяем состояние сервиса:

service caddy status

Можно было бы попробовать "зайти" на сервер, но с настройками по умолчанию идет редирект на https, а там уже невозможно получить сертификат.

Демо-приложение

Во FreeBSD, видимо, для размещения сайтов принят путь /usr/local/www. Директория, впрочем, пока не создана (во всяком случае у меня). Установим демку Symfony с помощью composer:

mkdir /usr/local/www
cd /usr/local/www
composer create-project symfony/symfony-demo demo
cd demo

Из-за FreeBSD немножко отваливается sass:build. Можно победить установкой Ноды и собственно sass:

pkg install node
pkg install www/npm
npm i -g sass

Настраиваем бандл для использования "правильной" библиотеки - файл config/packages/symfonycasts_sass.yaml:

symfonycasts_sass:
    binary: '/usr/local/bin/sass'

Очищаем кэш, чтобы применить изменения настройки:

php bin/console cache:clear

Собираем sass и компилируем ресурсы:

php bin/console sass:build
php bin/console asset-map:compile

Что-то, конечно, произошло, но с кучей предупреждений. Ну да ладно.

Меняем владельца на www:

chown -R www:www /usr/local/www

Настройка

Поскольку теперь есть, что опубликовать, возвращаемся к настройке веб-сервера - файл /usr/local/etc/caddy/Caddyfile, заменяем блок localhost данным фрагментом:

http:// {
  # Set this path to your site's directory:
  root * /usr/local/www/demo/public
  # Enable the static file server:
  encode gzip
  file_server
  # Serve a PHP site through php-fpm:
  php_fastcgi unix//var/run/php-fpm/www.sock
}

http:// позволяет заходить на сервер "по IP" и безо всяких там ваших SSL. Хотя если есть домен, то целесообразно его и прописать, чтобы получить сертификат (в этом случае напоминаю про глобальную настройку e-mail).

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

service caddy restart

СУБД

По большому счету с этим все хорошо - хотите MariaDB:

mariadb1011-server-10.11.9     Multithreaded SQL database (server)
mariadb105-server-10.5.26      Multithreaded SQL database (server)
mariadb106-server-10.6.19      Multithreaded SQL database (server)
mariadb114-server-11.4.3       Multithreaded SQL database (server)

Хотите - "родной" MySQL:

mysql80-server-8.0.39_1        Multithreaded SQL database (server)
mysql84-server-8.4.2_1         Multithreaded SQL database (server)
mysql90-server-9.0.1           Multithreaded SQL database (server)

Хотите - PostgreSQL:

postgresql12-server-12.20      PostgreSQL is the most advanced open-source database available anywhere
postgresql13-server-13.16      PostgreSQL is the most advanced open-source database available anywhere
postgresql14-server-14.13      PostgreSQL is the most advanced open-source database available anywhere
postgresql15-server-15.8       PostgreSQL is the most advanced open-source database available anywhere
postgresql16-server-16.4       PostgreSQL is the most advanced open-source database available anywhere
postgresql17-server-17.0       PostgreSQL is the most advanced open-source database available anywhere

(конкретные версии, разумеется, на момент написания).

MongoDB, Redis - без проблем.

MariaDB

Установим к примеру старую добрую MariaDB 10.6:

pkg install mariadb106-server
service mysql-server enable
service mysql-server start
mariadb-secure-installation

Запустим mysql и убедимся, что Performance Schema выключена:

SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | OFF   |
+--------------------+-------+
1 row in set (0.002 sec)

Как создать пользователя и БД, надеюсь, в 100500-й раз рассказывать не надо? smile А хотя почему бы и не да:

CREATE DATABASE freebsd;
CREATE USER freebsd@localhost IDENTIFIED BY 'very_secure_password';
GRANT ALL PRIVILEGES ON freebsd.* to freebsd@localhost;
FLUSH PRIVILEGES;

Конфиги, в случае чего, логичным образом находятся в /usr/local/etc/mysql.

Совсем не кстати - зачем-то подтягивается bash. Так что в случае чего можно опять поменять оболочку.

FTP

Обычно я еще рассказываю про установку FTP-сервера. Разумеется, во FreeBSD таковые есть. Это может быть и условно стандартный freebsd-ftpd, или vsftpd как в Alpine Linux, или тот же ProFTPD и т.д. и т.п.

ftpd

К примеру возьмем почти стандартный:

pkg install freebsd-ftpd

Проверяем файл /etc/ftpusers. В моем случае в нем присутствует пользователь www, которого надо из этого файла удалить. Затем скорее всего создаем файл /etc/ftpchroot (у меня его не было) следующего содержания:

www /usr/local/www

Бессовестным образом подправим /etc/rc.d/ftpd - поменяем путь к команде, чтобы использовать файл из установленного пакета (хотя потом система может на это ругаться при обновлении):

command="/usr/local/libexec/${name}"

Задаем пароль пользователю www:

passwd www

Поскольку у пользователя www стоит оболочка /usr/sbin/nologin, он все равно не сможет подключиться по FTP. Для обхода можно сделать свою оболочку, которая будет ссылаться на /usr/sbin/nologin:

echo '/sbin/nologin-ftp' >> /etc/shells
ln -s /usr/sbin/nologin /sbin/nologin-ftp
pw usermod www -s /sbin/nologin-ftp

Добавляем флаг запуска ftpd для поддержки UTF-8 в именах файлов:

sysrc ftpd_flags="-8"

Включаем и запускаем сервис:

service ftpd enable
service ftpd start

Pure-FTPd

Недостатком использования ftpd являются манипуляции с системным пользователем. Виртуальных пользователей поддерживает, например, Pure-FTPd, который я раньше не устанавливал.

pkg install pure-ftpd

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

cd /usr/local/etc
cp pure-ftpd.conf.sample pure-ftpd.conf

С точки зрения банальной эрудиции, подправим кое-какие настройки:

NoAnonymous                  yes
PureDB                       /usr/local/etc/pureftpd.pdb
MinUID                       80

Добавляем FTP-пользователя www (соответствующего системному пользователю www с UID 80, для чего и потребовалось настроить MinUID):

pure-pw useradd www -u www -d /usr/local/www
pure-pw mkdb

Первая команда запросит пароль для установки FTP-пользователю.

Как обычно, включаем и запускаем сервис (если до этого был настроен ftpd, то его надо предварительно остановить и отключить):

service pure-ftpd enable
service pure-ftpd start

Хорошо бы еще интегрировать с Fail2ban, раз установили его ранее. Файл /usr/local/etc/fail2ban/jail.d/pure-ftpd.conf:

[pure-ftpd]
enabled  = true
banaction = bsd-ipfw[table=ftp]
maxretry = 3
bantime = 12h

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

fail2ban-client reload

Можно смотреть статус:

fail2ban-client status pure-ftpd
Status for the jail: pure-ftpd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     1
|  `- File list:        /var/log/xferlog
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

Справедливости ради, FTP практически не "взламывают", в отличие от SSH (в примере это я попробовал не зайти).

Заключение

В целом мне понравилась FreeBSD в качестве веб-сервера (в принципе она мне и до этого понравилась, когда я смотрел TrueNAS), так что если вы можете обойтись без Докера, то советую присмотреться. Разве что места требует относительно много - диск на 10 гигабайт был бы лучше, да расширения PHP как-то уж слишком мелко "нарезаны".


Категория: Программирование, веб | Опубликовано 24.05.2025 | Редакция от 05.07.2025

Похожие материалы

Веб-сервер на FreeBSD с использованием клеток

Здесь вам не Докер, а клетки (jails) - будем говорить, это контейнеры FreeBSD, когда это еще не было мейнстримом (на минуточку, они появились еще во FreeBSD 4.x - 2000 год). Практический смысл в моем случае - неким образом изолированно использовать разные версии PHP, ну и чуть ближе познакомиться с технологией, с которой я уже сталкивался при обзоре TrueNAS. Основано, как говорится, на реальных событиях - я переносил сайты на Drupal 7.x и Yii с сервера на Linux.


Комментарии, обсуждение