В мире много профессий и навыков, которые со временем забываются и исчезают. Так, например, в Англии и Ирландии до 1920 года существовала профессия будильщика. Этот человек ходил с легкой бамбуковой палкой и духовой трубкой для стрельбы горохом. Его задачей было будить людей стуком в дверь или окно, чтобы те вовремя прибыли на работу — промышленная революция, как-никак. И пока клиент не вставал, стук не прекращался. С появлением будильников эта профессия канула в Лету.
Приложения на языках программирования второй половины 20-го века вроде COBOL, Fortran и Ada до сих пор встречаются в банках, страховых компаниях и госучреждениях. Но вот людей, которые реально могут легко написать программу на COBOL, в мире осталось немного. Точно так же дело обстоит со старыми операционными системами. Казалось бы, прошло всего 25 лет с момента выхода FreeBSD 4.x, но сейчас многие навыки работы с ней уже утрачены. Сегодня предлагаю взглянуть на процесс установки старой версии «фряхи» и запуска несложного серверного приложения вроде IRC.

Начнем с выбора версии и скачивания дистрибутива. Возможно, для чистоты эксперимента стоило взять 4.0, но все-таки там было много багов и шероховатостей, об которые не хотелось лишний раз споткнуться. А вот версия 4.4 лучше поддерживала ACPI, распознавала больше USB-устройств и вообще считалась true с точки зрения сетевого стека. Кстати, многие админы в то время задерживались именно на этой версии, поскольку FreeBSD 5.x на момент релиза не отличалась стабильностью.

Разница между установкой любой современной версии FreeBSD (14-й, например) и 4.4 видна невооруженным взглядом. Если сейчас у вас есть удобный модульный инсталлятор bsdinstall (появился с версии 9.0), то в те годы был олдовый монолитный sysinstall. Ни о какой поддержке схемы разметки GPT или новомодной ZFS даже речи не шло. Только MBR и UFS, на тот момент, кстати, без включенной поддержки журналирования по умолчанию.

Вместо него применялась soft updates — особая стратегия сохранения метаданных на диск, которые пишутся асинхронно и минимизируют возможность нарушения целостности данных. Если в процессе записи произойдет сбой по питанию, то в большинстве случаев единственной проблемой, с которой реально можно столкнуться, будет утечка свободного места. Дисковое пространство помечается как используемое, но при этом не задействуется ни одним файлом. Ситуация неприятная, но вполне поправимая.

В целом sysinstall не вызывает какого-то когнитивного диссонанса. Процедура установки понятна и не представляет сложности.

Теперь инсталлятор переходит к самому важному этапу — начальному конфигурированию. Для начала имеет смысл сразу настроить сеть. Тут я оговорюсь, что использовал PCem, который, в отличие от VirtualBox, не испытывает проблем при виртуализации столь старых версий BSD. Поэтому моя сетевая конфигурация определяется так:

Задать адрес можно вручную или через DHCP. Лично я пользуюсь последним вариантом, но сразу же закрепляю выданный IP на роутере за конкретной ВМ:

Дальше нужно ответить на ряд вопросов вроде «хотите ли использовать этот компьютер в качестве NFS-сервера». Самым интересным из них, пожалуй, будет вопрос о включении совместимости с приложениями для Linux:

Да-да, %USERNAME%, это старый добрый linuxulator, механизм для запуска немодифицированных бинарников для Linux. Это не виртуализация и даже не эмуляция, как можно вначале подумать. Работала фича через слой совместимости в ядре и созданием фейкового пользовательского окружения, дабы приложение думало, что запущено на Linux.
Со стороны ОС это выглядело как загрузка модуля ядра linux.ko и перехват системных вызовов Linux с последующей трансляцией в аналоги на FreeBSD. Разумеется, все это работало лишь для приложений — драйверы и модули ядра сразу мимо. Зато производительность была максимально близка к нативной.
Потом оставалось создать пользователей, установить пароль root, вытащить инсталляционный диск и отправить систему в ребут.
Первые шаги

После перезагрузки системы мы попадаем в командную оболочку C Shell (csh). Это прямо-таки верх минимализма, и работать в ней в большинстве случаев неудобно. Конечно, можно было бы накатить сразу bash и забыть об этом, но я вспомнил про значительно более приятную оболочку Zsh. Впервые познакомился с ней, работая с дистрибутивом для системных администраторов GRML. С тех пор именно Zsh является для меня эталоном правильной оболочки.
Любопытно, что она была разработана очень давно, в 1990 году, студентом Принстонского университета Паулем Фалстадом (Paul Falstad). Так что на момент выхода FreeBSD 4.4 пакет zsh-4.0.2 вполне был доступен в официальном репозитории. Проблема лишь в том, что для столь старой версии они уже давно отключены, и вы не сможете сходу воспользоваться pkg_add для установки.
Есть два варианта решения. Первый — указать значение переменной PACKAGESITE со ссылкой на FTP-архив проекта FreeBSD:
# setenv PACKAGESITE ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/4.4-RELEASE/packages/All/
Альтернативным вариантом будет выкачать оттуда все содержимое и развернуть небольшой сервер в локальной сети, который послужит репозиторием для старых версий. Если сетевая часть настроена верно, то следующая команда скачает и установит tgz-пакет с оболочкой Zsh в систему:
# pkg_add -r zsh-4.0.2
Можно было бы собрать и из портов методом cd /usr/ports/shells/zsh && make install clean, но это уже вопрос терпеливости. Проверяю работу с дефолтным конфигом:
# /usr/local/bin/zsh
Я не удержался и адаптировал рабочий профиль под свои нужды. Правда, приходилось учитывать то, что, например, атрибут -h у команды ls появился позже. Если мне не изменяет память, то с версии FreeBSD 4.5 (это 2002 год). Под спойлерами вы найдете мой немного доработанный grml-like-конфиг и профиль для этой оболочки. Там есть алиасы стандартных команд, удобное автодополнение и Emacs-совместимое поведение клавиатуры:
~/.zshrc
# Core options
setopt prompt_subst
setopt auto_cd
setopt auto_list
setopt auto_menu
setopt complete_in_word
setopt always_to_end
setopt correct
setopt extended_glob
setopt nohup
setopt notify
unsetopt beep
# History
HISTFILE=$HOME/.zsh_history
HISTSIZE=5000
SAVEHIST=5000
setopt hist_ignore_dups
setopt hist_ignore_all_dups
setopt hist_reduce_blanks
setopt hist_verify
setopt share_history
# Keys (emacs)
bindkey -e
bindkey '\e[H' beginning-of-line
bindkey '\e[F' end-of-line
bindkey '^[[3~' delete-char
bindkey '^[[2~' overwrite-mode
bindkey '^R' history-incremental-search-backward
# Aliases
alias ll='ls -la'
alias ..='cd ..'
alias ...='cd ../..'
alias df='df -h'
alias du='du -h'
alias e='${EDITOR:-vi}'
alias psg='ps auxw | grep -i'
# Colors (FreeBSD ls): -G works in xterm/screen; fallback otherwise
case "$TERM" in
xterm*|screen*) alias ls='ls -G' ;;
*) alias ls='ls -F' ;;
esac
# Prompt (plain ASCII)
PROMPT='%n@%m:%~ %# '
RPROMPT='%(?..exit:%?)'
# Completion (old compinit)
typeset -U fpath
fpath=($fpath /usr/local/share/zsh/site-functions /usr/local/share/zsh/$ZSH_VERSION/functions)
autoload -U compinit
compinit -i
# Completion styles (safe)
zstyle ':completion:*' menu select
zstyle ':completion:*' completer _complete _correct
zstyle ':completion:*' verbose yes
# Show dir listing after cd
chpwd() { ls -la; }
# Helpers
wh() { which "$1" && ls -l "$(which "$1" 2>/dev/null)" 2>/dev/null; }
alias zrc='${EDITOR:-vi} ~/.zshrc'
alias zre='source ~/.zshrc'
~/.zprofile
# minimal for zsh
typeset -U path
path=($path /usr/local/sbin /usr/local/bin)
export PATH
Чтобы заменить стандартную оболочку установленным Zsh, достаточно выполнить:
# chsh -s /usr/local/bin/zsh
После повторного логина вы автоматически попадете в shell и сможете комфортнее работать, даже находясь в старой версии FreeBSD. Единственное, для поддержки репозитория уже будет другая команда export вместо setenv:
# export PACKAGESITE=ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/4.4-RELEASE/packages/All/
Даже несмотря на то, что в ней нет аналогов screenfetch/neofetch, я нашел один из старых скриптов, выполняющих похожую функцию:

Кому интересно, код bsdfetch.sh также под спойлером:
#!/bin/sh
OS=`uname -s`
KERN=`uname -r`
ARCH=`uname -m`
HOST=`hostname`
USER_NAME=`whoami`
HW_MODEL=`sysctl -n hw.model 2>/dev/null`
NCPU=`sysctl -n hw.ncpu 2>/dev/null`
PHYS_BYTES=`sysctl -n hw.physmem 2>/dev/null`
if [ -n "$PHYS_BYTES" ]; then
PHYS_MB=`echo "$PHYS_BYTES / 1048576" | bc`
else
PHYS_MB="?"
fi
UPTIME_STR=`uptime 2>/dev/null | sed 's/^.*up *//; s/, *[0-9][0-9]* users.*//'`
USERS_CNT=`uptime 2>/dev/null | sed -n 's/.* \([0-9][0-9]*\) users.*/\1/p'`
[ -z "$USERS_CNT" ] && USERS_CNT="?"
if df -h / >/dev/null 2>&1; then
DLINE=`df -h / | tail -1`
D_TOTAL=`echo "$DLINE" | awk '{print $2}'`
D_USED=`echo "$DLINE" | awk '{print $3}'`
D_AVAIL=`echo "$DLINE" | awk '{print $4}'`
D_USEP=`echo "$DLINE" | awk '{print $5}'`
else
DLINE=`df -k / | tail -1`
DTK=`echo "$DLINE" | awk '{print $2}'`
DUK=`echo "$DLINE" | awk '{print $3}'`
DAK=`echo "$DLINE" | awk '{print $4}'`
D_TOTAL=`echo "$DTK/1024" | bc`"MB"
D_USED=`echo "$DUK/1024" | bc`"MB"
D_AVAIL=`echo "$DAK/1024" | bc`"MB"
D_USEP=`echo "$DLINE" | awk '{print $5}'`
fi
if [ -x /usr/local/bin/zsh ]; then
ZSH_BIN="/usr/local/bin/zsh"
ZSH_VER=`/usr/local/bin/zsh --version 2>/dev/null`
else
ZSH_BIN="not installed"
ZSH_VER=""
fi
cat <<'ART' >/tmp/.beastie.$$
, ,
/( )`
\ \___ / |
/- _ `-/ '
(/\/ \ \ /\
/ / | ` \
O O ) / |
`-^--'`< '
(_.) _ ) /
`.___/` /
`-----' /
<----. __\
<----|====O)))==) FreeBSD
<----' `--'
\ /
__\_______/___
ART
cat <<EOF >/tmp/.info.$$
User : $USER_NAME@$HOST
OS : $OS $KERN ($ARCH)
CPU : $HW_MODEL
Cores : $NCPU
Memory : ${PHYS_MB} MB
Uptime : $UPTIME_STR
Users : $USERS_CNT
Root FS : total $D_TOTAL, used $D_USED, avail $D_AVAIL, $D_USEP
Zsh : $ZSH_BIN
Version : $ZSH_VER
EOF
paste -d ' ' /tmp/.beastie.$$ /tmp/.info.$$
rm -f /tmp/.beastie.$$ /tmp/.info.$$ 2>/dev/null
Ищем и ставим IRC
Переходим к самому вкусному. Сейчас у нас есть куча современных приложений вроде Slack, Discord или Mattermost. Но вот раньше пользователи заходили на серверы IRC (Internet Relay Chat) для общения друг с другом. Говоря простым языком, это «прадедушка» Discord, поверх которого накатили современный интерфейс, прикрутили картинки, голосовое общение и push-уведомления. Но основной принцип остался тот же — на сервере есть каналы, начинающиеся с #, где можно общаться, а также пользоваться услугами ботов (IRC-сервисами).
До появления мессенджеров и соцсетей каналы IRC были наиболее популярным местом для живого общения. Там собирались программисты, системные администраторы, музыканты, любители аниме и мамкины хакеры. Словом, кто угодно. Первые интернет-драмы и холивары происходили именно тут, в «ирке».
С развитием доступа в сеть многие гики стали предпочитать создавать собственные серверы, своеобразные клубы по интересам. Они не зависели от публичных сервисов и не подвергались модерации. Вот такой мы сегодня и попробуем поднять.
Прежде всего нужно определиться с выбором приложения. В те годы были наиболее популярны ircd-hybrid и UnrealIRCd. Оба имеют очень давнюю историю. Первый появился в 1997 году, а второй в 1999. Фактически это два противоположных пути разработки оригинального демона ircd, который был для них общим «корнем».
ircd-hybrid был более строгим в плане конфигурирования, но при этом относительно прост и лаконичен. Его никогда не перегружали фичами, за счет чего достигалась стабильность. UnrealIRCd, напротив, позиционировался как «IRC для людей», предоставляя большую гибкость в настройке.
Мы выбрали первый вариант, поскольку он позволяет не запутаться и получить аутентичный опыт. В репозитории проекта на SourceForge была найдена версия 6.0 (ircd-hybrid-6.0.tgz), которая вполне хорошо идет на FreeBSD 4.4. Его я скачал на локальный компьютер и при помощи Serva Community быстро развернул FTP-сервер, разрешив анонимное скачивание, и загрузил файл через стандартный клиент:
ftp> open 192.168.88.20
Name (192.168.88.52):root : anonymous
230 User Logged In.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode off.
ftp> ls
200 PORT command successful.
150 Opening data channel.
-rw-rw-rw- 1 user group 618547 Sep 3 08:22 ircd-hybrid-6.0.tgz
226 Transfer complete.
ftp> recv ircd-hybrid-6.0.tgz
local: ircd-hybrid-6.0.tgz remote: ircd-hybrid-6.0.tgz
200 PORT command successful.
150 Opening data channel.
100% |**************************************************| 604 KB 00:00 ETA
226 Transfer complete.
618547 bytes received in 0.20 seconds (2.95 MB/s)
ftp> quit
221 Goodbye.
Теперь остается выполнить установку:
# pkg_add ircd-hybrid-6.0.tgz
Без конфига, разумеется, ничего работать не будет. Так что создаю его:
# vi /usr/local/ircd/ircd.conf
Ввожу следующее содержимое:
M:irc.local:127.0.0.1:Habr IRC Test Server
A:Local IRC Server
A:Server Administrator
A:admin@local
P::::6667
Y:1:90:200:100000
I:*@*::* 1
Чуть-чуть расшифрую. Весь конфиг поделен на блоки:
M — me block, описание самого сервера;
A — admin block, строки с контактной информацией;
P — port block, объявление портов для входящих соединений;
Y — class block, лимиты для группы клиентов;
I — allow block, правило допуска клиентов.
В моем конфиге открывается стандартный порт 6667, к которому можно подключаться любым клиентом без пароля и конкретного IP-адреса. Попросту говоря, добро пожаловать!
Запускаем:
# /usr/local/ircd/ircd -f /usr/local/ircd/ircd.conf
Sep 9 01:01:29 irc ircd[613]: Server Ready
Проверяем, что порт открылся:
# netstat -an | grep LISTEN
…
tcp4 0 0 *.6667 *.* LISTEN
…
Теперь можно подключаться любым клиентом, хоть через Telnet:
NICK testuser
USER testuser 0 * :Test User
:irc.local 001 testuser :Welcome to the Internet Relay Network testuser
:irc.local 002 testuser :Your host is irc.local[irc.local/6667], running version 2.8/hybrid-6.0
NOTICE testuser :*** Your host is irc.local[irc.local/6667], running version 2.8/hybrid-6.0
:irc.local 003 testuser :This server was created Wed Sep 3 2025 at 11:26:17 GMT
:irc.local 004 testuser irc.local 2.8/hybrid-6.0 oiwszcrkfydnxb biklmnopstved
:irc.local 251 testuser :There are 1 users and 0 invisible on 1 servers
:irc.local 255 testuser :I have 1 clients and 0 servers
:irc.local 265 testuser :Current local users: 1 Max: 1
:irc.local 266 testuser :Current global users: 1 Max: 1
:irc.local 250 testuser :Highest connection count: 1 (1 clients) (1 since server was (re)started)
:irc.local 375 testuser :- irc.local Message of the Day -
:irc.local 372 testuser :- This is ircd-hybrid MOTD replace it with something better
:irc.local 376 testuser :End of /MOTD command.
Вот так мы получили готовый IRC-сервер для дальнейшей настройки. Далее можно добавить его в автозапуск. Поскольку удобного и привычного /etc/rc.d еще нет в помине, прописываем олдскульно:
# vi /etc/rc.local
if [ -x /usr/local/ircd/ircd ]; then
echo -n ' ircd'
/usr/local/ircd/ircd -f /usr/local/ircd/ircd.conf &
fi
Созданный файл делаем исполняемым:
# chmod +x /etc/rc.local
После ребута демон ircd поднимется самостоятельно.
Подводим итоги
Работа со старой версией FreeBSD сильно отличается от современных. Это дает хорошее представление о том, сколько всяких удобных штук появилось за четверть века. Тем не менее особых проблем я не встретил. Это стабильная и мощная операционная система, которая сейчас может служить отличным учебным пособием для тех, кто только начинает изучать прекрасный мир *nix.
Разумеется, на FreeBSD 4.4 можно крутить какие-нибудь раритетные приложения, например в музеях компьютерной техники. Настройка собственного сервера IRC — тема скорее для отдельной статьи, но хочется отметить, что оба приложения (ircd-hybrid и UnrealIRCd) до сих пор актуальны и обновляются. Их свежие версии можно использовать и в 2025 году.
А вы когда-нибудь поднимали собственный IRC-сервер на FreeBSD?
Комментарии (2)
Gansterito
14.09.2025 09:26прошло всего 25 лет с момента выхода FreeBSD 4.x, но сейчас многие навыки работы с ней уже утрачены
Господь с Вами! Лишь бы distfiles для портов найти, а уж make/make install сделать всяко можно. Да и мир пересобрать не так уж сложно. Что утрачено?
Вот с 2.2.8 скорее всего повозиться придется. Я лет 15 назад в ностальгическом порыве ставил, но и тогда еле нашел образы. Сейчас уже не уверен.
И я бы всё-таки поспорил на счет удобства sysinstall (тогда он был еще в /stand/).
Moog_Prodigy
IRC сервер не поднимал, но несколько сайтов (форумы) на фряхе приходилось. На 6 еще. По сравнению с виндой казалось даже проще.