Продолжаю устанавливать что-нибудь этакое на 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-й раз рассказывать не надо? А хотя почему бы и не да:
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.